Merge branch 'develop' into enhancement/get-repre-path-function

This commit is contained in:
Jakub Trllo 2025-10-20 11:50:08 +02:00 committed by GitHub
commit fae8e2b0d3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 794 additions and 349 deletions

View file

@ -35,6 +35,9 @@ body:
label: Version
description: What version are you running? Look to AYON Tray
options:
- 1.6.4
- 1.6.3
- 1.6.2
- 1.6.1
- 1.6.0
- 1.5.3

View file

@ -1,5 +1,7 @@
# -*- coding: utf-8 -*-
"""Base class for AYON addons."""
from __future__ import annotations
import copy
import os
import sys
@ -11,10 +13,11 @@ import collections
import warnings
from uuid import uuid4
from abc import ABC, abstractmethod
from typing import Optional
from types import ModuleType
import typing
from typing import Optional, Any, Union
import ayon_api
from semver import VersionInfo
from ayon_core import AYON_CORE_ROOT
from ayon_core.lib import (
@ -30,6 +33,11 @@ from .interfaces import (
IHostAddon,
)
if typing.TYPE_CHECKING:
import click
from ayon_core.host import HostBase
# Files that will be always ignored on addons import
IGNORED_FILENAMES = {
"__pycache__",
@ -39,33 +47,6 @@ IGNORED_DEFAULT_FILENAMES = {
"__init__.py",
}
# When addon was moved from ayon-core codebase
# - this is used to log the missing addon
MOVED_ADDON_MILESTONE_VERSIONS = {
"aftereffects": VersionInfo(0, 2, 0),
"applications": VersionInfo(0, 2, 0),
"blender": VersionInfo(0, 2, 0),
"celaction": VersionInfo(0, 2, 0),
"clockify": VersionInfo(0, 2, 0),
"deadline": VersionInfo(0, 2, 0),
"flame": VersionInfo(0, 2, 0),
"fusion": VersionInfo(0, 2, 0),
"harmony": VersionInfo(0, 2, 0),
"hiero": VersionInfo(0, 2, 0),
"max": VersionInfo(0, 2, 0),
"photoshop": VersionInfo(0, 2, 0),
"timers_manager": VersionInfo(0, 2, 0),
"traypublisher": VersionInfo(0, 2, 0),
"tvpaint": VersionInfo(0, 2, 0),
"maya": VersionInfo(0, 2, 0),
"nuke": VersionInfo(0, 2, 0),
"resolve": VersionInfo(0, 2, 0),
"royalrender": VersionInfo(0, 2, 0),
"substancepainter": VersionInfo(0, 2, 0),
"houdini": VersionInfo(0, 3, 0),
"unreal": VersionInfo(0, 2, 0),
}
class ProcessPreparationError(Exception):
"""Exception that can be used when process preparation failed.
@ -128,7 +109,7 @@ class _LoadCache:
addon_modules = []
def load_addons(force=False):
def load_addons(force: bool = False) -> None:
"""Load AYON addons as python modules.
Modules does not load only classes (like in Interfaces) because there must
@ -155,7 +136,7 @@ def load_addons(force=False):
time.sleep(0.1)
def _get_ayon_bundle_data():
def _get_ayon_bundle_data() -> Optional[dict[str, Any]]:
studio_bundle_name = os.environ.get("AYON_STUDIO_BUNDLE_NAME")
project_bundle_name = os.getenv("AYON_BUNDLE_NAME")
bundles = ayon_api.get_bundles()["bundles"]
@ -185,18 +166,21 @@ def _get_ayon_bundle_data():
return project_bundle
def _get_ayon_addons_information(bundle_info):
def _get_ayon_addons_information(
bundle_info: dict[str, Any]
) -> list[dict[str, Any]]:
"""Receive information about addons to use from server.
Todos:
Actually ask server for the information.
Allow project name as optional argument to be able to query information
about used addons for specific project.
Wrap versions into an object.
Returns:
List[Dict[str, Any]]: List of addon information to use.
"""
list[dict[str, Any]]: List of addon information to use.
"""
output = []
bundle_addons = bundle_info["addons"]
addons = ayon_api.get_addons_info()["addons"]
@ -215,46 +199,7 @@ def _get_ayon_addons_information(bundle_info):
return output
def _handle_moved_addons(addon_name, milestone_version, log):
"""Log message that addon version is not compatible with current core.
The function can return path to addon client code, but that can happen
only if ayon-core is used from code (for development), but still
logs a warning.
Args:
addon_name (str): Addon name.
milestone_version (str): Milestone addon version.
log (logging.Logger): Logger object.
Returns:
Union[str, None]: Addon dir or None.
"""
# Handle addons which were moved out of ayon-core
# - Try to fix it by loading it directly from server addons dir in
# ayon-core repository. But that will work only if ayon-core is
# used from code.
addon_dir = os.path.join(
os.path.dirname(os.path.dirname(AYON_CORE_ROOT)),
"server_addon",
addon_name,
"client",
)
if not os.path.exists(addon_dir):
log.error(
f"Addon '{addon_name}' is not available. Please update "
f"{addon_name} addon to '{milestone_version}' or higher."
)
return None
log.warning((
"Please update '{}' addon to '{}' or higher."
" Using client code from ayon-core repository."
).format(addon_name, milestone_version))
return addon_dir
def _load_ayon_addons(log):
def _load_ayon_addons(log: logging.Logger) -> list[ModuleType]:
"""Load AYON addons based on information from server.
This function should not trigger downloading of any addons but only use
@ -264,6 +209,9 @@ def _load_ayon_addons(log):
Args:
log (logging.Logger): Logger object.
Returns:
list[ModuleType]: Loaded addon modules.
"""
all_addon_modules = []
bundle_info = _get_ayon_bundle_data()
@ -283,9 +231,8 @@ def _load_ayon_addons(log):
addons_dir_exists = os.path.exists(addons_dir)
if not addons_dir_exists:
log.warning("Addons directory does not exists. Path \"{}\"".format(
addons_dir
))
log.warning(
f"Addons directory does not exists. Path \"{addons_dir}\"")
for addon_info in addons_info:
addon_name = addon_info["name"]
@ -299,7 +246,6 @@ def _load_ayon_addons(log):
use_dev_path = dev_addon_info.get("enabled", False)
addon_dir = None
milestone_version = MOVED_ADDON_MILESTONE_VERSIONS.get(addon_name)
if use_dev_path:
addon_dir = dev_addon_info["path"]
if addon_dir:
@ -308,28 +254,20 @@ def _load_ayon_addons(log):
)
if not addon_dir or not os.path.exists(addon_dir):
log.warning((
"Dev addon {} {} path does not exists. Path \"{}\""
).format(addon_name, addon_version, addon_dir))
continue
elif (
milestone_version is not None
and VersionInfo.parse(addon_version) < milestone_version
):
addon_dir = _handle_moved_addons(
addon_name, milestone_version, log
)
if not addon_dir:
log.warning(
f"Dev addon {addon_name} {addon_version} path"
f" does not exists. Path \"{addon_dir}\""
)
continue
elif addons_dir_exists:
folder_name = "{}_{}".format(addon_name, addon_version)
folder_name = f"{addon_name}_{addon_version}"
addon_dir = os.path.join(addons_dir, folder_name)
if not os.path.exists(addon_dir):
log.debug((
"No localized client code found for addon {} {}."
).format(addon_name, addon_version))
log.debug(
"No localized client code found"
f" for addon {addon_name} {addon_version}."
)
continue
if not addon_dir:
@ -368,24 +306,22 @@ def _load_ayon_addons(log):
except BaseException:
log.warning(
"Failed to import \"{}\"".format(basename),
f"Failed to import \"{basename}\"",
exc_info=True
)
if not addon_modules:
log.warning("Addon {} {} has no content to import".format(
addon_name, addon_version
))
log.warning(
f"Addon {addon_name} {addon_version} has no content to import"
)
continue
if len(addon_modules) > 1:
log.warning((
"Multiple modules ({}) were found in addon '{}' in dir {}."
).format(
", ".join([m.__name__ for m in addon_modules]),
addon_name,
addon_dir,
))
joined_modules = ", ".join([m.__name__ for m in addon_modules])
log.warning(
f"Multiple modules ({joined_modules}) were found in"
f" addon '{addon_name}' in dir {addon_dir}."
)
all_addon_modules.extend(addon_modules)
return all_addon_modules
@ -403,20 +339,21 @@ class AYONAddon(ABC):
Attributes:
enabled (bool): Is addon enabled.
name (str): Addon name.
Args:
manager (AddonsManager): Manager object who discovered addon.
settings (dict[str, Any]): AYON settings.
"""
enabled = True
enabled: bool = True
_id = None
# Temporary variable for 'version' property
_missing_version_warned = False
def __init__(self, manager, settings):
def __init__(
self, manager: AddonsManager, settings: dict[str, Any]
) -> None:
self.manager = manager
self.log = Logger.get_logger(self.name)
@ -424,7 +361,7 @@ class AYONAddon(ABC):
self.initialize(settings)
@property
def id(self):
def id(self) -> str:
"""Random id of addon object.
Returns:
@ -437,7 +374,7 @@ class AYONAddon(ABC):
@property
@abstractmethod
def name(self):
def name(self) -> str:
"""Addon name.
Returns:
@ -447,7 +384,7 @@ class AYONAddon(ABC):
pass
@property
def version(self):
def version(self) -> str:
"""Addon version.
Todo:
@ -466,7 +403,7 @@ class AYONAddon(ABC):
)
return "0.0.0"
def initialize(self, settings):
def initialize(self, settings: dict[str, Any]) -> None:
"""Initialization of addon attributes.
It is not recommended to override __init__ that's why specific method
@ -478,7 +415,7 @@ class AYONAddon(ABC):
"""
pass
def connect_with_addons(self, enabled_addons):
def connect_with_addons(self, enabled_addons: list[AYONAddon]) -> None:
"""Connect with other enabled addons.
Args:
@ -489,7 +426,7 @@ class AYONAddon(ABC):
def ensure_is_process_ready(
self, process_context: ProcessContext
):
) -> None:
"""Make sure addon is prepared for a process.
This method is called when some action makes sure that addon has set
@ -510,7 +447,7 @@ class AYONAddon(ABC):
"""
pass
def get_global_environments(self):
def get_global_environments(self) -> dict[str, str]:
"""Get global environments values of addon.
Environment variables that can be get only from system settings.
@ -521,20 +458,12 @@ class AYONAddon(ABC):
"""
return {}
def modify_application_launch_arguments(self, application, env):
"""Give option to modify launch environments before application launch.
Implementation is optional. To change environments modify passed
dictionary of environments.
Args:
application (Application): Application that is launched.
env (dict[str, str]): Current environment variables.
"""
pass
def on_host_install(self, host, host_name, project_name):
def on_host_install(
self,
host: HostBase,
host_name: str,
project_name: str,
) -> None:
"""Host was installed which gives option to handle in-host logic.
It is a good option to register in-host event callbacks which are
@ -545,7 +474,7 @@ class AYONAddon(ABC):
to receive from 'host' object.
Args:
host (Union[ModuleType, HostBase]): Access to installed/registered
host (HostBase): Access to installed/registered
host object.
host_name (str): Name of host.
project_name (str): Project name which is main part of host
@ -554,7 +483,7 @@ class AYONAddon(ABC):
"""
pass
def cli(self, addon_click_group):
def cli(self, addon_click_group: click.Group) -> None:
"""Add commands to click group.
The best practise is to create click group for whole addon which is
@ -585,15 +514,21 @@ class AYONAddon(ABC):
class _AddonReportInfo:
def __init__(
self, class_name, name, version, report_value_by_label
):
self,
class_name: str,
name: str,
version: str,
report_value_by_label: dict[str, Optional[str]],
) -> None:
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):
def from_addon(
cls, addon: AYONAddon, report: dict[str, dict[str, int]]
) -> "_AddonReportInfo":
class_name = addon.__class__.__name__
report_value_by_label = {
label: reported.get(class_name)
@ -620,29 +555,35 @@ class AddonsManager:
_report_total_key = "Total"
_log = None
def __init__(self, settings=None, initialize=True):
def __init__(
self,
settings: Optional[dict[str, Any]] = None,
initialize: bool = True,
) -> None:
self._settings = settings
self._addons = []
self._addons_by_id = {}
self._addons_by_name = {}
self._addons: list[AYONAddon] = []
self._addons_by_id: dict[str, AYONAddon] = {}
self._addons_by_name: dict[str, AYONAddon] = {}
# For report of time consumption
self._report = {}
self._report: dict[str, dict[str, int]] = {}
if initialize:
self.initialize_addons()
self.connect_addons()
def __getitem__(self, addon_name):
def __getitem__(self, addon_name: str) -> AYONAddon:
return self._addons_by_name[addon_name]
@property
def log(self):
def log(self) -> logging.Logger:
if self._log is None:
self._log = logging.getLogger(self.__class__.__name__)
self._log = Logger.get_logger(self.__class__.__name__)
return self._log
def get(self, addon_name, default=None):
def get(
self, addon_name: str, default: Optional[Any] = None
) -> Union[AYONAddon, Any]:
"""Access addon by name.
Args:
@ -656,18 +597,20 @@ class AddonsManager:
return self._addons_by_name.get(addon_name, default)
@property
def addons(self):
def addons(self) -> list[AYONAddon]:
return list(self._addons)
@property
def addons_by_id(self):
def addons_by_id(self) -> dict[str, AYONAddon]:
return dict(self._addons_by_id)
@property
def addons_by_name(self):
def addons_by_name(self) -> dict[str, AYONAddon]:
return dict(self._addons_by_name)
def get_enabled_addon(self, addon_name, default=None):
def get_enabled_addon(
self, addon_name: str, default: Optional[Any] = None
) -> Union[AYONAddon, Any]:
"""Fast access to enabled addon.
If addon is available but is not enabled default value is returned.
@ -678,7 +621,7 @@ class AddonsManager:
not enabled.
Returns:
Union[AYONAddon, None]: Enabled addon found by name or None.
Union[AYONAddon, Any]: Enabled addon found by name or None.
"""
addon = self.get(addon_name)
@ -686,7 +629,7 @@ class AddonsManager:
return addon
return default
def get_enabled_addons(self):
def get_enabled_addons(self) -> list[AYONAddon]:
"""Enabled addons initialized by the manager.
Returns:
@ -699,7 +642,7 @@ class AddonsManager:
if addon.enabled
]
def initialize_addons(self):
def initialize_addons(self) -> None:
"""Import and initialize addons."""
# Make sure modules are loaded
load_addons()
@ -780,7 +723,7 @@ class AddonsManager:
report[self._report_total_key] = time.time() - time_start
self._report["Initialization"] = report
def connect_addons(self):
def connect_addons(self) -> None:
"""Trigger connection with other enabled addons.
Addons should handle their interfaces in `connect_with_addons`.
@ -789,7 +732,7 @@ class AddonsManager:
time_start = time.time()
prev_start_time = time_start
enabled_addons = self.get_enabled_addons()
self.log.debug("Has {} enabled addons.".format(len(enabled_addons)))
self.log.debug(f"Has {len(enabled_addons)} enabled addons.")
for addon in enabled_addons:
try:
addon.connect_with_addons(enabled_addons)
@ -808,7 +751,7 @@ class AddonsManager:
report[self._report_total_key] = time.time() - time_start
self._report["Connect modules"] = report
def collect_global_environments(self):
def collect_global_environments(self) -> dict[str, str]:
"""Helper to collect global environment variabled from modules.
Returns:
@ -831,7 +774,7 @@ class AddonsManager:
module_envs[key] = value
return module_envs
def collect_plugin_paths(self):
def collect_plugin_paths(self) -> dict[str, list[str]]:
"""Helper to collect all plugins from modules inherited IPluginPaths.
Unknown keys are logged out.
@ -890,7 +833,7 @@ class AddonsManager:
# Report unknown keys (Developing purposes)
if unknown_keys_by_addon:
expected_keys = ", ".join([
"\"{}\"".format(key) for key in output.keys()
f'"{key}"' for key in output.keys()
])
msg_template = "Addon: \"{}\" - got key {}"
msg_items = []
@ -899,12 +842,14 @@ class AddonsManager:
"\"{}\"".format(key) for key in keys
])
msg_items.append(msg_template.format(addon_name, joined_keys))
self.log.warning((
"Expected keys from `get_plugin_paths` are {}. {}"
).format(expected_keys, " | ".join(msg_items)))
joined_items = " | ".join(msg_items)
self.log.warning(
f"Expected keys from `get_plugin_paths` are {expected_keys}."
f" {joined_items}"
)
return output
def _collect_plugin_paths(self, method_name, *args, **kwargs):
def _collect_plugin_paths(self, method_name: str, *args, **kwargs):
output = []
for addon in self.get_enabled_addons():
# Skip addon that do not inherit from `IPluginPaths`
@ -935,7 +880,7 @@ class AddonsManager:
output.extend(paths)
return output
def collect_launcher_action_paths(self):
def collect_launcher_action_paths(self) -> list[str]:
"""Helper to collect launcher action paths from addons.
Returns:
@ -950,16 +895,16 @@ class AddonsManager:
output.insert(0, actions_dir)
return output
def collect_create_plugin_paths(self, host_name):
def collect_create_plugin_paths(self, host_name: str) -> list[str]:
"""Helper to collect creator plugin paths from addons.
Args:
host_name (str): For which host are creators meant.
Returns:
list: List of creator plugin paths.
"""
list[str]: List of creator plugin paths.
"""
return self._collect_plugin_paths(
"get_create_plugin_paths",
host_name
@ -967,37 +912,37 @@ class AddonsManager:
collect_creator_plugin_paths = collect_create_plugin_paths
def collect_load_plugin_paths(self, host_name):
def collect_load_plugin_paths(self, host_name: str) -> list[str]:
"""Helper to collect load plugin paths from addons.
Args:
host_name (str): For which host are load plugins meant.
Returns:
list: List of load plugin paths.
"""
list[str]: List of load plugin paths.
"""
return self._collect_plugin_paths(
"get_load_plugin_paths",
host_name
)
def collect_publish_plugin_paths(self, host_name):
def collect_publish_plugin_paths(self, host_name: str) -> list[str]:
"""Helper to collect load plugin paths from addons.
Args:
host_name (str): For which host are load plugins meant.
Returns:
list: List of pyblish plugin paths.
"""
list[str]: List of pyblish plugin paths.
"""
return self._collect_plugin_paths(
"get_publish_plugin_paths",
host_name
)
def collect_inventory_action_paths(self, host_name):
def collect_inventory_action_paths(self, host_name: str) -> list[str]:
"""Helper to collect load plugin paths from addons.
Args:
@ -1005,21 +950,21 @@ class AddonsManager:
Returns:
list: List of pyblish plugin paths.
"""
"""
return self._collect_plugin_paths(
"get_inventory_action_paths",
host_name
)
def get_host_addon(self, host_name):
def get_host_addon(self, host_name: str) -> Optional[AYONAddon]:
"""Find host addon by host name.
Args:
host_name (str): Host name for which is found host addon.
Returns:
Union[AYONAddon, None]: Found host addon by name or `None`.
Optional[AYONAddon]: Found host addon by name or `None`.
"""
for addon in self.get_enabled_addons():
@ -1030,21 +975,21 @@ class AddonsManager:
return addon
return None
def get_host_names(self):
def get_host_names(self) -> set[str]:
"""List of available host names based on host addons.
Returns:
Iterable[str]: All available host names based on enabled addons
set[str]: All available host names based on enabled addons
inheriting 'IHostAddon'.
"""
"""
return {
addon.host_name
for addon in self.get_enabled_addons()
if isinstance(addon, IHostAddon)
}
def print_report(self):
def print_report(self) -> None:
"""Print out report of time spent on addons initialization parts.
Reporting is not automated must be implemented for each initialization

View file

@ -420,11 +420,14 @@ def get_review_info_by_layer_name(channel_names):
channel = last_part[0].upper()
rgba_by_layer_name[layer_name][channel] = channel_name
# Put empty layer to the beginning of the list
# Put empty layer or 'rgba' to the beginning of the list
# - if input has R, G, B, A channels they should be used for review
if "" in layer_names_order:
layer_names_order.remove("")
layer_names_order.insert(0, "")
# NOTE They are iterated in reversed order because they're inserted to
# the beginning of 'layer_names_order' -> last added will be first.
for name in reversed(["", "rgba"]):
if name in layer_names_order:
layer_names_order.remove(name)
layer_names_order.insert(0, name)
output = []
for layer_name in layer_names_order:
@ -1519,12 +1522,27 @@ def get_media_mime_type(filepath: str) -> Optional[str]:
Optional[str]: Mime type or None if is unknown mime type.
"""
# The implementation is identical or better with ayon_api >=1.1.0,
# which is used in AYON launcher >=1.3.0.
# NOTE Remove safe import when AYON launcher >=1.2.0.
try:
from ayon_api.utils import (
get_media_mime_type_for_content as _ayon_api_func
)
except ImportError:
_ayon_api_func = None
if not filepath or not os.path.exists(filepath):
return None
with open(filepath, "rb") as stream:
content = stream.read()
if _ayon_api_func is not None:
mime_type = _ayon_api_func(content)
if mime_type is not None:
return mime_type
content_len = len(content)
# Pre-validation (largest definition check)
# - hopefully there cannot be media defined in less than 12 bytes
@ -1551,11 +1569,13 @@ def get_media_mime_type(filepath: str) -> Optional[str]:
if b'xmlns="http://www.w3.org/2000/svg"' in content:
return "image/svg+xml"
# JPEG, JFIF or Exif
if (
content[0:4] == b"\xff\xd8\xff\xdb"
or content[6:10] in (b"JFIF", b"Exif")
):
# JPEG
# - [0:2] is constant b"\xff\xd8"
# (ref. https://www.file-recovery.com/jpg-signature-format.htm)
# - [2:4] Marker identifier b"\xff{?}"
# (ref. https://www.disktuna.com/list-of-jpeg-markers/)
# NOTE: File ends with b"\xff\xd9"
if content[0:3] == b"\xff\xd8\xff":
return "image/jpeg"
# Webp

View file

@ -13,6 +13,8 @@ import copy
import pyblish.api
from ayon_core.pipeline.publish import get_publish_template_name
class CollectResourcesPath(pyblish.api.InstancePlugin):
"""Generate directory path where the files and resources will be stored.
@ -77,16 +79,29 @@ class CollectResourcesPath(pyblish.api.InstancePlugin):
# This is for cases of Deprecated anatomy without `folder`
# TODO remove when all clients have solved this issue
template_data.update({
"frame": "FRAME_TEMP",
"representation": "TEMP"
})
template_data.update({"frame": "FRAME_TEMP", "representation": "TEMP"})
publish_templates = anatomy.get_template_item(
"publish", "default", "directory"
task_name = task_type = None
task_entity = instance.data.get("taskEntity")
if task_entity:
task_name = task_entity["name"]
task_type = task_entity["taskType"]
template_name = get_publish_template_name(
project_name=instance.context.data["projectName"],
host_name=instance.context.data["hostName"],
product_type=instance.data["productType"],
task_name=task_name,
task_type=task_type,
project_settings=instance.context.data["project_settings"],
logger=self.log,
)
publish_template = anatomy.get_template_item(
"publish", template_name, "directory")
publish_folder = os.path.normpath(
publish_templates.format_strict(template_data)
publish_template.format_strict(template_data)
)
resources_folder = os.path.join(publish_folder, "resources")

View file

@ -6,6 +6,7 @@ import re
import pyblish.api
from ayon_core.lib import (
get_oiio_tool_args,
get_ffmpeg_tool_args,
get_ffprobe_data,
@ -15,7 +16,11 @@ from ayon_core.lib import (
path_to_subprocess_arg,
run_subprocess,
)
from ayon_core.lib.transcoding import oiio_color_convert
from ayon_core.lib.transcoding import (
oiio_color_convert,
get_oiio_input_and_channel_args,
get_oiio_info_for_input,
)
from ayon_core.lib.transcoding import VIDEO_EXTENSIONS, IMAGE_EXTENSIONS
@ -210,6 +215,12 @@ class ExtractThumbnail(pyblish.api.InstancePlugin):
full_output_path = os.path.join(dst_staging, jpeg_file)
colorspace_data = repre.get("colorspaceData")
# NOTE We should find out what is happening here. Why don't we
# use oiiotool all the time if it is available? Only possible
# reason might be that video files should be converted using
# ffmpeg, but other then that, we should use oiio all the time.
# - We should also probably get rid of the ffmpeg settings...
# only use OIIO if it is supported and representation has
# colorspace data
if oiio_supported and colorspace_data:
@ -219,7 +230,7 @@ class ExtractThumbnail(pyblish.api.InstancePlugin):
)
# If the input can read by OIIO then use OIIO method for
# conversion otherwise use ffmpeg
repre_thumb_created = self._create_thumbnail_oiio(
repre_thumb_created = self._create_colorspace_thumbnail(
full_input_path,
full_output_path,
colorspace_data
@ -229,17 +240,16 @@ class ExtractThumbnail(pyblish.api.InstancePlugin):
# oiiotool isn't available or representation is not having
# colorspace data
if not repre_thumb_created:
if oiio_supported:
self.log.debug(
"Converting with FFMPEG because input"
" can't be read by OIIO."
)
repre_thumb_created = self._create_thumbnail_ffmpeg(
full_input_path, full_output_path
)
# Skip representation and try next one if wasn't created
# Skip representation and try next one if wasn't created
if not repre_thumb_created and oiio_supported:
repre_thumb_created = self._create_thumbnail_oiio(
full_input_path, full_output_path
)
if not repre_thumb_created:
continue
@ -382,7 +392,7 @@ class ExtractThumbnail(pyblish.api.InstancePlugin):
return ext in IMAGE_EXTENSIONS or ext in VIDEO_EXTENSIONS
def _create_thumbnail_oiio(
def _create_colorspace_thumbnail(
self,
src_path,
dst_path,
@ -455,9 +465,50 @@ class ExtractThumbnail(pyblish.api.InstancePlugin):
return True
def _create_thumbnail_oiio(self, src_path, dst_path):
self.log.debug(f"Extracting thumbnail with OIIO: {dst_path}")
try:
resolution_arg = self._get_resolution_arg("oiiotool", src_path)
except RuntimeError:
self.log.warning(
"Failed to create thumbnail using oiio", exc_info=True
)
return False
input_info = get_oiio_info_for_input(src_path, logger=self.log)
input_arg, channels_arg = get_oiio_input_and_channel_args(input_info)
oiio_cmd = get_oiio_tool_args(
"oiiotool",
input_arg, src_path,
# Tell oiiotool which channels should be put to top stack
# (and output)
"--ch", channels_arg,
# Use first subimage
"--subimage", "0"
)
oiio_cmd.extend(resolution_arg)
oiio_cmd.extend(("-o", dst_path))
self.log.debug("Running: {}".format(" ".join(oiio_cmd)))
try:
run_subprocess(oiio_cmd, logger=self.log)
return True
except Exception:
self.log.warning(
"Failed to create thumbnail using oiiotool",
exc_info=True
)
return False
def _create_thumbnail_ffmpeg(self, src_path, dst_path):
self.log.debug("Extracting thumbnail with FFMPEG: {}".format(dst_path))
resolution_arg = self._get_resolution_arg("ffmpeg", src_path)
try:
resolution_arg = self._get_resolution_arg("ffmpeg", src_path)
except RuntimeError:
self.log.warning(
"Failed to create thumbnail using ffmpeg", exc_info=True
)
return False
ffmpeg_path_args = get_ffmpeg_tool_args("ffmpeg")
ffmpeg_args = self.ffmpeg_args or {}

View file

@ -6,7 +6,12 @@ import json
import tempfile
from string import Formatter
import opentimelineio_contrib.adapters.ffmpeg_burnins as ffmpeg_burnins
try:
from otio_burnins_adapter import ffmpeg_burnins
except ImportError:
import opentimelineio_contrib.adapters.ffmpeg_burnins as ffmpeg_burnins
from PIL import ImageFont
from ayon_core.lib import (
get_ffmpeg_tool_args,
get_ffmpeg_codec_args,
@ -36,6 +41,39 @@ TIMECODE_KEY = "{timecode}"
SOURCE_TIMECODE_KEY = "{source_timecode}"
def _drawtext(align, resolution, text, options):
"""
:rtype: {'x': int, 'y': int}
"""
x_pos = "0"
if align in (ffmpeg_burnins.TOP_CENTERED, ffmpeg_burnins.BOTTOM_CENTERED):
x_pos = "w/2-tw/2"
elif align in (ffmpeg_burnins.TOP_RIGHT, ffmpeg_burnins.BOTTOM_RIGHT):
ifont = ImageFont.truetype(options["font"], options["font_size"])
if hasattr(ifont, "getbbox"):
left, top, right, bottom = ifont.getbbox(text)
box_size = right - left, bottom - top
else:
box_size = ifont.getsize(text)
x_pos = resolution[0] - (box_size[0] + options["x_offset"])
elif align in (ffmpeg_burnins.TOP_LEFT, ffmpeg_burnins.BOTTOM_LEFT):
x_pos = options["x_offset"]
if align in (
ffmpeg_burnins.TOP_CENTERED,
ffmpeg_burnins.TOP_RIGHT,
ffmpeg_burnins.TOP_LEFT
):
y_pos = "%d" % options["y_offset"]
else:
y_pos = "h-text_h-%d" % (options["y_offset"])
return {"x": x_pos, "y": y_pos}
ffmpeg_burnins._drawtext = _drawtext
def _get_ffprobe_data(source):
"""Reimplemented from otio burnins to be able use full path to ffprobe
:param str source: source media file

View file

@ -41,7 +41,7 @@ class ScrollMessageBox(QtWidgets.QDialog):
"""
def __init__(self, icon, title, messages, cancelable=False):
super(ScrollMessageBox, self).__init__()
super().__init__()
self.setWindowTitle(title)
self.icon = icon
@ -49,8 +49,6 @@ class ScrollMessageBox(QtWidgets.QDialog):
self.setWindowFlags(QtCore.Qt.WindowTitleHint)
layout = QtWidgets.QVBoxLayout(self)
scroll_widget = QtWidgets.QScrollArea(self)
scroll_widget.setWidgetResizable(True)
content_widget = QtWidgets.QWidget(self)
@ -63,14 +61,8 @@ class ScrollMessageBox(QtWidgets.QDialog):
content_layout.addWidget(label_widget)
message_len = max(message_len, len(message))
# guess size of scrollable area
# WARNING: 'desktop' method probably won't work in PySide6
desktop = QtWidgets.QApplication.desktop()
max_width = desktop.availableGeometry().width()
scroll_widget.setMinimumWidth(
min(max_width, message_len * 6)
)
layout.addWidget(scroll_widget)
# Set minimum width
scroll_widget.setMinimumWidth(360)
buttons = QtWidgets.QDialogButtonBox.Ok
if cancelable:
@ -86,7 +78,9 @@ class ScrollMessageBox(QtWidgets.QDialog):
btn.clicked.connect(self._on_copy_click)
btn_box.addButton(btn, QtWidgets.QDialogButtonBox.NoRole)
layout.addWidget(btn_box)
main_layout = QtWidgets.QVBoxLayout(self)
main_layout.addWidget(scroll_widget, 1)
main_layout.addWidget(btn_box, 0)
def _on_copy_click(self):
clipboard = QtWidgets.QApplication.clipboard()
@ -104,7 +98,7 @@ class SimplePopup(QtWidgets.QDialog):
on_clicked = QtCore.Signal()
def __init__(self, parent=None, *args, **kwargs):
super(SimplePopup, self).__init__(parent=parent, *args, **kwargs)
super().__init__(parent=parent, *args, **kwargs)
# Set default title
self.setWindowTitle("Popup")
@ -161,7 +155,7 @@ class SimplePopup(QtWidgets.QDialog):
geo = self._calculate_window_geometry()
self.setGeometry(geo)
return super(SimplePopup, self).showEvent(event)
return super().showEvent(event)
def _on_clicked(self):
"""Callback for when the 'show' button is clicked.
@ -228,9 +222,7 @@ class PopupUpdateKeys(SimplePopup):
on_clicked_state = QtCore.Signal(bool)
def __init__(self, parent=None, *args, **kwargs):
super(PopupUpdateKeys, self).__init__(
parent=parent, *args, **kwargs
)
super().__init__(parent=parent, *args, **kwargs)
layout = self.layout()

View file

@ -85,12 +85,13 @@ account_circle_off f7b3
account_tree e97a
action_key f502
activity_zone e1e6
acupuncture f2c4
acute e4cb
ad e65a
ad_group e65b
ad_group_off eae5
ad_off f7b2
ad_units ef39
ad_units f2eb
adaptive_audio_mic f4cc
adaptive_audio_mic_off f4cb
adb e60e
@ -127,7 +128,7 @@ add_row_below f422
add_shopping_cart e854
add_task f23a
add_to_drive e65c
add_to_home_screen e1fe
add_to_home_screen f2b9
add_to_photos e39d
add_to_queue e05c
add_triangle f48e
@ -208,10 +209,36 @@ amp_stories ea13
analytics ef3e
anchor f1cd
android e859
android_cell_4_bar ef06
android_cell_4_bar_alert ef09
android_cell_4_bar_off ef08
android_cell_4_bar_plus ef07
android_cell_5_bar ef02
android_cell_5_bar_alert ef05
android_cell_5_bar_off ef04
android_cell_5_bar_plus ef03
android_cell_dual_4_bar ef0d
android_cell_dual_4_bar_alert ef0f
android_cell_dual_4_bar_plus ef0e
android_cell_dual_5_bar ef0a
android_cell_dual_5_bar_alert ef0c
android_cell_dual_5_bar_plus ef0b
android_wifi_3_bar ef16
android_wifi_3_bar_alert ef1b
android_wifi_3_bar_lock ef1a
android_wifi_3_bar_off ef19
android_wifi_3_bar_plus ef18
android_wifi_3_bar_question ef17
android_wifi_4_bar ef10
android_wifi_4_bar_alert ef15
android_wifi_4_bar_lock ef14
android_wifi_4_bar_off ef13
android_wifi_4_bar_plus ef12
android_wifi_4_bar_question ef11
animated_images f49a
animation e71c
announcement e87f
aod efda
aod f2e6
aod_tablet f89f
aod_watch f6ac
apartment ea40
@ -219,14 +246,15 @@ api f1b7
apk_document f88e
apk_install f88f
app_badging f72f
app_blocking ef3f
app_promo e981
app_blocking f2e5
app_promo f2cd
app_registration ef40
app_settings_alt ef41
app_shortcut eae4
app_settings_alt f2d9
app_shortcut f2df
apparel ef7b
approval e982
approval_delegation f84a
approval_delegation_off f2c5
apps e5c3
apps_outage e7cc
aq f55a
@ -265,6 +293,9 @@ arrow_range f69b
arrow_right e5df
arrow_right_alt e941
arrow_selector_tool f82f
arrow_shape_up eef6
arrow_shape_up_stack eef7
arrow_shape_up_stack_2 eef8
arrow_split ea04
arrow_top_left f72e
arrow_top_right f72d
@ -287,6 +318,7 @@ aspect_ratio e85b
assessment f0cc
assignment e85d
assignment_add f848
assignment_globe eeec
assignment_ind e85e
assignment_late e85f
assignment_return e860
@ -336,6 +368,7 @@ auto_read_pause f219
auto_read_play f216
auto_schedule e214
auto_stories e666
auto_stories_off f267
auto_timer ef7f
auto_towing e71e
auto_transmission f53f
@ -352,6 +385,7 @@ av_timer e01b
avc f4af
avg_pace f6bb
avg_time f813
award_meal f241
award_star f612
azm f6ec
baby_changing_station f19b
@ -370,6 +404,7 @@ backup e864
backup_table ef43
badge ea67
badge_critical_battery f156
badminton f2a8
bakery_dining ea53
balance eaf6
balcony e58f
@ -382,9 +417,11 @@ barcode_reader f85c
barcode_scanner e70c
barefoot f871
batch_prediction f0f5
bath_bedrock f286
bath_outdoor f6fb
bath_private f6fa
bath_public_large f6f9
bath_soak f2a0
bathroom efdd
bathtub ea41
battery_0_bar ebdc
@ -410,6 +447,19 @@ battery_android_5 f308
battery_android_6 f307
battery_android_alert f306
battery_android_bolt f305
battery_android_frame_1 f257
battery_android_frame_2 f256
battery_android_frame_3 f255
battery_android_frame_4 f254
battery_android_frame_5 f253
battery_android_frame_6 f252
battery_android_frame_alert f251
battery_android_frame_bolt f250
battery_android_frame_full f24f
battery_android_frame_plus f24e
battery_android_frame_question f24d
battery_android_frame_share f24c
battery_android_frame_shield f24b
battery_android_full f304
battery_android_plus f303
battery_android_question f302
@ -449,6 +499,7 @@ bedroom_parent efe2
bedtime f159
bedtime_off eb76
beenhere e52d
beer_meal f285
bento f1f4
bia f6eb
bid_landscape e678
@ -490,7 +541,7 @@ book_3 f53d
book_4 f53c
book_5 f53b
book_6 f3df
book_online f217
book_online f2e4
book_ribbon f3e7
bookmark e8e7
bookmark_add e598
@ -537,6 +588,7 @@ breaking_news ea08
breaking_news_alt_1 f0ba
breastfeeding f856
brick f388
briefcase_meal f246
brightness_1 e3fa
brightness_2 f036
brightness_3 e3a8
@ -564,6 +616,7 @@ brush e3ae
bubble ef83
bubble_chart e6dd
bubbles f64e
bucket_check ef2a
bug_report e868
build f8cd
build_circle ef48
@ -586,7 +639,11 @@ cake_add f85b
calculate ea5f
calendar_add_on ef85
calendar_apps_script f0bb
calendar_check f243
calendar_clock f540
calendar_lock f242
calendar_meal f296
calendar_meal_2 f240
calendar_month ebcc
calendar_today e935
calendar_view_day e936
@ -607,10 +664,10 @@ call_to_action e06c
camera e3af
camera_alt e412
camera_enhance e8fc
camera_front e3b1
camera_front f2c9
camera_indoor efe9
camera_outdoor efea
camera_rear e3b2
camera_rear f2c8
camera_roll e3b3
camera_video f7a6
cameraswitch efeb
@ -628,7 +685,9 @@ car_crash ebf2
car_defrost_left f344
car_defrost_low_left f343
car_defrost_low_right f342
car_defrost_mid_left f278
car_defrost_mid_low_left f341
car_defrost_mid_low_right f277
car_defrost_mid_right f340
car_defrost_right f33f
car_fan_low_left f33e
@ -674,17 +733,21 @@ center_focus_strong e3b4
center_focus_weak e3b5
chair efed
chair_alt efee
chair_counter f29f
chair_fireplace f29e
chair_umbrella f29d
chalet e585
change_circle e2e7
change_history e86b
charger e2ae
charging_station f19d
charging_station f2e3
chart_data e473
chat e0c9
chat_add_on f0f3
chat_apps_script f0bd
chat_bubble e0cb
chat_bubble_outline e0cb
chat_dashed eeed
chat_error f7ac
chat_info f52b
chat_paste_go f6bd
@ -695,6 +758,7 @@ check_box_outline_blank e835
check_circle f0be
check_circle_filled f0be
check_circle_outline f0be
check_circle_unread f27e
check_in_out f6f6
check_indeterminate_small f88a
check_small f88b
@ -707,13 +771,22 @@ checkroom f19e
cheer f6a8
chef_hat f357
chess f5e7
chess_bishop f261
chess_bishop_2 f262
chess_king f25f
chess_king_2 f260
chess_knight f25e
chess_pawn f3b6
chess_pawn_2 f25d
chess_queen f25c
chess_rook f25b
chevron_backward f46b
chevron_forward f46a
chevron_left e5cb
chevron_right e5cc
child_care eb41
child_friendly eb42
child_hat ef30
chip_extraction f821
chips e993
chrome_reader_mode e86d
@ -839,6 +912,7 @@ control_camera e074
control_point e3ba
control_point_duplicate e3bb
controller_gen e83d
conversation ef2f
conversion_path f0c1
conversion_path_off f7b4
convert_to_text f41f
@ -984,13 +1058,13 @@ detector_status e1e8
developer_board e30d
developer_board_off e4ff
developer_guide e99e
developer_mode e1b0
developer_mode f2e2
developer_mode_tv e874
device_band f2f5
device_hub e335
device_reset e8b3
device_thermostat e1ff
device_unknown e339
device_unknown f2e1
devices e326
devices_fold ebde
devices_fold_2 f406
@ -1004,10 +1078,14 @@ dialer_sip e0bb
dialogs e99f
dialpad e0bc
diamond ead5
diamond_shine f2b2
dictionary f539
difference eb7d
digital_out_of_home f1de
digital_wellbeing ef86
dine_heart f29c
dine_in f295
dine_lamp f29b
dining eff4
dinner_dining ea57
directions e52e
@ -1057,7 +1135,7 @@ do_not_disturb_on f08f
do_not_disturb_on_total_silence effb
do_not_step f19f
do_not_touch f1b0
dock e30e
dock f2e0
dock_to_bottom f7e6
dock_to_left f7e5
dock_to_right f7e4
@ -1112,6 +1190,8 @@ drive_file_move_rtl e9a1
drive_file_rename_outline e9a2
drive_folder_upload e9a3
drive_fusiontable e678
drone f25a
drone_2 f259
dropdown e9a4
dropper_eye f351
dry f1b3
@ -1139,8 +1219,8 @@ ecg f80f
ecg_heart f6e9
eco ea35
eda f6e8
edgesensor_high f005
edgesensor_low f006
edgesensor_high f2ef
edgesensor_low f2ee
edit f097
edit_arrow_down f380
edit_arrow_up f37f
@ -1266,6 +1346,8 @@ extension e87b
extension_off e4f5
eye_tracking f4c9
eyeglasses f6ee
eyeglasses_2 f2c7
eyeglasses_2_sound f265
face f008
face_2 f8da
face_3 f8db
@ -1285,6 +1367,7 @@ fact_check f0c5
factory ebbc
falling f60d
familiar_face_and_zone e21c
family_group eef2
family_history e0ad
family_home eb26
family_link eb19
@ -1379,6 +1462,7 @@ fit_screen ea10
fit_width f779
fitness_center eb43
fitness_tracker f463
fitness_trackers eef1
flag f0c6
flag_2 f40f
flag_check f3d8
@ -1515,6 +1599,8 @@ forward_media f6f4
forward_to_inbox f187
foundation f200
fragrance f345
frame_bug eeef
frame_exclamation eeee
frame_inspect f772
frame_person f8a6
frame_person_mic f4d5
@ -1541,8 +1627,10 @@ gallery_thumbnail f86f
gamepad e30f
games e30f
garage f011
garage_check f28d
garage_door e714
garage_home e82d
garage_money f28c
garden_cart f8a9
gas_meter ec19
gastroenterology e0f1
@ -1621,9 +1709,12 @@ h_plus_mobiledata f019
h_plus_mobiledata_badge f7df
hail e9b1
hallway e6f8
hanami_dango f23f
hand_bones f894
hand_gesture ef9c
hand_gesture_off f3f3
hand_meal f294
hand_package f293
handheld_controller f4c6
handshake ebcb
handwriting_recognition eb02
@ -1655,6 +1746,7 @@ headset_off e33a
healing e3f3
health_and_beauty ef9d
health_and_safety e1d5
health_cross f2c3
health_metrics f6e2
heap_snapshot_large f76e
heap_snapshot_multiple f76d
@ -1662,11 +1754,14 @@ heap_snapshot_thumbnail f76c
hearing e023
hearing_aid f464
hearing_aid_disabled f3b0
hearing_aid_disabled_left f2ec
hearing_aid_left f2ed
hearing_disabled f104
heart_broken eac2
heart_check f60a
heart_minus f883
heart_plus f884
heart_smile f292
heat f537
heat_pump ec18
heat_pump_balance e27e
@ -1682,6 +1777,7 @@ hexagon eb39
hide ef9e
hide_image f022
hide_source f023
high_chair f29a
high_density f79c
high_quality e024
high_res f54b
@ -1770,6 +1866,7 @@ iframe_off f71c
image e3f4
image_arrow_up f317
image_aspect_ratio e3f5
image_inset f247
image_not_supported f116
image_search e43f
imagesearch_roller e9b4
@ -1815,7 +1912,7 @@ insert_photo e3f4
insert_text f827
insights f092
install_desktop eb71
install_mobile eb72
install_mobile f2cd
instant_mix e026
integration_instructions ef54
interactive_space f7ff
@ -1830,6 +1927,8 @@ ios_share e6b8
iron e583
iso e3f6
jamboard_kiosk e9b5
japanese_curry f284
japanese_flag f283
javascript eb7c
join f84f
join_full f84f
@ -1838,6 +1937,7 @@ join_left eaf2
join_right eaea
joystick f5ee
jump_to_element f719
kanji_alcohol f23e
kayaking e50c
kebab_dining e842
keep f026
@ -2065,9 +2165,11 @@ magnification_small f83c
magnify_docked f7d6
magnify_fullscreen f7d5
mail e159
mail_asterisk eef4
mail_lock ec0a
mail_off f48b
mail_outline e159
mail_shield f249
male e58e
man e4eb
man_2 f8e1
@ -2079,6 +2181,8 @@ manage_search f02f
manga f5e3
manufacturing e726
map e55b
map_pin_heart f298
map_pin_review f297
map_search f3ca
maps_home_work f030
maps_ugc ef58
@ -2097,11 +2201,14 @@ markunread_mailbox e89b
masked_transitions e72e
masked_transitions_add f42b
masks f218
massage f2c2
match_case f6f1
match_case_off f36f
match_word f6f0
matter e907
maximize e930
meal_dinner f23d
meal_lunch f23c
measuring_tape f6af
media_bluetooth_off f031
media_bluetooth_on f032
@ -2120,6 +2227,7 @@ memory_alt f7a3
menstrual_health f6e1
menu e5d2
menu_book ea19
menu_book_2 f291
menu_open e9bd
merge eb98
merge_type e252
@ -2151,17 +2259,57 @@ mist e188
mitre f547
mixture_med e4c8
mms e618
mobile_friendly e200
mobile e7ba
mobile_2 f2db
mobile_3 f2da
mobile_alert f2d3
mobile_arrow_down f2cd
mobile_arrow_right f2d2
mobile_arrow_up_right f2b9
mobile_block f2e5
mobile_camera f44e
mobile_camera_front f2c9
mobile_camera_rear f2c8
mobile_cancel f2ea
mobile_cast f2cc
mobile_charge f2e3
mobile_chat f79f
mobile_check f073
mobile_code f2e2
mobile_dots f2d0
mobile_friendly f073
mobile_gear f2d9
mobile_hand f323
mobile_hand_left f313
mobile_hand_left_off f312
mobile_hand_off f314
mobile_info f2dc
mobile_landscape ed3e
mobile_layout f2bf
mobile_lock_landscape f2d8
mobile_lock_portrait f2be
mobile_loupe f322
mobile_menu f2d1
mobile_off e201
mobile_screen_share e0e7
mobile_question f2e1
mobile_rotate f2d5
mobile_rotate_lock f2d6
mobile_screen_share f2df
mobile_screensaver f321
mobile_sensor_hi f2ef
mobile_sensor_lo f2ee
mobile_share f2df
mobile_share_stack f2de
mobile_sound f2e8
mobile_sound_2 f318
mobile_sound_off f7aa
mobile_speaker f320
mobile_text f2eb
mobile_text_2 f2e6
mobile_theft f2a9
mobile_ticket f2e4
mobile_vibrate f2cb
mobile_wrench f2b0
mobiledata_off f034
mode f097
mode_comment e253
@ -2186,6 +2334,7 @@ money e57d
money_bag f3ee
money_off f038
money_off_csred f038
money_range f245
monitor ef5b
monitor_heart eaa2
monitor_weight f039
@ -2199,6 +2348,7 @@ mood_bad e7f3
moon_stars f34f
mop e28d
moped eb28
moped_package f28b
more e619
more_down f196
more_horiz e5d3
@ -2220,6 +2370,7 @@ motion_sensor_idle e783
motion_sensor_urgent e78e
motorcycle e91b
mountain_flag f5e2
mountain_steam f282
mouse e323
mouse_lock f490
mouse_lock_off f48f
@ -2241,6 +2392,7 @@ movie_edit f840
movie_filter e43a
movie_info e02d
movie_off f499
movie_speaker f2a3
moving e501
moving_beds e73d
moving_ministry e73e
@ -2252,6 +2404,7 @@ multiple_airports efab
multiple_stop f1b9
museum ea36
music_cast eb1a
music_history f2c1
music_note e405
music_note_add f391
music_off e440
@ -2288,6 +2441,11 @@ nest_display f124
nest_display_max f125
nest_doorbell_visitor f8bd
nest_eco_leaf f8be
nest_farsight_cool f27d
nest_farsight_dual f27c
nest_farsight_eco f27b
nest_farsight_heat f27a
nest_farsight_seasonal f279
nest_farsight_weather f8bf
nest_found_savings f8c0
nest_gale_wifi f579
@ -2356,7 +2514,7 @@ night_sight_max f6c3
nightlife ea62
nightlight f03d
nightlight_round f03d
nights_stay ea46
nights_stay f174
no_accounts f03e
no_adult_content f8fe
no_backpack f237
@ -2410,8 +2568,9 @@ odt e6e9
offline_bolt e932
offline_pin e90a
offline_pin_off f4d0
offline_share e9c5
offline_share f2de
oil_barrel ec15
okonomiyaki f281
on_device_training ebfd
on_hub_device e6c3
oncology e114
@ -2424,7 +2583,7 @@ open_in_full f1ce
open_in_new e89e
open_in_new_down f70f
open_in_new_off e4f6
open_in_phone e702
open_in_phone f2d2
open_jam efae
open_run f4b7
open_with e89f
@ -2461,10 +2620,12 @@ pacemaker e656
package e48f
package_2 f569
padding e9c8
padel f2a7
page_control e731
page_footer f383
page_header f384
page_info f614
page_menu_ios eefb
pageless f509
pages e7f9
pageview e8a0
@ -2481,10 +2642,15 @@ panorama_photosphere e9c9
panorama_vertical e40e
panorama_wide_angle e40f
paragliding e50f
parent_child_dining f22d
park ea63
parking_meter f28a
parking_sign f289
parking_valet f288
partly_cloudy_day f172
partly_cloudy_night f174
partner_exchange f7f9
partner_heart ef2e
partner_reports efaf
party_mode e7fa
passkey f87f
@ -2499,6 +2665,8 @@ pause_circle_filled e1a2
pause_circle_outline e1a2
pause_presentation e0ea
payment e8a1
payment_arrow_down f2c0
payment_card f2a1
payments ef63
pedal_bike eb29
pediatrics e11d
@ -2514,12 +2682,13 @@ people ea21
people_alt ea21
people_outline ea21
percent eb58
percent_discount f244
performance_max e51a
pergola e203
perm_camera_mic e8a2
perm_contact_calendar e8a3
perm_data_setting e8a4
perm_device_information e8a5
perm_device_information f2dc
perm_identity f0d3
perm_media e8a7
perm_phone_msg e8a8
@ -2539,6 +2708,7 @@ person_celebrate f7fe
person_check f565
person_edit f4fa
person_filled f0d3
person_heart f290
person_off e510
person_outline f0d3
person_pin e55a
@ -2561,24 +2731,24 @@ pets e91d
phishing ead7
phone f0d4
phone_alt f0d4
phone_android e324
phone_android f2db
phone_bluetooth_speaker e61b
phone_callback e649
phone_disabled e9cc
phone_enabled e9cd
phone_forwarded e61c
phone_in_talk e61d
phone_iphone e325
phone_iphone f2da
phone_locked e61e
phone_missed e61f
phone_paused e620
phonelink e326
phonelink_erase e0db
phonelink_lock e0dc
phonelink_off e327
phonelink_ring e0dd
phonelink_erase f2ea
phonelink_lock f2be
phonelink_off f7a5
phonelink_ring f2e8
phonelink_ring_off f7aa
phonelink_setup ef41
phonelink_setup f2d9
photo e432
photo_album e411
photo_auto_merge f530
@ -2596,6 +2766,7 @@ php eb8f
physical_therapy e11e
piano e521
piano_off e520
pickleball f2a6
picture_as_pdf e415
picture_in_picture e8aa
picture_in_picture_alt e911
@ -2626,6 +2797,7 @@ pivot_table_chart e9ce
place f1db
place_item f1f0
plagiarism ea5a
plane_contrails f2ac
planet f387
planner_banner_ad_pt e692
planner_review e694
@ -2637,6 +2809,8 @@ play_lesson f047
play_music e6ee
play_pause f137
play_shapes f7fc
playground f28e
playground_2 f28f
playing_cards f5dc
playlist_add e03b
playlist_add_check e065
@ -2818,6 +2992,7 @@ report_problem f083
request_page f22c
request_quote f1b6
reset_brightness f482
reset_exposure f266
reset_focus f481
reset_image f824
reset_iso f480
@ -2830,6 +3005,7 @@ reset_wrench f56c
resize f707
respiratory_rate e127
responsive_layout e9da
rest_area f22a
restart_alt f053
restaurant e56c
restaurant_menu e561
@ -2913,11 +3089,11 @@ science_off f542
scooter f471
score e269
scoreboard ebd0
screen_lock_landscape e1be
screen_lock_portrait e1bf
screen_lock_rotation e1c0
screen_lock_landscape f2d8
screen_lock_portrait f2be
screen_lock_rotation f2d6
screen_record f679
screen_rotation e1c1
screen_rotation f2d5
screen_rotation_alt ebee
screen_rotation_up f678
screen_search_desktop ef70
@ -2941,6 +3117,7 @@ search e8b6
search_activity f3e5
search_check f800
search_check_2 f469
search_gear eefa
search_hands_free e696
search_insights f4bc
search_off ea76
@ -2952,9 +3129,9 @@ seat_vent_left f32d
seat_vent_right f32c
security e32a
security_key f503
security_update f072
security_update f2cd
security_update_good f073
security_update_warning f074
security_update_warning f2d3
segment e94b
select f74d
select_all e162
@ -2970,7 +3147,7 @@ send e163
send_and_archive ea0c
send_money e8b7
send_time_extension eadb
send_to_mobile f05c
send_to_mobile f2d2
sensor_door f1b5
sensor_occupied ec10
sensor_window f1b4
@ -3005,7 +3182,7 @@ settings_b_roll f625
settings_backup_restore e8ba
settings_bluetooth e8bb
settings_brightness e8bd
settings_cell e8bc
settings_cell f2d1
settings_cinematic_blur f624
settings_ethernet e8be
settings_heart f522
@ -3022,6 +3199,7 @@ settings_phone e8c5
settings_photo_camera f834
settings_power e8c6
settings_remote e8c7
settings_seating ef2d
settings_slow_motion f623
settings_suggest f05e
settings_system_daydream e1c3
@ -3042,6 +3220,7 @@ share_location f05f
share_off f6cb
share_reviews f8a4
share_windows f613
shaved_ice f225
sheets_rtl f823
shelf_auto_hide f703
shelf_position f702
@ -3052,6 +3231,7 @@ shield_locked f592
shield_moon eaa9
shield_person f650
shield_question f529
shield_toggle f2ad
shield_watch f30f
shield_with_heart e78f
shield_with_house e78d
@ -3081,6 +3261,7 @@ shutter_speed_minus f57d
sick f220
side_navigation e9e2
sign_language ebe5
sign_language_2 f258
signal_cellular_0_bar f0a8
signal_cellular_1_bar f0a9
signal_cellular_2_bar f0aa
@ -3140,9 +3321,9 @@ smart_card_reader f4a5
smart_card_reader_off f4a6
smart_display f06a
smart_outlet e844
smart_screen f06b
smart_screen f2d0
smart_toy f06c
smartphone e32c
smartphone e7ba
smartphone_camera f44e
smb_share f74b
smoke_free eb4a
@ -3157,9 +3338,11 @@ snowing_heavy f61c
snowmobile e503
snowshoeing e514
soap f1b2
soba ef36
social_distance e1cb
social_leaderboard f6a0
solar_power ec0f
solo_dining ef35
sort e164
sort_by_alpha e053
sos ebf7
@ -3283,10 +3466,10 @@ stat_3 e69a
stat_minus_1 e69b
stat_minus_2 e69c
stat_minus_3 e69d
stay_current_landscape e0d3
stay_current_portrait e0d4
stay_primary_landscape e0d5
stay_primary_portrait e0d6
stay_current_landscape ed3e
stay_current_portrait e7ba
stay_primary_landscape ed3e
stay_primary_portrait f2d3
steering_wheel_heat f32b
step f6fe
step_into f701
@ -3340,6 +3523,7 @@ subtitles e048
subtitles_gear f355
subtitles_off ef72
subway e56f
subway_walk f287
summarize f071
sunny e81a
sunny_snowing e819
@ -3395,11 +3579,12 @@ sync_disabled e628
sync_lock eaee
sync_problem e629
sync_saved_locally f820
sync_saved_locally_off f264
syringe e133
system_security_update f072
system_security_update f2cd
system_security_update_good f073
system_security_update_warning f074
system_update f072
system_security_update_warning f2d3
system_update f2cd
system_update_alt e8d7
tab e8d8
tab_close f745
@ -3421,9 +3606,11 @@ table_convert f3c7
table_edit f3c6
table_eye f466
table_lamp e1f2
table_large f299
table_restaurant eac6
table_rows f101
table_rows_narrow f73f
table_sign ef2c
table_view f1be
tablet e32f
tablet_android e330
@ -3434,13 +3621,15 @@ tactic f564
tag e9ef
tag_faces ea22
takeout_dining ea74
takeout_dining_2 ef34
tamper_detection_off e82e
tamper_detection_on f8c8
tap_and_play e62b
tap_and_play f2cc
tapas f1e9
target e719
task f075
task_alt e2e6
tatami_seat ef33
taunt f69f
taxi_alert ef74
team_dashboard e013
@ -3507,6 +3696,7 @@ thumb_up_filled f577
thumb_up_off f577
thumb_up_off_alt f577
thumbnail_bar f734
thumbs_up_double eefc
thumbs_up_down e8dd
thunderstorm ebdb
tibia f89b
@ -3519,9 +3709,11 @@ time_to_leave eff7
timelapse e422
timeline e922
timer e425
timer_1 f2af
timer_10 e423
timer_10_alt_1 efbf
timer_10_select f07a
timer_2 f2ae
timer_3 e424
timer_3_alt_1 efc0
timer_3_select f07b
@ -3544,6 +3736,7 @@ toggle_on e9f6
token ea25
toll e8e0
tonality e427
tonality_2 f2b4
toolbar e9f7
tools_flat_head f8cb
tools_installation_kit e2ab
@ -3593,6 +3786,7 @@ transition_fade f50c
transition_push f50b
transition_slide f50a
translate e8e2
translate_indic f263
transportation e21d
travel ef93
travel_explore e2db
@ -3637,6 +3831,7 @@ two_wheeler e9f9
type_specimen f8f0
u_turn_left eba1
u_turn_right eba2
udon ef32
ulna_radius f89d
ulna_radius_alt f89e
umbrella f1ad
@ -3693,7 +3888,7 @@ vertical_distribute e076
vertical_shades ec0e
vertical_shades_closed ec0d
vertical_split e949
vibration e62d
vibration f2cb
video_call e070
video_camera_back f07f
video_camera_back_add f40c
@ -3738,6 +3933,7 @@ view_stream e8f2
view_timeline eb85
view_week e8f3
vignette e435
vignette_2 f2b3
villa e586
visibility e8f4
visibility_lock f653
@ -3780,7 +3976,9 @@ warning f083
warning_amber f083
warning_off f7ad
wash f1b1
washoku f280
watch e334
watch_arrow f2ca
watch_button_press f6aa
watch_check f468
watch_later efd6
@ -3867,6 +4065,7 @@ window f088
window_closed e77e
window_open e78c
window_sensor e2bb
windshield_defrost_auto f248
windshield_defrost_front f32a
windshield_defrost_rear f329
windshield_heat_front f328
@ -3888,7 +4087,9 @@ wrap_text e25b
wrist f69c
wrong_location ef78
wysiwyg f1c3
yakitori ef31
yard f089
yoshoku f27f
your_trips eb2b
youtube_activity f85a
youtube_searched_for e8fa

View file

@ -86,12 +86,13 @@
"account_tree": 59770,
"action_key": 62722,
"activity_zone": 57830,
"acupuncture": 62148,
"acute": 58571,
"ad": 58970,
"ad_group": 58971,
"ad_group_off": 60133,
"ad_off": 63410,
"ad_units": 61241,
"ad_units": 62187,
"adaptive_audio_mic": 62668,
"adaptive_audio_mic_off": 62667,
"adb": 58894,
@ -128,7 +129,7 @@
"add_shopping_cart": 59476,
"add_task": 62010,
"add_to_drive": 58972,
"add_to_home_screen": 57854,
"add_to_home_screen": 62137,
"add_to_photos": 58269,
"add_to_queue": 57436,
"add_triangle": 62606,
@ -209,10 +210,36 @@
"analytics": 61246,
"anchor": 61901,
"android": 59481,
"android_cell_4_bar": 61190,
"android_cell_4_bar_alert": 61193,
"android_cell_4_bar_off": 61192,
"android_cell_4_bar_plus": 61191,
"android_cell_5_bar": 61186,
"android_cell_5_bar_alert": 61189,
"android_cell_5_bar_off": 61188,
"android_cell_5_bar_plus": 61187,
"android_cell_dual_4_bar": 61197,
"android_cell_dual_4_bar_alert": 61199,
"android_cell_dual_4_bar_plus": 61198,
"android_cell_dual_5_bar": 61194,
"android_cell_dual_5_bar_alert": 61196,
"android_cell_dual_5_bar_plus": 61195,
"android_wifi_3_bar": 61206,
"android_wifi_3_bar_alert": 61211,
"android_wifi_3_bar_lock": 61210,
"android_wifi_3_bar_off": 61209,
"android_wifi_3_bar_plus": 61208,
"android_wifi_3_bar_question": 61207,
"android_wifi_4_bar": 61200,
"android_wifi_4_bar_alert": 61205,
"android_wifi_4_bar_lock": 61204,
"android_wifi_4_bar_off": 61203,
"android_wifi_4_bar_plus": 61202,
"android_wifi_4_bar_question": 61201,
"animated_images": 62618,
"animation": 59164,
"announcement": 59519,
"aod": 61402,
"aod": 62182,
"aod_tablet": 63647,
"aod_watch": 63148,
"apartment": 59968,
@ -220,14 +247,15 @@
"apk_document": 63630,
"apk_install": 63631,
"app_badging": 63279,
"app_blocking": 61247,
"app_promo": 59777,
"app_blocking": 62181,
"app_promo": 62157,
"app_registration": 61248,
"app_settings_alt": 61249,
"app_shortcut": 60132,
"app_settings_alt": 62169,
"app_shortcut": 62175,
"apparel": 61307,
"approval": 59778,
"approval_delegation": 63562,
"approval_delegation_off": 62149,
"apps": 58819,
"apps_outage": 59340,
"aq": 62810,
@ -266,6 +294,9 @@
"arrow_right": 58847,
"arrow_right_alt": 59713,
"arrow_selector_tool": 63535,
"arrow_shape_up": 61174,
"arrow_shape_up_stack": 61175,
"arrow_shape_up_stack_2": 61176,
"arrow_split": 59908,
"arrow_top_left": 63278,
"arrow_top_right": 63277,
@ -288,6 +319,7 @@
"assessment": 61644,
"assignment": 59485,
"assignment_add": 63560,
"assignment_globe": 61164,
"assignment_ind": 59486,
"assignment_late": 59487,
"assignment_return": 59488,
@ -337,6 +369,7 @@
"auto_read_play": 61974,
"auto_schedule": 57876,
"auto_stories": 58982,
"auto_stories_off": 62055,
"auto_timer": 61311,
"auto_towing": 59166,
"auto_transmission": 62783,
@ -353,6 +386,7 @@
"avc": 62639,
"avg_pace": 63163,
"avg_time": 63507,
"award_meal": 62017,
"award_star": 62994,
"azm": 63212,
"baby_changing_station": 61851,
@ -371,6 +405,7 @@
"backup_table": 61251,
"badge": 60007,
"badge_critical_battery": 61782,
"badminton": 62120,
"bakery_dining": 59987,
"balance": 60150,
"balcony": 58767,
@ -383,9 +418,11 @@
"barcode_scanner": 59148,
"barefoot": 63601,
"batch_prediction": 61685,
"bath_bedrock": 62086,
"bath_outdoor": 63227,
"bath_private": 63226,
"bath_public_large": 63225,
"bath_soak": 62112,
"bathroom": 61405,
"bathtub": 59969,
"battery_0_bar": 60380,
@ -411,6 +448,19 @@
"battery_android_6": 62215,
"battery_android_alert": 62214,
"battery_android_bolt": 62213,
"battery_android_frame_1": 62039,
"battery_android_frame_2": 62038,
"battery_android_frame_3": 62037,
"battery_android_frame_4": 62036,
"battery_android_frame_5": 62035,
"battery_android_frame_6": 62034,
"battery_android_frame_alert": 62033,
"battery_android_frame_bolt": 62032,
"battery_android_frame_full": 62031,
"battery_android_frame_plus": 62030,
"battery_android_frame_question": 62029,
"battery_android_frame_share": 62028,
"battery_android_frame_shield": 62027,
"battery_android_full": 62212,
"battery_android_plus": 62211,
"battery_android_question": 62210,
@ -450,6 +500,7 @@
"bedtime": 61785,
"bedtime_off": 60278,
"beenhere": 58669,
"beer_meal": 62085,
"bento": 61940,
"bia": 63211,
"bid_landscape": 59000,
@ -491,7 +542,7 @@
"book_4": 62780,
"book_5": 62779,
"book_6": 62431,
"book_online": 61975,
"book_online": 62180,
"book_ribbon": 62439,
"bookmark": 59623,
"bookmark_add": 58776,
@ -538,6 +589,7 @@
"breaking_news_alt_1": 61626,
"breastfeeding": 63574,
"brick": 62344,
"briefcase_meal": 62022,
"brightness_1": 58362,
"brightness_2": 61494,
"brightness_3": 58280,
@ -565,6 +617,7 @@
"bubble": 61315,
"bubble_chart": 59101,
"bubbles": 63054,
"bucket_check": 61226,
"bug_report": 59496,
"build": 63693,
"build_circle": 61256,
@ -587,7 +640,11 @@
"calculate": 59999,
"calendar_add_on": 61317,
"calendar_apps_script": 61627,
"calendar_check": 62019,
"calendar_clock": 62784,
"calendar_lock": 62018,
"calendar_meal": 62102,
"calendar_meal_2": 62016,
"calendar_month": 60364,
"calendar_today": 59701,
"calendar_view_day": 59702,
@ -608,10 +665,10 @@
"camera": 58287,
"camera_alt": 58386,
"camera_enhance": 59644,
"camera_front": 58289,
"camera_front": 62153,
"camera_indoor": 61417,
"camera_outdoor": 61418,
"camera_rear": 58290,
"camera_rear": 62152,
"camera_roll": 58291,
"camera_video": 63398,
"cameraswitch": 61419,
@ -629,7 +686,9 @@
"car_defrost_left": 62276,
"car_defrost_low_left": 62275,
"car_defrost_low_right": 62274,
"car_defrost_mid_left": 62072,
"car_defrost_mid_low_left": 62273,
"car_defrost_mid_low_right": 62071,
"car_defrost_mid_right": 62272,
"car_defrost_right": 62271,
"car_fan_low_left": 62270,
@ -675,17 +734,21 @@
"center_focus_weak": 58293,
"chair": 61421,
"chair_alt": 61422,
"chair_counter": 62111,
"chair_fireplace": 62110,
"chair_umbrella": 62109,
"chalet": 58757,
"change_circle": 58087,
"change_history": 59499,
"charger": 58030,
"charging_station": 61853,
"charging_station": 62179,
"chart_data": 58483,
"chat": 57545,
"chat_add_on": 61683,
"chat_apps_script": 61629,
"chat_bubble": 57547,
"chat_bubble_outline": 57547,
"chat_dashed": 61165,
"chat_error": 63404,
"chat_info": 62763,
"chat_paste_go": 63165,
@ -696,6 +759,7 @@
"check_circle": 61630,
"check_circle_filled": 61630,
"check_circle_outline": 61630,
"check_circle_unread": 62078,
"check_in_out": 63222,
"check_indeterminate_small": 63626,
"check_small": 63627,
@ -708,13 +772,22 @@
"cheer": 63144,
"chef_hat": 62295,
"chess": 62951,
"chess_bishop": 62049,
"chess_bishop_2": 62050,
"chess_king": 62047,
"chess_king_2": 62048,
"chess_knight": 62046,
"chess_pawn": 62390,
"chess_pawn_2": 62045,
"chess_queen": 62044,
"chess_rook": 62043,
"chevron_backward": 62571,
"chevron_forward": 62570,
"chevron_left": 58827,
"chevron_right": 58828,
"child_care": 60225,
"child_friendly": 60226,
"child_hat": 61232,
"chip_extraction": 63521,
"chips": 59795,
"chrome_reader_mode": 59501,
@ -840,6 +913,7 @@
"control_point": 58298,
"control_point_duplicate": 58299,
"controller_gen": 59453,
"conversation": 61231,
"conversion_path": 61633,
"conversion_path_off": 63412,
"convert_to_text": 62495,
@ -985,13 +1059,13 @@
"developer_board": 58125,
"developer_board_off": 58623,
"developer_guide": 59806,
"developer_mode": 57776,
"developer_mode": 62178,
"developer_mode_tv": 59508,
"device_band": 62197,
"device_hub": 58165,
"device_reset": 59571,
"device_thermostat": 57855,
"device_unknown": 58169,
"device_unknown": 62177,
"devices": 58150,
"devices_fold": 60382,
"devices_fold_2": 62470,
@ -1005,10 +1079,14 @@
"dialogs": 59807,
"dialpad": 57532,
"diamond": 60117,
"diamond_shine": 62130,
"dictionary": 62777,
"difference": 60285,
"digital_out_of_home": 61918,
"digital_wellbeing": 61318,
"dine_heart": 62108,
"dine_in": 62101,
"dine_lamp": 62107,
"dining": 61428,
"dinner_dining": 59991,
"directions": 58670,
@ -1058,7 +1136,7 @@
"do_not_disturb_on_total_silence": 61435,
"do_not_step": 61855,
"do_not_touch": 61872,
"dock": 58126,
"dock": 62176,
"dock_to_bottom": 63462,
"dock_to_left": 63461,
"dock_to_right": 63460,
@ -1113,6 +1191,8 @@
"drive_file_rename_outline": 59810,
"drive_folder_upload": 59811,
"drive_fusiontable": 59000,
"drone": 62042,
"drone_2": 62041,
"dropdown": 59812,
"dropper_eye": 62289,
"dry": 61875,
@ -1140,8 +1220,8 @@
"ecg_heart": 63209,
"eco": 59957,
"eda": 63208,
"edgesensor_high": 61445,
"edgesensor_low": 61446,
"edgesensor_high": 62191,
"edgesensor_low": 62190,
"edit": 61591,
"edit_arrow_down": 62336,
"edit_arrow_up": 62335,
@ -1267,6 +1347,8 @@
"extension_off": 58613,
"eye_tracking": 62665,
"eyeglasses": 63214,
"eyeglasses_2": 62151,
"eyeglasses_2_sound": 62053,
"face": 61448,
"face_2": 63706,
"face_3": 63707,
@ -1286,6 +1368,7 @@
"factory": 60348,
"falling": 62989,
"familiar_face_and_zone": 57884,
"family_group": 61170,
"family_history": 57517,
"family_home": 60198,
"family_link": 60185,
@ -1380,6 +1463,7 @@
"fit_width": 63353,
"fitness_center": 60227,
"fitness_tracker": 62563,
"fitness_trackers": 61169,
"flag": 61638,
"flag_2": 62479,
"flag_check": 62424,
@ -1516,6 +1600,8 @@
"forward_to_inbox": 61831,
"foundation": 61952,
"fragrance": 62277,
"frame_bug": 61167,
"frame_exclamation": 61166,
"frame_inspect": 63346,
"frame_person": 63654,
"frame_person_mic": 62677,
@ -1542,8 +1628,10 @@
"gamepad": 58127,
"games": 58127,
"garage": 61457,
"garage_check": 62093,
"garage_door": 59156,
"garage_home": 59437,
"garage_money": 62092,
"garden_cart": 63657,
"gas_meter": 60441,
"gastroenterology": 57585,
@ -1622,9 +1710,12 @@
"h_plus_mobiledata_badge": 63455,
"hail": 59825,
"hallway": 59128,
"hanami_dango": 62015,
"hand_bones": 63636,
"hand_gesture": 61340,
"hand_gesture_off": 62451,
"hand_meal": 62100,
"hand_package": 62099,
"handheld_controller": 62662,
"handshake": 60363,
"handwriting_recognition": 60162,
@ -1656,6 +1747,7 @@
"healing": 58355,
"health_and_beauty": 61341,
"health_and_safety": 57813,
"health_cross": 62147,
"health_metrics": 63202,
"heap_snapshot_large": 63342,
"heap_snapshot_multiple": 63341,
@ -1663,11 +1755,14 @@
"hearing": 57379,
"hearing_aid": 62564,
"hearing_aid_disabled": 62384,
"hearing_aid_disabled_left": 62188,
"hearing_aid_left": 62189,
"hearing_disabled": 61700,
"heart_broken": 60098,
"heart_check": 62986,
"heart_minus": 63619,
"heart_plus": 63620,
"heart_smile": 62098,
"heat": 62775,
"heat_pump": 60440,
"heat_pump_balance": 57982,
@ -1683,6 +1778,7 @@
"hide": 61342,
"hide_image": 61474,
"hide_source": 61475,
"high_chair": 62106,
"high_density": 63388,
"high_quality": 57380,
"high_res": 62795,
@ -1771,6 +1867,7 @@
"image": 58356,
"image_arrow_up": 62231,
"image_aspect_ratio": 58357,
"image_inset": 62023,
"image_not_supported": 61718,
"image_search": 58431,
"imagesearch_roller": 59828,
@ -1816,7 +1913,7 @@
"insert_text": 63527,
"insights": 61586,
"install_desktop": 60273,
"install_mobile": 60274,
"install_mobile": 62157,
"instant_mix": 57382,
"integration_instructions": 61268,
"interactive_space": 63487,
@ -1831,6 +1928,8 @@
"iron": 58755,
"iso": 58358,
"jamboard_kiosk": 59829,
"japanese_curry": 62084,
"japanese_flag": 62083,
"javascript": 60284,
"join": 63567,
"join_full": 63567,
@ -1839,6 +1938,7 @@
"join_right": 60138,
"joystick": 62958,
"jump_to_element": 63257,
"kanji_alcohol": 62014,
"kayaking": 58636,
"kebab_dining": 59458,
"keep": 61478,
@ -2066,9 +2166,11 @@
"magnify_docked": 63446,
"magnify_fullscreen": 63445,
"mail": 57689,
"mail_asterisk": 61172,
"mail_lock": 60426,
"mail_off": 62603,
"mail_outline": 57689,
"mail_shield": 62025,
"male": 58766,
"man": 58603,
"man_2": 63713,
@ -2080,6 +2182,8 @@
"manga": 62947,
"manufacturing": 59174,
"map": 58715,
"map_pin_heart": 62104,
"map_pin_review": 62103,
"map_search": 62410,
"maps_home_work": 61488,
"maps_ugc": 61272,
@ -2098,11 +2202,14 @@
"masked_transitions": 59182,
"masked_transitions_add": 62507,
"masks": 61976,
"massage": 62146,
"match_case": 63217,
"match_case_off": 62319,
"match_word": 63216,
"matter": 59655,
"maximize": 59696,
"meal_dinner": 62013,
"meal_lunch": 62012,
"measuring_tape": 63151,
"media_bluetooth_off": 61489,
"media_bluetooth_on": 61490,
@ -2121,6 +2228,7 @@
"menstrual_health": 63201,
"menu": 58834,
"menu_book": 59929,
"menu_book_2": 62097,
"menu_open": 59837,
"merge": 60312,
"merge_type": 57938,
@ -2152,17 +2260,57 @@
"mitre": 62791,
"mixture_med": 58568,
"mms": 58904,
"mobile_friendly": 57856,
"mobile": 59322,
"mobile_2": 62171,
"mobile_3": 62170,
"mobile_alert": 62163,
"mobile_arrow_down": 62157,
"mobile_arrow_right": 62162,
"mobile_arrow_up_right": 62137,
"mobile_block": 62181,
"mobile_camera": 62542,
"mobile_camera_front": 62153,
"mobile_camera_rear": 62152,
"mobile_cancel": 62186,
"mobile_cast": 62156,
"mobile_charge": 62179,
"mobile_chat": 63391,
"mobile_check": 61555,
"mobile_code": 62178,
"mobile_dots": 62160,
"mobile_friendly": 61555,
"mobile_gear": 62169,
"mobile_hand": 62243,
"mobile_hand_left": 62227,
"mobile_hand_left_off": 62226,
"mobile_hand_off": 62228,
"mobile_info": 62172,
"mobile_landscape": 60734,
"mobile_layout": 62143,
"mobile_lock_landscape": 62168,
"mobile_lock_portrait": 62142,
"mobile_loupe": 62242,
"mobile_menu": 62161,
"mobile_off": 57857,
"mobile_screen_share": 57575,
"mobile_question": 62177,
"mobile_rotate": 62165,
"mobile_rotate_lock": 62166,
"mobile_screen_share": 62175,
"mobile_screensaver": 62241,
"mobile_sensor_hi": 62191,
"mobile_sensor_lo": 62190,
"mobile_share": 62175,
"mobile_share_stack": 62174,
"mobile_sound": 62184,
"mobile_sound_2": 62232,
"mobile_sound_off": 63402,
"mobile_speaker": 62240,
"mobile_text": 62187,
"mobile_text_2": 62182,
"mobile_theft": 62121,
"mobile_ticket": 62180,
"mobile_vibrate": 62155,
"mobile_wrench": 62128,
"mobiledata_off": 61492,
"mode": 61591,
"mode_comment": 57939,
@ -2187,6 +2335,7 @@
"money_bag": 62446,
"money_off": 61496,
"money_off_csred": 61496,
"money_range": 62021,
"monitor": 61275,
"monitor_heart": 60066,
"monitor_weight": 61497,
@ -2200,6 +2349,7 @@
"moon_stars": 62287,
"mop": 57997,
"moped": 60200,
"moped_package": 62091,
"more": 58905,
"more_down": 61846,
"more_horiz": 58835,
@ -2221,6 +2371,7 @@
"motion_sensor_urgent": 59278,
"motorcycle": 59675,
"mountain_flag": 62946,
"mountain_steam": 62082,
"mouse": 58147,
"mouse_lock": 62608,
"mouse_lock_off": 62607,
@ -2242,6 +2393,7 @@
"movie_filter": 58426,
"movie_info": 57389,
"movie_off": 62617,
"movie_speaker": 62115,
"moving": 58625,
"moving_beds": 59197,
"moving_ministry": 59198,
@ -2253,6 +2405,7 @@
"multiple_stop": 61881,
"museum": 59958,
"music_cast": 60186,
"music_history": 62145,
"music_note": 58373,
"music_note_add": 62353,
"music_off": 58432,
@ -2289,6 +2442,11 @@
"nest_display_max": 61733,
"nest_doorbell_visitor": 63677,
"nest_eco_leaf": 63678,
"nest_farsight_cool": 62077,
"nest_farsight_dual": 62076,
"nest_farsight_eco": 62075,
"nest_farsight_heat": 62074,
"nest_farsight_seasonal": 62073,
"nest_farsight_weather": 63679,
"nest_found_savings": 63680,
"nest_gale_wifi": 62841,
@ -2357,7 +2515,7 @@
"nightlife": 60002,
"nightlight": 61501,
"nightlight_round": 61501,
"nights_stay": 59974,
"nights_stay": 61812,
"no_accounts": 61502,
"no_adult_content": 63742,
"no_backpack": 62007,
@ -2411,8 +2569,9 @@
"offline_bolt": 59698,
"offline_pin": 59658,
"offline_pin_off": 62672,
"offline_share": 59845,
"offline_share": 62174,
"oil_barrel": 60437,
"okonomiyaki": 62081,
"on_device_training": 60413,
"on_hub_device": 59075,
"oncology": 57620,
@ -2425,7 +2584,7 @@
"open_in_new": 59550,
"open_in_new_down": 63247,
"open_in_new_off": 58614,
"open_in_phone": 59138,
"open_in_phone": 62162,
"open_jam": 61358,
"open_run": 62647,
"open_with": 59551,
@ -2462,10 +2621,12 @@
"package": 58511,
"package_2": 62825,
"padding": 59848,
"padel": 62119,
"page_control": 59185,
"page_footer": 62339,
"page_header": 62340,
"page_info": 62996,
"page_menu_ios": 61179,
"pageless": 62729,
"pages": 59385,
"pageview": 59552,
@ -2482,10 +2643,15 @@
"panorama_vertical": 58382,
"panorama_wide_angle": 58383,
"paragliding": 58639,
"parent_child_dining": 61997,
"park": 60003,
"parking_meter": 62090,
"parking_sign": 62089,
"parking_valet": 62088,
"partly_cloudy_day": 61810,
"partly_cloudy_night": 61812,
"partner_exchange": 63481,
"partner_heart": 61230,
"partner_reports": 61359,
"party_mode": 59386,
"passkey": 63615,
@ -2500,6 +2666,8 @@
"pause_circle_outline": 57762,
"pause_presentation": 57578,
"payment": 59553,
"payment_arrow_down": 62144,
"payment_card": 62113,
"payments": 61283,
"pedal_bike": 60201,
"pediatrics": 57629,
@ -2515,12 +2683,13 @@
"people_alt": 59937,
"people_outline": 59937,
"percent": 60248,
"percent_discount": 62020,
"performance_max": 58650,
"pergola": 57859,
"perm_camera_mic": 59554,
"perm_contact_calendar": 59555,
"perm_data_setting": 59556,
"perm_device_information": 59557,
"perm_device_information": 62172,
"perm_identity": 61651,
"perm_media": 59559,
"perm_phone_msg": 59560,
@ -2540,6 +2709,7 @@
"person_check": 62821,
"person_edit": 62714,
"person_filled": 61651,
"person_heart": 62096,
"person_off": 58640,
"person_outline": 61651,
"person_pin": 58714,
@ -2562,24 +2732,24 @@
"phishing": 60119,
"phone": 61652,
"phone_alt": 61652,
"phone_android": 58148,
"phone_android": 62171,
"phone_bluetooth_speaker": 58907,
"phone_callback": 58953,
"phone_disabled": 59852,
"phone_enabled": 59853,
"phone_forwarded": 58908,
"phone_in_talk": 58909,
"phone_iphone": 58149,
"phone_iphone": 62170,
"phone_locked": 58910,
"phone_missed": 58911,
"phone_paused": 58912,
"phonelink": 58150,
"phonelink_erase": 57563,
"phonelink_lock": 57564,
"phonelink_off": 58151,
"phonelink_ring": 57565,
"phonelink_erase": 62186,
"phonelink_lock": 62142,
"phonelink_off": 63397,
"phonelink_ring": 62184,
"phonelink_ring_off": 63402,
"phonelink_setup": 61249,
"phonelink_setup": 62169,
"photo": 58418,
"photo_album": 58385,
"photo_auto_merge": 62768,
@ -2597,6 +2767,7 @@
"physical_therapy": 57630,
"piano": 58657,
"piano_off": 58656,
"pickleball": 62118,
"picture_as_pdf": 58389,
"picture_in_picture": 59562,
"picture_in_picture_alt": 59665,
@ -2627,6 +2798,7 @@
"place": 61915,
"place_item": 61936,
"plagiarism": 59994,
"plane_contrails": 62124,
"planet": 62343,
"planner_banner_ad_pt": 59026,
"planner_review": 59028,
@ -2638,6 +2810,8 @@
"play_music": 59118,
"play_pause": 61751,
"play_shapes": 63484,
"playground": 62094,
"playground_2": 62095,
"playing_cards": 62940,
"playlist_add": 57403,
"playlist_add_check": 57445,
@ -2819,6 +2993,7 @@
"request_page": 61996,
"request_quote": 61878,
"reset_brightness": 62594,
"reset_exposure": 62054,
"reset_focus": 62593,
"reset_image": 63524,
"reset_iso": 62592,
@ -2831,6 +3006,7 @@
"resize": 63239,
"respiratory_rate": 57639,
"responsive_layout": 59866,
"rest_area": 61994,
"restart_alt": 61523,
"restaurant": 58732,
"restaurant_menu": 58721,
@ -2914,11 +3090,11 @@
"scooter": 62577,
"score": 57961,
"scoreboard": 60368,
"screen_lock_landscape": 57790,
"screen_lock_portrait": 57791,
"screen_lock_rotation": 57792,
"screen_lock_landscape": 62168,
"screen_lock_portrait": 62142,
"screen_lock_rotation": 62166,
"screen_record": 63097,
"screen_rotation": 57793,
"screen_rotation": 62165,
"screen_rotation_alt": 60398,
"screen_rotation_up": 63096,
"screen_search_desktop": 61296,
@ -2942,6 +3118,7 @@
"search_activity": 62437,
"search_check": 63488,
"search_check_2": 62569,
"search_gear": 61178,
"search_hands_free": 59030,
"search_insights": 62652,
"search_off": 60022,
@ -2953,9 +3130,9 @@
"seat_vent_right": 62252,
"security": 58154,
"security_key": 62723,
"security_update": 61554,
"security_update": 62157,
"security_update_good": 61555,
"security_update_warning": 61556,
"security_update_warning": 62163,
"segment": 59723,
"select": 63309,
"select_all": 57698,
@ -2971,7 +3148,7 @@
"send_and_archive": 59916,
"send_money": 59575,
"send_time_extension": 60123,
"send_to_mobile": 61532,
"send_to_mobile": 62162,
"sensor_door": 61877,
"sensor_occupied": 60432,
"sensor_window": 61876,
@ -3006,7 +3183,7 @@
"settings_backup_restore": 59578,
"settings_bluetooth": 59579,
"settings_brightness": 59581,
"settings_cell": 59580,
"settings_cell": 62161,
"settings_cinematic_blur": 63012,
"settings_ethernet": 59582,
"settings_heart": 62754,
@ -3023,6 +3200,7 @@
"settings_photo_camera": 63540,
"settings_power": 59590,
"settings_remote": 59591,
"settings_seating": 61229,
"settings_slow_motion": 63011,
"settings_suggest": 61534,
"settings_system_daydream": 57795,
@ -3043,6 +3221,7 @@
"share_off": 63179,
"share_reviews": 63652,
"share_windows": 62995,
"shaved_ice": 61989,
"sheets_rtl": 63523,
"shelf_auto_hide": 63235,
"shelf_position": 63234,
@ -3053,6 +3232,7 @@
"shield_moon": 60073,
"shield_person": 63056,
"shield_question": 62761,
"shield_toggle": 62125,
"shield_watch": 62223,
"shield_with_heart": 59279,
"shield_with_house": 59277,
@ -3082,6 +3262,7 @@
"sick": 61984,
"side_navigation": 59874,
"sign_language": 60389,
"sign_language_2": 62040,
"signal_cellular_0_bar": 61608,
"signal_cellular_1_bar": 61609,
"signal_cellular_2_bar": 61610,
@ -3141,9 +3322,9 @@
"smart_card_reader_off": 62630,
"smart_display": 61546,
"smart_outlet": 59460,
"smart_screen": 61547,
"smart_screen": 62160,
"smart_toy": 61548,
"smartphone": 58156,
"smartphone": 59322,
"smartphone_camera": 62542,
"smb_share": 63307,
"smoke_free": 60234,
@ -3158,9 +3339,11 @@
"snowmobile": 58627,
"snowshoeing": 58644,
"soap": 61874,
"soba": 61238,
"social_distance": 57803,
"social_leaderboard": 63136,
"solar_power": 60431,
"solo_dining": 61237,
"sort": 57700,
"sort_by_alpha": 57427,
"sos": 60407,
@ -3284,10 +3467,10 @@
"stat_minus_1": 59035,
"stat_minus_2": 59036,
"stat_minus_3": 59037,
"stay_current_landscape": 57555,
"stay_current_portrait": 57556,
"stay_primary_landscape": 57557,
"stay_primary_portrait": 57558,
"stay_current_landscape": 60734,
"stay_current_portrait": 59322,
"stay_primary_landscape": 60734,
"stay_primary_portrait": 62163,
"steering_wheel_heat": 62251,
"step": 63230,
"step_into": 63233,
@ -3341,6 +3524,7 @@
"subtitles_gear": 62293,
"subtitles_off": 61298,
"subway": 58735,
"subway_walk": 62087,
"summarize": 61553,
"sunny": 59418,
"sunny_snowing": 59417,
@ -3396,11 +3580,12 @@
"sync_lock": 60142,
"sync_problem": 58921,
"sync_saved_locally": 63520,
"sync_saved_locally_off": 62052,
"syringe": 57651,
"system_security_update": 61554,
"system_security_update": 62157,
"system_security_update_good": 61555,
"system_security_update_warning": 61556,
"system_update": 61554,
"system_security_update_warning": 62163,
"system_update": 62157,
"system_update_alt": 59607,
"tab": 59608,
"tab_close": 63301,
@ -3422,9 +3607,11 @@
"table_edit": 62406,
"table_eye": 62566,
"table_lamp": 57842,
"table_large": 62105,
"table_restaurant": 60102,
"table_rows": 61697,
"table_rows_narrow": 63295,
"table_sign": 61228,
"table_view": 61886,
"tablet": 58159,
"tablet_android": 58160,
@ -3435,13 +3622,15 @@
"tag": 59887,
"tag_faces": 59938,
"takeout_dining": 60020,
"takeout_dining_2": 61236,
"tamper_detection_off": 59438,
"tamper_detection_on": 63688,
"tap_and_play": 58923,
"tap_and_play": 62156,
"tapas": 61929,
"target": 59161,
"task": 61557,
"task_alt": 58086,
"tatami_seat": 61235,
"taunt": 63135,
"taxi_alert": 61300,
"team_dashboard": 57363,
@ -3508,6 +3697,7 @@
"thumb_up_off": 62839,
"thumb_up_off_alt": 62839,
"thumbnail_bar": 63284,
"thumbs_up_double": 61180,
"thumbs_up_down": 59613,
"thunderstorm": 60379,
"tibia": 63643,
@ -3520,9 +3710,11 @@
"timelapse": 58402,
"timeline": 59682,
"timer": 58405,
"timer_1": 62127,
"timer_10": 58403,
"timer_10_alt_1": 61375,
"timer_10_select": 61562,
"timer_2": 62126,
"timer_3": 58404,
"timer_3_alt_1": 61376,
"timer_3_select": 61563,
@ -3545,6 +3737,7 @@
"token": 59941,
"toll": 59616,
"tonality": 58407,
"tonality_2": 62132,
"toolbar": 59895,
"tools_flat_head": 63691,
"tools_installation_kit": 58027,
@ -3594,6 +3787,7 @@
"transition_push": 62731,
"transition_slide": 62730,
"translate": 59618,
"translate_indic": 62051,
"transportation": 57885,
"travel": 61331,
"travel_explore": 58075,
@ -3638,6 +3832,7 @@
"type_specimen": 63728,
"u_turn_left": 60321,
"u_turn_right": 60322,
"udon": 61234,
"ulna_radius": 63645,
"ulna_radius_alt": 63646,
"umbrella": 61869,
@ -3694,7 +3889,7 @@
"vertical_shades": 60430,
"vertical_shades_closed": 60429,
"vertical_split": 59721,
"vibration": 58925,
"vibration": 62155,
"video_call": 57456,
"video_camera_back": 61567,
"video_camera_back_add": 62476,
@ -3739,6 +3934,7 @@
"view_timeline": 60293,
"view_week": 59635,
"vignette": 58421,
"vignette_2": 62131,
"villa": 58758,
"visibility": 59636,
"visibility_lock": 63059,
@ -3781,7 +3977,9 @@
"warning_amber": 61571,
"warning_off": 63405,
"wash": 61873,
"washoku": 62080,
"watch": 58164,
"watch_arrow": 62154,
"watch_button_press": 63146,
"watch_check": 62568,
"watch_later": 61398,
@ -3868,6 +4066,7 @@
"window_closed": 59262,
"window_open": 59276,
"window_sensor": 58043,
"windshield_defrost_auto": 62024,
"windshield_defrost_front": 62250,
"windshield_defrost_rear": 62249,
"windshield_heat_front": 62248,
@ -3889,7 +4088,9 @@
"wrist": 63132,
"wrong_location": 61304,
"wysiwyg": 61891,
"yakitori": 61233,
"yard": 61577,
"yoshoku": 62079,
"your_trips": 60203,
"youtube_activity": 63578,
"youtube_searched_for": 59642,

View file

@ -5,32 +5,12 @@ CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
def get_font_filepath(
font_name: Optional[str] = "MaterialSymbolsOutlined-Regular"
font_name: Optional[str] = "MaterialSymbolsOutlined"
) -> str:
return os.path.join(CURRENT_DIR, f"{font_name}.ttf")
def get_mapping_filepath(
font_name: Optional[str] = "MaterialSymbolsOutlined-Regular"
font_name: Optional[str] = "MaterialSymbolsOutlined"
) -> str:
return os.path.join(CURRENT_DIR, f"{font_name}.json")
def regenerate_mapping():
"""Regenerate the MaterialSymbolsOutlined.json file, assuming
MaterialSymbolsOutlined.codepoints and the TrueType font file have been
updated to support the new symbols.
"""
import json
jfile = get_mapping_filepath()
cpfile = jfile.replace(".json", ".codepoints")
with open(cpfile, "r") as cpf:
codepoints = cpf.read()
mapping = {}
for cp in codepoints.splitlines():
name, code = cp.split()
mapping[name] = int(f"0x{code}", 16)
with open(jfile, "w") as jf:
json.dump(mapping, jf, indent=4)

View file

@ -1,3 +1,3 @@
# -*- coding: utf-8 -*-
"""Package declaring AYON addon 'core' version."""
__version__ = "1.6.1+dev"
__version__ = "1.6.4+dev"

View file

@ -15,8 +15,7 @@ qtawesome = "0.7.3"
[ayon.runtimeDependencies]
aiohttp-middlewares = "^2.0.0"
Click = "^8"
OpenTimelineIO = "0.17.0"
otio-burnins-adapter = "1.0.0"
OpenTimelineIO = "0.16.0"
opencolorio = "^2.3.2,<2.4.0"
Pillow = "9.5.0"
websocket-client = ">=0.40.0,<2"

View file

@ -1,6 +1,6 @@
name = "core"
title = "Core"
version = "1.6.1+dev"
version = "1.6.4+dev"
client_dir = "ayon_core"

View file

@ -5,7 +5,7 @@
[tool.poetry]
name = "ayon-core"
version = "1.6.1+dev"
version = "1.6.4+dev"
description = ""
authors = ["Ynput Team <team@ynput.io>"]
readme = "README.md"