diff --git a/client/ayon_core/tools/publisher/models/publish.py b/client/ayon_core/tools/publisher/models/publish.py index da7b64ceae..ef207bfb79 100644 --- a/client/ayon_core/tools/publisher/models/publish.py +++ b/client/ayon_core/tools/publisher/models/publish.py @@ -4,7 +4,7 @@ import traceback import collections from functools import partial -from typing import Optional, Dict, List, Union, Any, Iterable, Literal +from typing import Optional, Dict, List, Union, Any, Iterable import arrow import pyblish.plugin @@ -22,15 +22,6 @@ # Define constant for plugin orders offset PLUGIN_ORDER_OFFSET = 0.5 -ActionFilterType = Literal[ - "all", - "notProcessed", - "processed", - "failed", - "warning", - "failedOrWarning", - "succeeded" -] class PublishReportMaker: @@ -318,8 +309,10 @@ class PublishPluginActionItem: action_id (str): Action id. plugin_id (str): Plugin id. active (bool): Action is active. - on_filter (ActionFilterType): Actions have 'on' attribute which define - when can be action triggered (e.g. 'all', 'failed', ...). + on_filter (Literal["all", "notProcessed", "processed", "failed", + "warning", "failedOrWarning", "succeeded"]): Actions have 'on' + attribute which define when can be action triggered + (e.g. 'all', 'failed', ...). label (str): Action's label. icon (Optional[str]) Action's icon. """ @@ -329,14 +322,14 @@ def __init__( action_id: str, plugin_id: str, active: bool, - on_filter: ActionFilterType, + on_filter: str, label: str, icon: Optional[str], ): self.action_id: str = action_id self.plugin_id: str = plugin_id self.active: bool = active - self.on_filter: ActionFilterType = on_filter + self.on_filter: str = on_filter self.label: str = label self.icon: Optional[str] = icon diff --git a/server_addon/applications/client/ayon_applications/__init__.py b/server_addon/applications/client/ayon_applications/__init__.py deleted file mode 100644 index 99d201e49b..0000000000 --- a/server_addon/applications/client/ayon_applications/__init__.py +++ /dev/null @@ -1,62 +0,0 @@ -from .version import __version__ -from .constants import ( - APPLICATIONS_ADDON_ROOT, - DEFAULT_ENV_SUBGROUP, - PLATFORM_NAMES, -) -from .exceptions import ( - ApplicationNotFound, - ApplicationExecutableNotFound, - ApplicationLaunchFailed, - MissingRequiredKey, -) -from .defs import ( - LaunchTypes, - ApplicationExecutable, - UndefinedApplicationExecutable, - ApplicationGroup, - Application, - EnvironmentToolGroup, - EnvironmentTool, -) -from .hooks import ( - LaunchHook, - PreLaunchHook, - PostLaunchHook, -) -from .manager import ( - ApplicationManager, - ApplicationLaunchContext, -) -from .addon import ApplicationsAddon - - -__all__ = ( - "__version__", - - "APPLICATIONS_ADDON_ROOT", - "DEFAULT_ENV_SUBGROUP", - "PLATFORM_NAMES", - - "ApplicationNotFound", - "ApplicationExecutableNotFound", - "ApplicationLaunchFailed", - "MissingRequiredKey", - - "LaunchTypes", - "ApplicationExecutable", - "UndefinedApplicationExecutable", - "ApplicationGroup", - "Application", - "EnvironmentToolGroup", - "EnvironmentTool", - - "LaunchHook", - "PreLaunchHook", - "PostLaunchHook", - - "ApplicationManager", - "ApplicationLaunchContext", - - "ApplicationsAddon", -) diff --git a/server_addon/applications/client/ayon_applications/action.py b/server_addon/applications/client/ayon_applications/action.py deleted file mode 100644 index e5942c7008..0000000000 --- a/server_addon/applications/client/ayon_applications/action.py +++ /dev/null @@ -1,147 +0,0 @@ -import copy - -import ayon_api - -from ayon_core import resources -from ayon_core.lib import Logger, NestedCacheItem -from ayon_core.settings import get_studio_settings, get_project_settings -from ayon_core.pipeline.actions import LauncherAction - -from .exceptions import ( - ApplicationExecutableNotFound, - ApplicationLaunchFailed, -) - - -class ApplicationAction(LauncherAction): - """Action to launch an application. - - Application action based on 'ApplicationManager' system. - - Handling of applications in launcher is not ideal and should be completely - redone from scratch. This is just a temporary solution to keep backwards - compatibility with AYON launcher. - - Todos: - Move handling of errors to frontend. - """ - - # Application object - application = None - # Action attributes - name = None - label = None - label_variant = None - group = None - icon = None - color = None - order = 0 - data = {} - project_settings = {} - project_entities = {} - - _log = None - - # --- For compatibility for combinations of new and old ayon-core --- - project_settings_cache = NestedCacheItem( - levels=1, default_factory=dict, lifetime=20 - ) - project_entities_cache = NestedCacheItem( - levels=1, default_factory=dict, lifetime=20 - ) - - @classmethod - def _app_get_project_settings(cls, selection): - project_name = selection.project_name - if project_name in ApplicationAction.project_settings: - return ApplicationAction.project_settings[project_name] - - if hasattr(selection, "get_project_settings"): - return selection.get_project_settings() - - cache = ApplicationAction.project_settings_cache[project_name] - if not cache.is_valid: - if project_name: - settings = get_project_settings(project_name) - else: - settings = get_studio_settings() - cache.update_data(settings) - return copy.deepcopy(cache.get_data()) - - @classmethod - def _app_get_project_entity(cls, selection): - project_name = selection.project_name - if project_name in ApplicationAction.project_entities: - return ApplicationAction.project_entities[project_name] - - if hasattr(selection, "get_project_settings"): - return selection.get_project_entity() - - cache = ApplicationAction.project_entities_cache[project_name] - if not cache.is_valid: - project_entity = None - if project_name: - project_entity = ayon_api.get_project(project_name) - cache.update_data(project_entity) - return copy.deepcopy(cache.get_data()) - - @property - def log(self): - if self._log is None: - self._log = Logger.get_logger(self.__class__.__name__) - return self._log - - def is_compatible(self, selection): - if not selection.is_task_selected: - return False - - project_entity = self._app_get_project_entity(selection) - apps = project_entity["attrib"].get("applications") - if not apps or self.application.full_name not in apps: - return False - - project_settings = self._app_get_project_settings(selection) - only_available = project_settings["applications"]["only_available"] - if only_available and not self.application.find_executable(): - return False - return True - - def _show_message_box(self, title, message, details=None): - from qtpy import QtWidgets, QtGui - from ayon_core import style - - dialog = QtWidgets.QMessageBox() - icon = QtGui.QIcon(resources.get_ayon_icon_filepath()) - dialog.setWindowIcon(icon) - dialog.setStyleSheet(style.load_stylesheet()) - dialog.setWindowTitle(title) - dialog.setText(message) - if details: - dialog.setDetailedText(details) - dialog.exec_() - - def process(self, selection, **kwargs): - """Process the full Application action""" - try: - self.application.launch( - project_name=selection.project_name, - folder_path=selection.folder_path, - task_name=selection.task_name, - **self.data - ) - - except ApplicationExecutableNotFound as exc: - details = exc.details - msg = exc.msg - log_msg = str(msg) - if details: - log_msg += "\n" + details - self.log.warning(log_msg) - self._show_message_box( - "Application executable not found", msg, details - ) - - except ApplicationLaunchFailed as exc: - msg = str(exc) - self.log.warning(msg, exc_info=True) - self._show_message_box("Application launch failed", msg) diff --git a/server_addon/applications/client/ayon_applications/addon.py b/server_addon/applications/client/ayon_applications/addon.py deleted file mode 100644 index 26374ad0cd..0000000000 --- a/server_addon/applications/client/ayon_applications/addon.py +++ /dev/null @@ -1,321 +0,0 @@ -import os -import json - -import ayon_api - -from ayon_core.addon import AYONAddon, IPluginPaths, click_wrap - -from .version import __version__ -from .constants import APPLICATIONS_ADDON_ROOT -from .defs import LaunchTypes -from .manager import ApplicationManager - - -class ApplicationsAddon(AYONAddon, IPluginPaths): - name = "applications" - version = __version__ - - def initialize(self, settings): - # TODO remove when addon is removed from ayon-core - self.enabled = self.name in settings - - def get_app_environments_for_context( - self, - project_name, - folder_path, - task_name, - full_app_name, - env_group=None, - launch_type=None, - env=None, - ): - """Calculate environment variables for launch context. - - Args: - project_name (str): Project name. - folder_path (str): Folder path. - task_name (str): Task name. - full_app_name (str): Full application name. - env_group (Optional[str]): Environment group. - launch_type (Optional[str]): Launch type. - env (Optional[dict[str, str]]): Environment variables to update. - - Returns: - dict[str, str]: Environment variables for context. - - """ - from ayon_applications.utils import get_app_environments_for_context - - if not full_app_name: - return {} - - return get_app_environments_for_context( - project_name, - folder_path, - task_name, - full_app_name, - env_group=env_group, - launch_type=launch_type, - env=env, - addons_manager=self.manager - ) - - def get_farm_publish_environment_variables( - self, - project_name, - folder_path, - task_name, - full_app_name=None, - env_group=None, - ): - """Calculate environment variables for farm publish. - - Args: - project_name (str): Project name. - folder_path (str): Folder path. - task_name (str): Task name. - env_group (Optional[str]): Environment group. - full_app_name (Optional[str]): Full application name. Value from - environment variable 'AYON_APP_NAME' is used if 'None' is - passed. - - Returns: - dict[str, str]: Environment variables for farm publish. - - """ - if full_app_name is None: - full_app_name = os.getenv("AYON_APP_NAME") - - return self.get_app_environments_for_context( - project_name, - folder_path, - task_name, - full_app_name, - env_group=env_group, - launch_type=LaunchTypes.farm_publish - ) - - def get_applications_manager(self, settings=None): - """Get applications manager. - - Args: - settings (Optional[dict]): Studio/project settings. - - Returns: - ApplicationManager: Applications manager. - - """ - return ApplicationManager(settings) - - def get_plugin_paths(self): - return { - "publish": [ - os.path.join(APPLICATIONS_ADDON_ROOT, "plugins", "publish") - ] - } - - def get_app_icon_path(self, icon_filename): - """Get icon path. - - Args: - icon_filename (str): Icon filename. - - Returns: - Union[str, None]: Icon path or None if not found. - - """ - if not icon_filename: - return None - icon_name = os.path.basename(icon_filename) - path = os.path.join(APPLICATIONS_ADDON_ROOT, "icons", icon_name) - if os.path.exists(path): - return path - return None - - def get_app_icon_url(self, icon_filename, server=False): - """Get icon path. - - Method does not validate if icon filename exist on server. - - Args: - icon_filename (str): Icon name. - server (Optional[bool]): Return url to AYON server. - - Returns: - Union[str, None]: Icon path or None is server url is not - available. - - """ - if not icon_filename: - return None - icon_name = os.path.basename(icon_filename) - if server: - base_url = ayon_api.get_base_url() - return ( - f"{base_url}/addons/{self.name}/{self.version}" - f"/public/icons/{icon_name}" - ) - server_url = os.getenv("AYON_WEBSERVER_URL") - if not server_url: - return None - return "/".join([ - server_url, "addons", self.name, self.version, "icons", icon_name - ]) - - def get_applications_action_classes(self): - """Get application action classes for launcher tool. - - This method should be used only by launcher tool. Please do not use it - in other places as its implementation is not optimal, and might - change or be removed. - - Returns: - list[ApplicationAction]: List of application action classes. - - """ - from .action import ApplicationAction - - actions = [] - - manager = self.get_applications_manager() - for full_name, application in manager.applications.items(): - if not application.enabled: - continue - - icon = self.get_app_icon_path(application.icon) - - action = type( - "app_{}".format(full_name), - (ApplicationAction,), - { - "identifier": "application.{}".format(full_name), - "application": application, - "name": application.name, - "label": application.group.label, - "label_variant": application.label, - "group": None, - "icon": icon, - "color": getattr(application, "color", None), - "order": getattr(application, "order", None) or 0, - "data": {} - } - ) - actions.append(action) - return actions - - def launch_application( - self, app_name, project_name, folder_path, task_name - ): - """Launch application. - - Args: - app_name (str): Full application name e.g. 'maya/2024'. - project_name (str): Project name. - folder_path (str): Folder path. - task_name (str): Task name. - - """ - app_manager = self.get_applications_manager() - return app_manager.launch( - app_name, - project_name=project_name, - folder_path=folder_path, - task_name=task_name, - ) - - def webserver_initialization(self, manager): - """Initialize webserver. - - Args: - manager (WebServerManager): Webserver manager. - - """ - static_prefix = f"/addons/{self.name}/{self.version}/icons" - manager.add_static( - static_prefix, os.path.join(APPLICATIONS_ADDON_ROOT, "icons") - ) - - # --- CLI --- - def cli(self, addon_click_group): - main_group = click_wrap.group( - self._cli_main, name=self.name, help="Applications addon" - ) - ( - main_group.command( - self._cli_extract_environments, - name="extractenvironments", - help=( - "Extract environment variables for context into json file" - ) - ) - .argument("output_json_path") - .option("--project", help="Project name", default=None) - .option("--folder", help="Folder path", default=None) - .option("--task", help="Task name", default=None) - .option("--app", help="Application name", default=None) - .option( - "--envgroup", - help="Environment group (e.g. \"farm\")", - default=None - ) - ) - ( - main_group.command( - self._cli_launch_applications, - name="launch", - help="Launch application" - ) - .option("--app", required=True, help="Application name") - .option("--project", required=True, help="Project name") - .option("--folder", required=True, help="Folder path") - .option("--task", required=True, help="Task name") - ) - # Convert main command to click object and add it to parent group - addon_click_group.add_command( - main_group.to_click_obj() - ) - - def _cli_main(self): - pass - - def _cli_extract_environments( - self, output_json_path, project, folder, task, app, envgroup - ): - """Produces json file with environment based on project and app. - - Called by farm integration to propagate environment into farm jobs. - - Args: - output_json_path (str): Output json file path. - project (str): Project name. - folder (str): Folder path. - task (str): Task name. - app (str): Full application name e.g. 'maya/2024'. - envgroup (str): Environment group. - - """ - if all((project, folder, task, app)): - env = self.get_farm_publish_environment_variables( - project, folder, task, app, env_group=envgroup, - ) - else: - env = os.environ.copy() - - output_dir = os.path.dirname(output_json_path) - if not os.path.exists(output_dir): - os.makedirs(output_dir) - - with open(output_json_path, "w") as file_stream: - json.dump(env, file_stream, indent=4) - - def _cli_launch_applications(self, project, folder, task, app): - """Launch application. - - Args: - project (str): Project name. - folder (str): Folder path. - task (str): Task name. - app (str): Full application name e.g. 'maya/2024'. - - """ - self.launch_application(app, project, folder, task) diff --git a/server_addon/applications/client/ayon_applications/constants.py b/server_addon/applications/client/ayon_applications/constants.py deleted file mode 100644 index 92c8f4f254..0000000000 --- a/server_addon/applications/client/ayon_applications/constants.py +++ /dev/null @@ -1,6 +0,0 @@ -import os - -APPLICATIONS_ADDON_ROOT = os.path.dirname(os.path.abspath(__file__)) - -PLATFORM_NAMES = {"windows", "linux", "darwin"} -DEFAULT_ENV_SUBGROUP = "standard" diff --git a/server_addon/applications/client/ayon_applications/defs.py b/server_addon/applications/client/ayon_applications/defs.py deleted file mode 100644 index 5cc36041a1..0000000000 --- a/server_addon/applications/client/ayon_applications/defs.py +++ /dev/null @@ -1,404 +0,0 @@ -import os -import platform -import json -import copy - -from ayon_core.lib import find_executable - - -class LaunchTypes: - """Launch types are filters for pre/post-launch hooks. - - Please use these variables in case they'll change values. - """ - - # Local launch - application is launched on local machine - local = "local" - # Farm render job - application is on farm - farm_render = "farm-render" - # Farm publish job - integration post-render job - farm_publish = "farm-publish" - # Remote launch - application is launched on remote machine from which - # can be started publishing - remote = "remote" - # Automated launch - application is launched with automated publishing - automated = "automated" - - -class ApplicationExecutable: - """Representation of executable loaded from settings.""" - - def __init__(self, executable): - # Try to format executable with environments - try: - executable = executable.format(**os.environ) - except Exception: - pass - - # On MacOS check if exists path to executable when ends with `.app` - # - it is common that path will lead to "/Applications/Blender" but - # real path is "/Applications/Blender.app" - if platform.system().lower() == "darwin": - executable = self.macos_executable_prep(executable) - - self.executable_path = executable - - def __str__(self): - return self.executable_path - - def __repr__(self): - return "<{}> {}".format(self.__class__.__name__, self.executable_path) - - @staticmethod - def macos_executable_prep(executable): - """Try to find full path to executable file. - - Real executable is stored in '*.app/Contents/MacOS/'. - - Having path to '*.app' gives ability to read it's plist info and - use "CFBundleExecutable" key from plist to know what is "executable." - - Plist is stored in '*.app/Contents/Info.plist'. - - This is because some '*.app' directories don't have same permissions - as real executable. - """ - # Try to find if there is `.app` file - if not os.path.exists(executable): - _executable = executable + ".app" - if os.path.exists(_executable): - executable = _executable - - # Try to find real executable if executable has `Contents` subfolder - contents_dir = os.path.join(executable, "Contents") - if os.path.exists(contents_dir): - executable_filename = None - # Load plist file and check for bundle executable - plist_filepath = os.path.join(contents_dir, "Info.plist") - if os.path.exists(plist_filepath): - import plistlib - - if hasattr(plistlib, "load"): - with open(plist_filepath, "rb") as stream: - parsed_plist = plistlib.load(stream) - else: - parsed_plist = plistlib.readPlist(plist_filepath) - executable_filename = parsed_plist.get("CFBundleExecutable") - - if executable_filename: - executable = os.path.join( - contents_dir, "MacOS", executable_filename - ) - - return executable - - def as_args(self): - return [self.executable_path] - - def _realpath(self): - """Check if path is valid executable path.""" - # Check for executable in PATH - result = find_executable(self.executable_path) - if result is not None: - return result - - # This is not 100% validation but it is better than remove ability to - # launch .bat, .sh or extentionless files - if os.path.exists(self.executable_path): - return self.executable_path - return None - - def exists(self): - if not self.executable_path: - return False - return bool(self._realpath()) - - -class UndefinedApplicationExecutable(ApplicationExecutable): - """Some applications do not require executable path from settings. - - In that case this class is used to "fake" existing executable. - """ - def __init__(self): - pass - - def __str__(self): - return self.__class__.__name__ - - def __repr__(self): - return "<{}>".format(self.__class__.__name__) - - def as_args(self): - return [] - - def exists(self): - return True - - -class ApplicationGroup: - """Hold information about application group. - - Application group wraps different versions(variants) of application. - e.g. "maya" is group and "maya_2020" is variant. - - Group hold `host_name` which is implementation name used in AYON. Also - holds `enabled` if whole app group is enabled or `icon` for application - icon path in resources. - - Group has also `environment` which hold same environments for all variants. - - Args: - name (str): Groups' name. - data (dict): Group defying data loaded from settings. - manager (ApplicationManager): Manager that created the group. - """ - - def __init__(self, name, data, manager): - self.name = name - self.manager = manager - self._data = data - - self.enabled = data["enabled"] - self.label = data["label"] or None - self.icon = data["icon"] or None - env = {} - try: - env = json.loads(data["environment"]) - except Exception: - pass - self._environment = env - - host_name = data["host_name"] or None - self.is_host = host_name is not None - self.host_name = host_name - - settings_variants = data["variants"] - variants = {} - for variant_data in settings_variants: - app_variant = Application(variant_data, self) - variants[app_variant.name] = app_variant - - self.variants = variants - - def __repr__(self): - return "<{}> - {}".format(self.__class__.__name__, self.name) - - def __iter__(self): - for variant in self.variants.values(): - yield variant - - @property - def environment(self): - return copy.deepcopy(self._environment) - - -class Application: - """Hold information about application. - - Object by itself does nothing special. - - Args: - data (dict): Data for the version containing information about - executables, variant label or if is enabled. - Only required key is `executables`. - group (ApplicationGroup): App group object that created the application - and under which application belongs. - - """ - def __init__(self, data, group): - self._data = data - name = data["name"] - label = data["label"] or name - enabled = False - if group.enabled: - enabled = data.get("enabled", True) - - if group.label: - full_label = " ".join((group.label, label)) - else: - full_label = label - env = {} - try: - env = json.loads(data["environment"]) - except Exception: - pass - - arguments = data["arguments"] - if isinstance(arguments, dict): - arguments = arguments.get(platform.system().lower()) - - if not arguments: - arguments = [] - - _executables = data["executables"].get(platform.system().lower(), []) - executables = [ - ApplicationExecutable(executable) - for executable in _executables - ] - - self.group = group - - self.name = name - self.label = label - self.enabled = enabled - self.use_python_2 = data.get("use_python_2", False) - - self.full_name = "/".join((group.name, name)) - self.full_label = full_label - self.arguments = arguments - self.executables = executables - self._environment = env - - def __repr__(self): - return "<{}> - {}".format(self.__class__.__name__, self.full_name) - - @property - def environment(self): - return copy.deepcopy(self._environment) - - @property - def manager(self): - return self.group.manager - - @property - def host_name(self): - return self.group.host_name - - @property - def icon(self): - return self.group.icon - - @property - def is_host(self): - return self.group.is_host - - def find_executable(self): - """Try to find existing executable for application. - - Returns (str): Path to executable from `executables` or None if any - exists. - """ - for executable in self.executables: - if executable.exists(): - return executable - return None - - def launch(self, *args, **kwargs): - """Launch the application. - - For this purpose is used manager's launch method to keep logic at one - place. - - Arguments must match with manager's launch method. That's why *args - **kwargs are used. - - Returns: - subprocess.Popen: Return executed process as Popen object. - """ - return self.manager.launch(self.full_name, *args, **kwargs) - - -class EnvironmentToolGroup: - """Hold information about environment tool group. - - Environment tool group may hold different variants of same tool and set - environments that are same for all of them. - - e.g. "mtoa" may have different versions but all environments except one - are same. - - Args: - data (dict): Group information with variants. - manager (ApplicationManager): Manager that creates the group. - """ - - def __init__(self, data, manager): - name = data["name"] - label = data["label"] - - self.name = name - self.label = label - self._data = data - self.manager = manager - - environment = {} - try: - environment = json.loads(data["environment"]) - except Exception: - pass - self._environment = environment - - variants = data.get("variants") or [] - variants_by_name = {} - for variant_data in variants: - tool = EnvironmentTool(variant_data, self) - variants_by_name[tool.name] = tool - self.variants = variants_by_name - - def __repr__(self): - return "<{}> - {}".format(self.__class__.__name__, self.name) - - def __iter__(self): - for variant in self.variants.values(): - yield variant - - @property - def environment(self): - return copy.deepcopy(self._environment) - - -class EnvironmentTool: - """Hold information about application tool. - - Structure of tool information. - - Args: - variant_data (dict): Variant data with environments and - host and app variant filters. - group (EnvironmentToolGroup): Name of group which wraps tool. - """ - - def __init__(self, variant_data, group): - # Backwards compatibility 3.9.1 - 3.9.2 - # - 'variant_data' contained only environments but contain also host - # and application variant filters - name = variant_data["name"] - label = variant_data["label"] - host_names = variant_data["host_names"] - app_variants = variant_data["app_variants"] - - environment = {} - try: - environment = json.loads(variant_data["environment"]) - except Exception: - pass - - self.host_names = host_names - self.app_variants = app_variants - self.name = name - self.variant_label = label - self.label = " ".join((group.label, label)) - self.group = group - - self._environment = environment - self.full_name = "/".join((group.name, name)) - - def __repr__(self): - return "<{}> - {}".format(self.__class__.__name__, self.full_name) - - @property - def environment(self): - return copy.deepcopy(self._environment) - - def is_valid_for_app(self, app): - """Is tool valid for application. - - Args: - app (Application): Application for which are prepared environments. - """ - if self.app_variants and app.full_name not in self.app_variants: - return False - - if self.host_names and app.host_name not in self.host_names: - return False - return True diff --git a/server_addon/applications/client/ayon_applications/exceptions.py b/server_addon/applications/client/ayon_applications/exceptions.py deleted file mode 100644 index d5a48d3b6b..0000000000 --- a/server_addon/applications/client/ayon_applications/exceptions.py +++ /dev/null @@ -1,50 +0,0 @@ -class ApplicationNotFound(Exception): - """Application was not found in ApplicationManager by name.""" - - def __init__(self, app_name): - self.app_name = app_name - super(ApplicationNotFound, self).__init__( - "Application \"{}\" was not found.".format(app_name) - ) - - -class ApplicationExecutableNotFound(Exception): - """Defined executable paths are not available on the machine.""" - - def __init__(self, application): - self.application = application - details = None - if not application.executables: - msg = ( - "Executable paths for application \"{}\"({}) are not set." - ) - else: - msg = ( - "Defined executable paths for application \"{}\"({})" - " are not available on this machine." - ) - details = "Defined paths:" - for executable in application.executables: - details += "\n- " + executable.executable_path - - self.msg = msg.format(application.full_label, application.full_name) - self.details = details - - exc_mgs = str(self.msg) - if details: - # Is good idea to pass new line symbol to exception message? - exc_mgs += "\n" + details - self.exc_msg = exc_mgs - super(ApplicationExecutableNotFound, self).__init__(exc_mgs) - - -class ApplicationLaunchFailed(Exception): - """Application launch failed due to known reason. - - Message should be self explanatory as traceback won't be shown. - """ - pass - - -class MissingRequiredKey(KeyError): - pass diff --git a/server_addon/applications/client/ayon_applications/hooks.py b/server_addon/applications/client/ayon_applications/hooks.py deleted file mode 100644 index 6aa12a210a..0000000000 --- a/server_addon/applications/client/ayon_applications/hooks.py +++ /dev/null @@ -1,150 +0,0 @@ -import platform -from abc import ABCMeta, abstractmethod - -import six - -from ayon_core.lib import Logger - -from .defs import LaunchTypes - - -@six.add_metaclass(ABCMeta) -class LaunchHook: - """Abstract base class of launch hook.""" - # Order of prelaunch hook, will be executed as last if set to None. - order = None - # List of host implementations, skipped if empty. - hosts = set() - # Set of application groups - app_groups = set() - # Set of specific application names - app_names = set() - # Set of platform availability - platforms = set() - # Set of launch types for which is available - # - if empty then is available for all launch types - # - by default has 'local' which is most common reason for launc hooks - launch_types = {LaunchTypes.local} - - def __init__(self, launch_context): - """Constructor of launch hook. - - Always should be called - """ - self.log = Logger.get_logger(self.__class__.__name__) - - self.launch_context = launch_context - - is_valid = self.class_validation(launch_context) - if is_valid: - is_valid = self.validate() - - self.is_valid = is_valid - - @classmethod - def class_validation(cls, launch_context): - """Validation of class attributes by launch context. - - Args: - launch_context (ApplicationLaunchContext): Context of launching - application. - - Returns: - bool: Is launch hook valid for the context by class attributes. - """ - if cls.platforms: - low_platforms = tuple( - _platform.lower() - for _platform in cls.platforms - ) - if platform.system().lower() not in low_platforms: - return False - - if cls.hosts: - if launch_context.host_name not in cls.hosts: - return False - - if cls.app_groups: - if launch_context.app_group.name not in cls.app_groups: - return False - - if cls.app_names: - if launch_context.app_name not in cls.app_names: - return False - - if cls.launch_types: - if launch_context.launch_type not in cls.launch_types: - return False - - return True - - @property - def data(self): - return self.launch_context.data - - @property - def application(self): - return getattr(self.launch_context, "application", None) - - @property - def manager(self): - return getattr(self.application, "manager", None) - - @property - def host_name(self): - return getattr(self.application, "host_name", None) - - @property - def app_group(self): - return getattr(self.application, "group", None) - - @property - def app_name(self): - return getattr(self.application, "full_name", None) - - @property - def addons_manager(self): - return getattr(self.launch_context, "addons_manager", None) - - @property - def modules_manager(self): - """ - Deprecated: - Use 'addons_wrapper' instead. - """ - return self.addons_manager - - def validate(self): - """Optional validation of launch hook on initialization. - - Returns: - bool: Hook is valid (True) or invalid (False). - """ - # QUESTION Not sure if this method has any usable potential. - # - maybe result can be based on settings - return True - - @abstractmethod - def execute(self, *args, **kwargs): - """Abstract execute method where logic of hook is.""" - pass - - -class PreLaunchHook(LaunchHook): - """Abstract class of prelaunch hook. - - This launch hook will be processed before application is launched. - - If any exception will happen during processing the application won't be - launched. - """ - - -class PostLaunchHook(LaunchHook): - """Abstract class of postlaunch hook. - - This launch hook will be processed after application is launched. - - Nothing will happen if any exception will happen during processing. And - processing of other postlaunch hooks won't stop either. - """ diff --git a/server_addon/applications/client/ayon_applications/icons/3de4.png b/server_addon/applications/client/ayon_applications/icons/3de4.png deleted file mode 100644 index bd0fe40d37..0000000000 Binary files a/server_addon/applications/client/ayon_applications/icons/3de4.png and /dev/null differ diff --git a/server_addon/applications/client/ayon_applications/icons/3dsmax.png b/server_addon/applications/client/ayon_applications/icons/3dsmax.png deleted file mode 100644 index 9ebdf6099f..0000000000 Binary files a/server_addon/applications/client/ayon_applications/icons/3dsmax.png and /dev/null differ diff --git a/server_addon/applications/client/ayon_applications/icons/aftereffects.png b/server_addon/applications/client/ayon_applications/icons/aftereffects.png deleted file mode 100644 index 56754e2be2..0000000000 Binary files a/server_addon/applications/client/ayon_applications/icons/aftereffects.png and /dev/null differ diff --git a/server_addon/applications/client/ayon_applications/icons/blender.png b/server_addon/applications/client/ayon_applications/icons/blender.png deleted file mode 100644 index 6070a51fae..0000000000 Binary files a/server_addon/applications/client/ayon_applications/icons/blender.png and /dev/null differ diff --git a/server_addon/applications/client/ayon_applications/icons/celaction.png b/server_addon/applications/client/ayon_applications/icons/celaction.png deleted file mode 100644 index 86ac092365..0000000000 Binary files a/server_addon/applications/client/ayon_applications/icons/celaction.png and /dev/null differ diff --git a/server_addon/applications/client/ayon_applications/icons/flame.png b/server_addon/applications/client/ayon_applications/icons/flame.png deleted file mode 100644 index ba9b69e45f..0000000000 Binary files a/server_addon/applications/client/ayon_applications/icons/flame.png and /dev/null differ diff --git a/server_addon/applications/client/ayon_applications/icons/fusion.png b/server_addon/applications/client/ayon_applications/icons/fusion.png deleted file mode 100644 index 50541b0e4f..0000000000 Binary files a/server_addon/applications/client/ayon_applications/icons/fusion.png and /dev/null differ diff --git a/server_addon/applications/client/ayon_applications/icons/harmony.png b/server_addon/applications/client/ayon_applications/icons/harmony.png deleted file mode 100644 index f0f6c82c6e..0000000000 Binary files a/server_addon/applications/client/ayon_applications/icons/harmony.png and /dev/null differ diff --git a/server_addon/applications/client/ayon_applications/icons/hiero.png b/server_addon/applications/client/ayon_applications/icons/hiero.png deleted file mode 100644 index ba666c2fe0..0000000000 Binary files a/server_addon/applications/client/ayon_applications/icons/hiero.png and /dev/null differ diff --git a/server_addon/applications/client/ayon_applications/icons/houdini.png b/server_addon/applications/client/ayon_applications/icons/houdini.png deleted file mode 100644 index 11cfa46dce..0000000000 Binary files a/server_addon/applications/client/ayon_applications/icons/houdini.png and /dev/null differ diff --git a/server_addon/applications/client/ayon_applications/icons/maya.png b/server_addon/applications/client/ayon_applications/icons/maya.png deleted file mode 100644 index 95c605f50d..0000000000 Binary files a/server_addon/applications/client/ayon_applications/icons/maya.png and /dev/null differ diff --git a/server_addon/applications/client/ayon_applications/icons/nuke.png b/server_addon/applications/client/ayon_applications/icons/nuke.png deleted file mode 100644 index e734b4984e..0000000000 Binary files a/server_addon/applications/client/ayon_applications/icons/nuke.png and /dev/null differ diff --git a/server_addon/applications/client/ayon_applications/icons/nukestudio.png b/server_addon/applications/client/ayon_applications/icons/nukestudio.png deleted file mode 100644 index 601d4a591d..0000000000 Binary files a/server_addon/applications/client/ayon_applications/icons/nukestudio.png and /dev/null differ diff --git a/server_addon/applications/client/ayon_applications/icons/nukex.png b/server_addon/applications/client/ayon_applications/icons/nukex.png deleted file mode 100644 index 980f150124..0000000000 Binary files a/server_addon/applications/client/ayon_applications/icons/nukex.png and /dev/null differ diff --git a/server_addon/applications/client/ayon_applications/icons/openrv.png b/server_addon/applications/client/ayon_applications/icons/openrv.png deleted file mode 100644 index 30077b38e8..0000000000 Binary files a/server_addon/applications/client/ayon_applications/icons/openrv.png and /dev/null differ diff --git a/server_addon/applications/client/ayon_applications/icons/photoshop.png b/server_addon/applications/client/ayon_applications/icons/photoshop.png deleted file mode 100644 index c7e9d14711..0000000000 Binary files a/server_addon/applications/client/ayon_applications/icons/photoshop.png and /dev/null differ diff --git a/server_addon/applications/client/ayon_applications/icons/premiere.png b/server_addon/applications/client/ayon_applications/icons/premiere.png deleted file mode 100644 index eb5b3d1ba2..0000000000 Binary files a/server_addon/applications/client/ayon_applications/icons/premiere.png and /dev/null differ diff --git a/server_addon/applications/client/ayon_applications/icons/python.png b/server_addon/applications/client/ayon_applications/icons/python.png deleted file mode 100644 index b3b5b2220a..0000000000 Binary files a/server_addon/applications/client/ayon_applications/icons/python.png and /dev/null differ diff --git a/server_addon/applications/client/ayon_applications/icons/resolve.png b/server_addon/applications/client/ayon_applications/icons/resolve.png deleted file mode 100644 index d084288d90..0000000000 Binary files a/server_addon/applications/client/ayon_applications/icons/resolve.png and /dev/null differ diff --git a/server_addon/applications/client/ayon_applications/icons/shotgrid.png b/server_addon/applications/client/ayon_applications/icons/shotgrid.png deleted file mode 100644 index 6d0cc047f9..0000000000 Binary files a/server_addon/applications/client/ayon_applications/icons/shotgrid.png and /dev/null differ diff --git a/server_addon/applications/client/ayon_applications/icons/storyboardpro.png b/server_addon/applications/client/ayon_applications/icons/storyboardpro.png deleted file mode 100644 index ac9526f163..0000000000 Binary files a/server_addon/applications/client/ayon_applications/icons/storyboardpro.png and /dev/null differ diff --git a/server_addon/applications/client/ayon_applications/icons/substancepainter.png b/server_addon/applications/client/ayon_applications/icons/substancepainter.png deleted file mode 100644 index dc46f25d74..0000000000 Binary files a/server_addon/applications/client/ayon_applications/icons/substancepainter.png and /dev/null differ diff --git a/server_addon/applications/client/ayon_applications/icons/tvpaint.png b/server_addon/applications/client/ayon_applications/icons/tvpaint.png deleted file mode 100644 index adad6b2015..0000000000 Binary files a/server_addon/applications/client/ayon_applications/icons/tvpaint.png and /dev/null differ diff --git a/server_addon/applications/client/ayon_applications/icons/ue4.png b/server_addon/applications/client/ayon_applications/icons/ue4.png deleted file mode 100644 index 39201de664..0000000000 Binary files a/server_addon/applications/client/ayon_applications/icons/ue4.png and /dev/null differ diff --git a/server_addon/applications/client/ayon_applications/icons/wrap.png b/server_addon/applications/client/ayon_applications/icons/wrap.png deleted file mode 100644 index 34ae1d68ed..0000000000 Binary files a/server_addon/applications/client/ayon_applications/icons/wrap.png and /dev/null differ diff --git a/server_addon/applications/client/ayon_applications/icons/zbrush.png b/server_addon/applications/client/ayon_applications/icons/zbrush.png deleted file mode 100644 index 4b0662580c..0000000000 Binary files a/server_addon/applications/client/ayon_applications/icons/zbrush.png and /dev/null differ diff --git a/server_addon/applications/client/ayon_applications/manager.py b/server_addon/applications/client/ayon_applications/manager.py deleted file mode 100644 index f32bc20ef8..0000000000 --- a/server_addon/applications/client/ayon_applications/manager.py +++ /dev/null @@ -1,676 +0,0 @@ -import os -import sys -import copy -import json -import tempfile -import platform -import inspect -import subprocess - -import six - -from ayon_core import AYON_CORE_ROOT -from ayon_core.settings import get_studio_settings -from ayon_core.lib import ( - Logger, - modules_from_path, - classes_from_module, - get_linux_launcher_args, -) -from ayon_core.addon import AddonsManager - -from .constants import DEFAULT_ENV_SUBGROUP -from .exceptions import ( - ApplicationNotFound, - ApplicationExecutableNotFound, -) -from .hooks import PostLaunchHook, PreLaunchHook -from .defs import EnvironmentToolGroup, ApplicationGroup, LaunchTypes - - -class ApplicationManager: - """Load applications and tools and store them by their full name. - - Args: - studio_settings (dict): Preloaded studio settings. When passed manager - will always use these values. Gives ability to create manager - using different settings. - """ - - def __init__(self, studio_settings=None): - self.log = Logger.get_logger(self.__class__.__name__) - - self.app_groups = {} - self.applications = {} - self.tool_groups = {} - self.tools = {} - - self._studio_settings = studio_settings - - self.refresh() - - def set_studio_settings(self, studio_settings): - """Ability to change init system settings. - - This will trigger refresh of manager. - """ - self._studio_settings = studio_settings - - self.refresh() - - def refresh(self): - """Refresh applications from settings.""" - self.app_groups.clear() - self.applications.clear() - self.tool_groups.clear() - self.tools.clear() - - if self._studio_settings is not None: - settings = copy.deepcopy(self._studio_settings) - else: - settings = get_studio_settings( - clear_metadata=False, exclude_locals=False - ) - - applications_addon_settings = settings["applications"] - - # Prepare known applications - app_defs = applications_addon_settings["applications"] - additional_apps = app_defs.pop("additional_apps") - for additional_app in additional_apps: - app_name = additional_app.pop("name") - if app_name in app_defs: - self.log.warning(( - "Additional application '{}' is already" - " in built-in applications." - ).format(app_name)) - app_defs[app_name] = additional_app - - for group_name, variant_defs in app_defs.items(): - group = ApplicationGroup(group_name, variant_defs, self) - self.app_groups[group_name] = group - for app in group: - self.applications[app.full_name] = app - - tools_definitions = applications_addon_settings["tool_groups"] - for tool_group_data in tools_definitions: - group = EnvironmentToolGroup(tool_group_data, self) - self.tool_groups[group.name] = group - for tool in group: - self.tools[tool.full_name] = tool - - def find_latest_available_variant_for_group(self, group_name): - group = self.app_groups.get(group_name) - if group is None or not group.enabled: - return None - - output = None - for _, variant in reversed(sorted(group.variants.items())): - executable = variant.find_executable() - if executable: - output = variant - break - return output - - def create_launch_context(self, app_name, **data): - """Prepare launch context for application. - - Args: - app_name (str): Name of application that should be launched. - **data (Any): Any additional data. Data may be used during - - Returns: - ApplicationLaunchContext: Launch context for application. - - Raises: - ApplicationNotFound: Application was not found by entered name. - """ - - app = self.applications.get(app_name) - if not app: - raise ApplicationNotFound(app_name) - - executable = app.find_executable() - - return ApplicationLaunchContext( - app, executable, **data - ) - - def launch_with_context(self, launch_context): - """Launch application using existing launch context. - - Args: - launch_context (ApplicationLaunchContext): Prepared launch - context. - """ - - if not launch_context.executable: - raise ApplicationExecutableNotFound(launch_context.application) - return launch_context.launch() - - def launch(self, app_name, **data): - """Launch procedure. - - For host application it's expected to contain "project_name", - "folder_path" and "task_name". - - Args: - app_name (str): Name of application that should be launched. - **data (Any): Any additional data. Data may be used during - preparation to store objects usable in multiple places. - - Raises: - ApplicationNotFound: Application was not found by entered - argument `app_name`. - ApplicationExecutableNotFound: Executables in application definition - were not found on this machine. - ApplicationLaunchFailed: Something important for application launch - failed. Exception should contain explanation message, - traceback should not be needed. - """ - - context = self.create_launch_context(app_name, **data) - return self.launch_with_context(context) - - -class ApplicationLaunchContext: - """Context of launching application. - - Main purpose of context is to prepare launch arguments and keyword - arguments for new process. Most important part of keyword arguments - preparations are environment variables. - - During the whole process is possible to use `data` attribute to store - object usable in multiple places. - - Launch arguments are strings in list. It is possible to "chain" argument - when order of them matters. That is possible to do with adding list where - order is right and should not change. - NOTE: This is recommendation, not requirement. - e.g.: `["nuke.exe", "--NukeX"]` -> In this case any part of process may - insert argument between `nuke.exe` and `--NukeX`. To keep them together - it is better to wrap them in another list: `[["nuke.exe", "--NukeX"]]`. - - Notes: - It is possible to use launch context only to prepare environment - variables. In that case `executable` may be None and can be used - 'run_prelaunch_hooks' method to run prelaunch hooks which prepare - them. - - Args: - application (Application): Application definition. - executable (ApplicationExecutable): Object with path to executable. - env_group (Optional[str]): Environment variable group. If not set - 'DEFAULT_ENV_SUBGROUP' is used. - launch_type (Optional[str]): Launch type. If not set 'local' is used. - **data (dict): Any additional data. Data may be used during - preparation to store objects usable in multiple places. - """ - - def __init__( - self, - application, - executable, - env_group=None, - launch_type=None, - **data - ): - # Application object - self.application = application - - self.addons_manager = AddonsManager() - - # Logger - logger_name = "{}-{}".format(self.__class__.__name__, - self.application.full_name) - self.log = Logger.get_logger(logger_name) - - self.executable = executable - - if launch_type is None: - launch_type = LaunchTypes.local - self.launch_type = launch_type - - if env_group is None: - env_group = DEFAULT_ENV_SUBGROUP - - self.env_group = env_group - - self.data = dict(data) - - launch_args = [] - if executable is not None: - launch_args = executable.as_args() - # subprocess.Popen launch arguments (first argument in constructor) - self.launch_args = launch_args - self.launch_args.extend(application.arguments) - if self.data.get("app_args"): - self.launch_args.extend(self.data.pop("app_args")) - - # Handle launch environemtns - src_env = self.data.pop("env", None) - if src_env is not None and not isinstance(src_env, dict): - self.log.warning(( - "Passed `env` kwarg has invalid type: {}. Expected: `dict`." - " Using `os.environ` instead." - ).format(str(type(src_env)))) - src_env = None - - if src_env is None: - src_env = os.environ - - ignored_env = {"QT_API", } - env = { - key: str(value) - for key, value in src_env.items() - if key not in ignored_env - } - # subprocess.Popen keyword arguments - self.kwargs = {"env": env} - - if platform.system().lower() == "windows": - # Detach new process from currently running process on Windows - flags = ( - subprocess.CREATE_NEW_PROCESS_GROUP - | subprocess.DETACHED_PROCESS - ) - self.kwargs["creationflags"] = flags - - if not sys.stdout: - self.kwargs["stdout"] = subprocess.DEVNULL - self.kwargs["stderr"] = subprocess.DEVNULL - - self.prelaunch_hooks = None - self.postlaunch_hooks = None - - self.process = None - self._prelaunch_hooks_executed = False - - @property - def env(self): - if ( - "env" not in self.kwargs - or self.kwargs["env"] is None - ): - self.kwargs["env"] = {} - return self.kwargs["env"] - - @env.setter - def env(self, value): - if not isinstance(value, dict): - raise ValueError( - "'env' attribute expect 'dict' object. Got: {}".format( - str(type(value)) - ) - ) - self.kwargs["env"] = value - - @property - def modules_manager(self): - """ - Deprecated: - Use 'addons_manager' instead. - - """ - return self.addons_manager - - def _collect_addons_launch_hook_paths(self): - """Helper to collect application launch hooks from addons. - - Module have to have implemented 'get_launch_hook_paths' method which - can expect application as argument or nothing. - - Returns: - List[str]: Paths to launch hook directories. - """ - - expected_types = (list, tuple, set) - - output = [] - for module in self.addons_manager.get_enabled_addons(): - # Skip module if does not have implemented 'get_launch_hook_paths' - func = getattr(module, "get_launch_hook_paths", None) - if func is None: - continue - - func = module.get_launch_hook_paths - if hasattr(inspect, "signature"): - sig = inspect.signature(func) - expect_args = len(sig.parameters) > 0 - else: - expect_args = len(inspect.getargspec(func)[0]) > 0 - - # Pass application argument if method expect it. - try: - if expect_args: - hook_paths = func(self.application) - else: - hook_paths = func() - except Exception: - self.log.warning( - "Failed to call 'get_launch_hook_paths'", - exc_info=True - ) - continue - - if not hook_paths: - continue - - # Convert string to list - if isinstance(hook_paths, six.string_types): - hook_paths = [hook_paths] - - # Skip invalid types - if not isinstance(hook_paths, expected_types): - self.log.warning(( - "Result of `get_launch_hook_paths`" - " has invalid type {}. Expected {}" - ).format(type(hook_paths), expected_types)) - continue - - output.extend(hook_paths) - return output - - def paths_to_launch_hooks(self): - """Directory paths where to look for launch hooks.""" - # This method has potential to be part of application manager (maybe). - paths = [] - - # TODO load additional studio paths from settings - global_hooks_dir = os.path.join(AYON_CORE_ROOT, "hooks") - - hooks_dirs = [ - global_hooks_dir - ] - if self.host_name: - # If host requires launch hooks and is module then launch hooks - # should be collected using 'collect_launch_hook_paths' - # - module have to implement 'get_launch_hook_paths' - host_module = self.addons_manager.get_host_addon(self.host_name) - if not host_module: - hooks_dirs.append(os.path.join( - AYON_CORE_ROOT, "hosts", self.host_name, "hooks" - )) - - for path in hooks_dirs: - if ( - os.path.exists(path) - and os.path.isdir(path) - and path not in paths - ): - paths.append(path) - - # Load modules paths - paths.extend(self._collect_addons_launch_hook_paths()) - - return paths - - def discover_launch_hooks(self, force=False): - """Load and prepare launch hooks.""" - if ( - self.prelaunch_hooks is not None - or self.postlaunch_hooks is not None - ): - if not force: - self.log.info("Launch hooks were already discovered.") - return - - self.prelaunch_hooks.clear() - self.postlaunch_hooks.clear() - - self.log.debug("Discovery of launch hooks started.") - - paths = self.paths_to_launch_hooks() - self.log.debug("Paths searched for launch hooks:\n{}".format( - "\n".join("- {}".format(path) for path in paths) - )) - - all_classes = { - "pre": [], - "post": [] - } - for path in paths: - if not os.path.exists(path): - self.log.info( - "Path to launch hooks does not exist: \"{}\"".format(path) - ) - continue - - modules, _crashed = modules_from_path(path) - for _filepath, module in modules: - all_classes["pre"].extend( - classes_from_module(PreLaunchHook, module) - ) - all_classes["post"].extend( - classes_from_module(PostLaunchHook, module) - ) - - for launch_type, classes in all_classes.items(): - hooks_with_order = [] - hooks_without_order = [] - for klass in classes: - try: - hook = klass(self) - if not hook.is_valid: - self.log.debug( - "Skipped hook invalid for current launch context: " - "{}".format(klass.__name__) - ) - continue - - if inspect.isabstract(hook): - self.log.debug("Skipped abstract hook: {}".format( - klass.__name__ - )) - continue - - # Separate hooks by pre/post class - if hook.order is None: - hooks_without_order.append(hook) - else: - hooks_with_order.append(hook) - - except Exception: - self.log.warning( - "Initialization of hook failed: " - "{}".format(klass.__name__), - exc_info=True - ) - - # Sort hooks with order by order - ordered_hooks = list(sorted( - hooks_with_order, key=lambda obj: obj.order - )) - # Extend ordered hooks with hooks without defined order - ordered_hooks.extend(hooks_without_order) - - if launch_type == "pre": - self.prelaunch_hooks = ordered_hooks - else: - self.postlaunch_hooks = ordered_hooks - - self.log.debug("Found {} prelaunch and {} postlaunch hooks.".format( - len(self.prelaunch_hooks), len(self.postlaunch_hooks) - )) - - @property - def app_name(self): - return self.application.name - - @property - def host_name(self): - return self.application.host_name - - @property - def app_group(self): - return self.application.group - - @property - def manager(self): - return self.application.manager - - def _run_process(self): - # Windows and MacOS have easier process start - low_platform = platform.system().lower() - if low_platform in ("windows", "darwin"): - return subprocess.Popen(self.launch_args, **self.kwargs) - - # Linux uses mid process - # - it is possible that the mid process executable is not - # available for this version of AYON in that case use standard - # launch - launch_args = get_linux_launcher_args() - if launch_args is None: - return subprocess.Popen(self.launch_args, **self.kwargs) - - # Prepare data that will be passed to midprocess - # - store arguments to a json and pass path to json as last argument - # - pass environments to set - app_env = self.kwargs.pop("env", {}) - json_data = { - "args": self.launch_args, - "env": app_env - } - if app_env: - # Filter environments of subprocess - self.kwargs["env"] = { - key: value - for key, value in os.environ.items() - if key in app_env - } - - # Create temp file - json_temp = tempfile.NamedTemporaryFile( - mode="w", prefix="op_app_args", suffix=".json", delete=False - ) - json_temp.close() - json_temp_filpath = json_temp.name - with open(json_temp_filpath, "w") as stream: - json.dump(json_data, stream) - - launch_args.append(json_temp_filpath) - - # Create mid-process which will launch application - process = subprocess.Popen(launch_args, **self.kwargs) - # Wait until the process finishes - # - This is important! The process would stay in "open" state. - process.wait() - # Remove the temp file - os.remove(json_temp_filpath) - # Return process which is already terminated - return process - - def run_prelaunch_hooks(self): - """Run prelaunch hooks. - - This method will be executed only once, any future calls will skip - the processing. - """ - - if self._prelaunch_hooks_executed: - self.log.warning("Prelaunch hooks were already executed.") - return - # Discover launch hooks - self.discover_launch_hooks() - - # Execute prelaunch hooks - for prelaunch_hook in self.prelaunch_hooks: - self.log.debug("Executing prelaunch hook: {}".format( - str(prelaunch_hook.__class__.__name__) - )) - prelaunch_hook.execute() - self._prelaunch_hooks_executed = True - - def launch(self): - """Collect data for new process and then create it. - - This method must not be executed more than once. - - Returns: - subprocess.Popen: Created process as Popen object. - """ - if self.process is not None: - self.log.warning("Application was already launched.") - return - - if not self._prelaunch_hooks_executed: - self.run_prelaunch_hooks() - - self.log.debug("All prelaunch hook executed. Starting new process.") - - # Prepare subprocess args - args_len_str = "" - if isinstance(self.launch_args, str): - args = self.launch_args - else: - args = self.clear_launch_args(self.launch_args) - args_len_str = " ({})".format(len(args)) - self.log.info( - "Launching \"{}\" with args{}: {}".format( - self.application.full_name, args_len_str, args - ) - ) - self.launch_args = args - - # Run process - self.process = self._run_process() - - # Process post launch hooks - for postlaunch_hook in self.postlaunch_hooks: - self.log.debug("Executing postlaunch hook: {}".format( - str(postlaunch_hook.__class__.__name__) - )) - - # TODO how to handle errors? - # - store to variable to let them accessible? - try: - postlaunch_hook.execute() - - except Exception: - self.log.warning( - "After launch procedures were not successful.", - exc_info=True - ) - - self.log.debug("Launch of {} finished.".format( - self.application.full_name - )) - - return self.process - - @staticmethod - def clear_launch_args(args): - """Collect launch arguments to final order. - - Launch argument should be list that may contain another lists this - function will upack inner lists and keep ordering. - - ``` - # source - [ [ arg1, [ arg2, arg3 ] ], arg4, [arg5, arg6]] - # result - [ arg1, arg2, arg3, arg4, arg5, arg6] - - Args: - args (list): Source arguments in list may contain inner lists. - - Return: - list: Unpacked arguments. - """ - if isinstance(args, str): - return args - all_cleared = False - while not all_cleared: - all_cleared = True - new_args = [] - for arg in args: - if isinstance(arg, (list, tuple, set)): - all_cleared = False - for _arg in arg: - new_args.append(_arg) - else: - new_args.append(arg) - args = new_args - - return args - diff --git a/server_addon/applications/client/ayon_applications/plugins/publish/collect_app_name.py b/server_addon/applications/client/ayon_applications/plugins/publish/collect_app_name.py deleted file mode 100644 index f54a551cda..0000000000 --- a/server_addon/applications/client/ayon_applications/plugins/publish/collect_app_name.py +++ /dev/null @@ -1,48 +0,0 @@ -""" -Run after global plugin 'CollectHostName' in ayon_core. - -Requires: - None - -Provides: - context -> hostName (str) - context -> appName (str) - context -> appLabel (str) -""" -import os -import pyblish.api - -from ayon_applications import ApplicationManager - - -class CollectAppName(pyblish.api.ContextPlugin): - """Collect avalon host name to context.""" - - label = "Collect App Name" - order = pyblish.api.CollectorOrder - 0.499999 - - def process(self, context): - host_name = context.data.get("hostName") - app_name = context.data.get("appName") - app_label = context.data.get("appLabel") - # Don't override value if is already set - if host_name and app_name and app_label: - return - - # Use AYON_APP_NAME to get full app name - if not app_name: - app_name = os.environ.get("AYON_APP_NAME") - - # Fill missing values based on app full name - if (not host_name or not app_label) and app_name: - app_manager = ApplicationManager() - app = app_manager.applications.get(app_name) - if app: - if not host_name: - host_name = app.host_name - if not app_label: - app_label = app.full_label - - context.data["hostName"] = host_name - context.data["appName"] = app_name - context.data["appLabel"] = app_label diff --git a/server_addon/applications/client/ayon_applications/utils.py b/server_addon/applications/client/ayon_applications/utils.py deleted file mode 100644 index ce587e3abe..0000000000 --- a/server_addon/applications/client/ayon_applications/utils.py +++ /dev/null @@ -1,614 +0,0 @@ -import os -import copy -import json -import platform -import collections - -import six -import acre - -from ayon_core import AYON_CORE_ROOT -from ayon_core.settings import get_project_settings -from ayon_core.lib import Logger, get_ayon_username -from ayon_core.addon import AddonsManager -from ayon_core.pipeline.template_data import get_template_data -from ayon_core.pipeline.workfile import ( - get_workfile_template_key, - get_workdir_with_workdir_data, - get_last_workfile, - should_use_last_workfile_on_launch, - should_open_workfiles_tool_on_launch, -) - -from .constants import PLATFORM_NAMES, DEFAULT_ENV_SUBGROUP -from .exceptions import MissingRequiredKey, ApplicationLaunchFailed -from .manager import ApplicationManager - - -def parse_environments(env_data, env_group=None, platform_name=None): - """Parse environment values from settings byt group and platform. - - Data may contain up to 2 hierarchical levels of dictionaries. At the end - of the last level must be string or list. List is joined using platform - specific joiner (';' for windows and ':' for linux and mac). - - Hierarchical levels can contain keys for subgroups and platform name. - Platform specific values must be always last level of dictionary. Platform - names are "windows" (MS Windows), "linux" (any linux distribution) and - "darwin" (any MacOS distribution). - - Subgroups are helpers added mainly for standard and on farm usage. Farm - may require different environments for e.g. licence related values or - plugins. Default subgroup is "standard". - - Examples: - ``` - { - # Unchanged value - "ENV_KEY1": "value", - # Empty values are kept (unset environment variable) - "ENV_KEY2": "", - - # Join list values with ':' or ';' - "ENV_KEY3": ["value1", "value2"], - - # Environment groups - "ENV_KEY4": { - "standard": "DEMO_SERVER_URL", - "farm": "LICENCE_SERVER_URL" - }, - - # Platform specific (and only for windows and mac) - "ENV_KEY5": { - "windows": "windows value", - "darwin": ["value 1", "value 2"] - }, - - # Environment groups and platform combination - "ENV_KEY6": { - "farm": "FARM_VALUE", - "standard": { - "windows": ["value1", "value2"], - "linux": "value1", - "darwin": "" - } - } - } - ``` - """ - output = {} - if not env_data: - return output - - if not env_group: - env_group = DEFAULT_ENV_SUBGROUP - - if not platform_name: - platform_name = platform.system().lower() - - for key, value in env_data.items(): - if isinstance(value, dict): - # Look if any key is platform key - # - expect that represents environment group if does not contain - # platform keys - if not PLATFORM_NAMES.intersection(set(value.keys())): - # Skip the key if group is not available - if env_group not in value: - continue - value = value[env_group] - - # Check again if value is dictionary - # - this time there should be only platform keys - if isinstance(value, dict): - value = value.get(platform_name) - - # Check if value is list and join it's values - # QUESTION Should empty values be skipped? - if isinstance(value, (list, tuple)): - value = os.pathsep.join(value) - - # Set key to output if value is string - if isinstance(value, six.string_types): - output[key] = value - return output - - -class EnvironmentPrepData(dict): - """Helper dictionary for storin temp data during environment prep. - - Args: - data (dict): Data must contain required keys. - """ - required_keys = ( - "project_entity", "folder_entity", "task_entity", "app", "anatomy" - ) - - def __init__(self, data): - for key in self.required_keys: - if key not in data: - raise MissingRequiredKey(key) - - if not data.get("log"): - data["log"] = Logger.get_logger("EnvironmentPrepData") - - if data.get("env") is None: - data["env"] = os.environ.copy() - - project_name = data["project_entity"]["name"] - if "project_settings" not in data: - data["project_settings"] = get_project_settings(project_name) - - super(EnvironmentPrepData, self).__init__(data) - - -def get_app_environments_for_context( - project_name, - folder_path, - task_name, - app_name, - env_group=None, - launch_type=None, - env=None, - addons_manager=None -): - """Prepare environment variables by context. - Args: - project_name (str): Name of project. - folder_path (str): Folder path. - task_name (str): Name of task. - app_name (str): Name of application that is launched and can be found - by ApplicationManager. - env_group (Optional[str]): Name of environment group. If not passed - default group is used. - launch_type (Optional[str]): Type for which prelaunch hooks are - executed. - env (Optional[dict[str, str]]): Initial environment variables. - `os.environ` is used when not passed. - addons_manager (Optional[AddonsManager]): Initialized modules - manager. - - Returns: - dict: Environments for passed context and application. - """ - - # Prepare app object which can be obtained only from ApplicationManager - app_manager = ApplicationManager() - context = app_manager.create_launch_context( - app_name, - project_name=project_name, - folder_path=folder_path, - task_name=task_name, - env_group=env_group, - launch_type=launch_type, - env=env, - addons_manager=addons_manager, - modules_manager=addons_manager, - ) - context.run_prelaunch_hooks() - return context.env - - -def _merge_env(env, current_env): - """Modified function(merge) from acre module.""" - result = current_env.copy() - for key, value in env.items(): - # Keep missing keys by not filling `missing` kwarg - value = acre.lib.partial_format(value, data=current_env) - result[key] = value - return result - - -def _add_python_version_paths(app, env, logger, addons_manager): - """Add vendor packages specific for a Python version.""" - - for addon in addons_manager.get_enabled_addons(): - addon.modify_application_launch_arguments(app, env) - - # Skip adding if host name is not set - if not app.host_name: - return - - # Add Python 2/3 modules - python_vendor_dir = os.path.join( - AYON_CORE_ROOT, - "vendor", - "python" - ) - if app.use_python_2: - pythonpath = os.path.join(python_vendor_dir, "python_2") - else: - pythonpath = os.path.join(python_vendor_dir, "python_3") - - if not os.path.exists(pythonpath): - return - - logger.debug("Adding Python version specific paths to PYTHONPATH") - python_paths = [pythonpath] - - # Load PYTHONPATH from current launch context - python_path = env.get("PYTHONPATH") - if python_path: - python_paths.append(python_path) - - # Set new PYTHONPATH to launch context environments - env["PYTHONPATH"] = os.pathsep.join(python_paths) - - -def prepare_app_environments( - data, env_group=None, implementation_envs=True, addons_manager=None -): - """Modify launch environments based on launched app and context. - - Args: - data (EnvironmentPrepData): Dictionary where result and intermediate - result will be stored. - - """ - app = data["app"] - log = data["log"] - source_env = data["env"].copy() - - if addons_manager is None: - addons_manager = AddonsManager() - - _add_python_version_paths(app, source_env, log, addons_manager) - - # Use environments from local settings - filtered_local_envs = {} - # NOTE Overrides for environment variables are not implemented in AYON. - # project_settings = data["project_settings"] - # whitelist_envs = project_settings["general"].get("local_env_white_list") - # if whitelist_envs: - # local_settings = get_local_settings() - # local_envs = local_settings.get("environments") or {} - # filtered_local_envs = { - # key: value - # for key, value in local_envs.items() - # if key in whitelist_envs - # } - - # Apply local environment variables for already existing values - for key, value in filtered_local_envs.items(): - if key in source_env: - source_env[key] = value - - # `app_and_tool_labels` has debug purpose - app_and_tool_labels = [app.full_name] - # Environments for application - environments = [ - app.group.environment, - app.environment - ] - - task_entity = data.get("task_entity") - folder_entity = data.get("folder_entity") - # Add tools environments - groups_by_name = {} - tool_by_group_name = collections.defaultdict(dict) - tools = None - if task_entity: - tools = task_entity["attrib"].get("tools") - - if tools is None and folder_entity: - tools = folder_entity["attrib"].get("tools") - - if tools: - for key in tools: - tool = app.manager.tools.get(key) - if not tool or not tool.is_valid_for_app(app): - continue - groups_by_name[tool.group.name] = tool.group - tool_by_group_name[tool.group.name][tool.name] = tool - - for group_name in sorted(groups_by_name.keys()): - group = groups_by_name[group_name] - environments.append(group.environment) - for tool_name in sorted(tool_by_group_name[group_name].keys()): - tool = tool_by_group_name[group_name][tool_name] - environments.append(tool.environment) - app_and_tool_labels.append(tool.full_name) - - log.debug( - "Will add environments for apps and tools: {}".format( - ", ".join(app_and_tool_labels) - ) - ) - - env_values = {} - for _env_values in environments: - if not _env_values: - continue - - # Choose right platform - tool_env = parse_environments(_env_values, env_group) - - # Apply local environment variables - # - must happen between all values because they may be used during - # merge - for key, value in filtered_local_envs.items(): - if key in tool_env: - tool_env[key] = value - - # Merge dictionaries - env_values = _merge_env(tool_env, env_values) - - merged_env = _merge_env(env_values, source_env) - - loaded_env = acre.compute(merged_env, cleanup=False) - - final_env = None - # Add host specific environments - if app.host_name and implementation_envs: - host_addon = addons_manager.get_host_addon(app.host_name) - add_implementation_envs = None - if host_addon: - add_implementation_envs = getattr( - host_addon, "add_implementation_envs", None - ) - if add_implementation_envs: - # Function may only modify passed dict without returning value - final_env = add_implementation_envs(loaded_env, app) - - if final_env is None: - final_env = loaded_env - - keys_to_remove = set(source_env.keys()) - set(final_env.keys()) - - # Update env - data["env"].update(final_env) - for key in keys_to_remove: - data["env"].pop(key, None) - - -def apply_project_environments_value( - project_name, env, project_settings=None, env_group=None -): - """Apply project specific environments on passed environments. - - The environments are applied on passed `env` argument value so it is not - required to apply changes back. - - Args: - project_name (str): Name of project for which environments should be - received. - env (dict): Environment values on which project specific environments - will be applied. - project_settings (dict): Project settings for passed project name. - Optional if project settings are already prepared. - - Returns: - dict: Passed env values with applied project environments. - - Raises: - KeyError: If project settings do not contain keys for project specific - environments. - - """ - if project_settings is None: - project_settings = get_project_settings(project_name) - - env_value = project_settings["core"]["project_environments"] - if env_value: - env_value = json.loads(env_value) - parsed_value = parse_environments(env_value, env_group) - env.update(acre.compute( - _merge_env(parsed_value, env), - cleanup=False - )) - return env - - -def prepare_context_environments(data, env_group=None, addons_manager=None): - """Modify launch environments with context data for launched host. - - Args: - data (EnvironmentPrepData): Dictionary where result and intermediate - result will be stored. - - """ - # Context environments - log = data["log"] - - project_entity = data["project_entity"] - folder_entity = data["folder_entity"] - task_entity = data["task_entity"] - if not project_entity: - log.info( - "Skipping context environments preparation." - " Launch context does not contain required data." - ) - return - - # Load project specific environments - project_name = project_entity["name"] - project_settings = get_project_settings(project_name) - data["project_settings"] = project_settings - - app = data["app"] - context_env = { - "AYON_PROJECT_NAME": project_entity["name"], - "AYON_APP_NAME": app.full_name - } - if folder_entity: - folder_path = folder_entity["path"] - context_env["AYON_FOLDER_PATH"] = folder_path - - if task_entity: - context_env["AYON_TASK_NAME"] = task_entity["name"] - - log.debug( - "Context environments set:\n{}".format( - json.dumps(context_env, indent=4) - ) - ) - data["env"].update(context_env) - - # Apply project specific environments on current env value - # - apply them once the context environments are set - apply_project_environments_value( - project_name, data["env"], project_settings, env_group - ) - - if not app.is_host: - return - - data["env"]["AYON_HOST_NAME"] = app.host_name - - if not folder_entity or not task_entity: - # QUESTION replace with log.info and skip workfile discovery? - # - technically it should be possible to launch host without context - raise ApplicationLaunchFailed( - "Host launch require folder and task context." - ) - - workdir_data = get_template_data( - project_entity, - folder_entity, - task_entity, - app.host_name, - project_settings - ) - data["workdir_data"] = workdir_data - - anatomy = data["anatomy"] - - task_type = workdir_data["task"]["type"] - # Temp solution how to pass task type to `_prepare_last_workfile` - data["task_type"] = task_type - - try: - workdir = get_workdir_with_workdir_data( - workdir_data, - anatomy.project_name, - anatomy, - project_settings=project_settings - ) - - except Exception as exc: - raise ApplicationLaunchFailed( - "Error in anatomy.format: {}".format(str(exc)) - ) - - if not os.path.exists(workdir): - log.debug( - "Creating workdir folder: \"{}\"".format(workdir) - ) - try: - os.makedirs(workdir) - except Exception as exc: - raise ApplicationLaunchFailed( - "Couldn't create workdir because: {}".format(str(exc)) - ) - - data["env"]["AYON_WORKDIR"] = workdir - - _prepare_last_workfile(data, workdir, addons_manager) - - -def _prepare_last_workfile(data, workdir, addons_manager): - """last workfile workflow preparation. - - Function check if should care about last workfile workflow and tries - to find the last workfile. Both information are stored to `data` and - environments. - - Last workfile is filled always (with version 1) even if any workfile - exists yet. - - Args: - data (EnvironmentPrepData): Dictionary where result and intermediate - result will be stored. - workdir (str): Path to folder where workfiles should be stored. - - """ - if not addons_manager: - addons_manager = AddonsManager() - - log = data["log"] - - _workdir_data = data.get("workdir_data") - if not _workdir_data: - log.info( - "Skipping last workfile preparation." - " Key `workdir_data` not filled." - ) - return - - app = data["app"] - workdir_data = copy.deepcopy(_workdir_data) - project_name = data["project_name"] - task_name = data["task_name"] - task_type = data["task_type"] - - start_last_workfile = data.get("start_last_workfile") - if start_last_workfile is None: - start_last_workfile = should_use_last_workfile_on_launch( - project_name, app.host_name, task_name, task_type - ) - else: - log.info("Opening of last workfile was disabled by user") - - data["start_last_workfile"] = start_last_workfile - - workfile_startup = should_open_workfiles_tool_on_launch( - project_name, app.host_name, task_name, task_type - ) - data["workfile_startup"] = workfile_startup - - # Store boolean as "0"(False) or "1"(True) - data["env"]["AVALON_OPEN_LAST_WORKFILE"] = ( - str(int(bool(start_last_workfile))) - ) - data["env"]["AYON_WORKFILE_TOOL_ON_START"] = ( - str(int(bool(workfile_startup))) - ) - - _sub_msg = "" if start_last_workfile else " not" - log.debug( - "Last workfile should{} be opened on start.".format(_sub_msg) - ) - - # Last workfile path - last_workfile_path = data.get("last_workfile_path") or "" - if not last_workfile_path: - host_addon = addons_manager.get_host_addon(app.host_name) - extensions = None - if host_addon: - extensions = host_addon.get_workfile_extensions() - - if extensions: - anatomy = data["anatomy"] - project_settings = data["project_settings"] - task_type = workdir_data["task"]["type"] - template_key = get_workfile_template_key( - project_name, - task_type, - app.host_name, - project_settings=project_settings - ) - # Find last workfile - file_template = anatomy.get_template_item( - "work", template_key, "file" - ).template - - workdir_data.update({ - "version": 1, - "user": get_ayon_username(), - "ext": extensions[0] - }) - - last_workfile_path = get_last_workfile( - workdir, file_template, workdir_data, extensions, True - ) - - if os.path.exists(last_workfile_path): - log.debug(( - "Workfiles for launch context does not exists" - " yet but path will be set." - )) - log.debug( - "Setting last workfile path: {}".format(last_workfile_path) - ) - - data["env"]["AYON_LAST_WORKFILE"] = last_workfile_path - data["last_workfile_path"] = last_workfile_path diff --git a/server_addon/applications/client/ayon_applications/version.py b/server_addon/applications/client/ayon_applications/version.py deleted file mode 100644 index 06abc74286..0000000000 --- a/server_addon/applications/client/ayon_applications/version.py +++ /dev/null @@ -1,3 +0,0 @@ -# -*- coding: utf-8 -*- -"""Package declaring AYON addon 'applications' version.""" -__version__ = "0.2.4" diff --git a/server_addon/applications/package.py b/server_addon/applications/package.py deleted file mode 100644 index 23b1756d99..0000000000 --- a/server_addon/applications/package.py +++ /dev/null @@ -1,12 +0,0 @@ -name = "applications" -title = "Applications" -version = "0.2.4" - -client_dir = "ayon_applications" - -ayon_server_version = ">=1.0.7" -ayon_launcher_version = ">=1.0.2" -ayon_required_addons = { - "core": ">0.3.0", -} -ayon_compatible_addons = {} diff --git a/server_addon/applications/public/icons/3de4.png b/server_addon/applications/public/icons/3de4.png deleted file mode 100644 index bd0fe40d37..0000000000 Binary files a/server_addon/applications/public/icons/3de4.png and /dev/null differ diff --git a/server_addon/applications/public/icons/3dsmax.png b/server_addon/applications/public/icons/3dsmax.png deleted file mode 100644 index 9ebdf6099f..0000000000 Binary files a/server_addon/applications/public/icons/3dsmax.png and /dev/null differ diff --git a/server_addon/applications/public/icons/aftereffects.png b/server_addon/applications/public/icons/aftereffects.png deleted file mode 100644 index 56754e2be2..0000000000 Binary files a/server_addon/applications/public/icons/aftereffects.png and /dev/null differ diff --git a/server_addon/applications/public/icons/blender.png b/server_addon/applications/public/icons/blender.png deleted file mode 100644 index 6070a51fae..0000000000 Binary files a/server_addon/applications/public/icons/blender.png and /dev/null differ diff --git a/server_addon/applications/public/icons/celaction.png b/server_addon/applications/public/icons/celaction.png deleted file mode 100644 index 86ac092365..0000000000 Binary files a/server_addon/applications/public/icons/celaction.png and /dev/null differ diff --git a/server_addon/applications/public/icons/flame.png b/server_addon/applications/public/icons/flame.png deleted file mode 100644 index ba9b69e45f..0000000000 Binary files a/server_addon/applications/public/icons/flame.png and /dev/null differ diff --git a/server_addon/applications/public/icons/fusion.png b/server_addon/applications/public/icons/fusion.png deleted file mode 100644 index 50541b0e4f..0000000000 Binary files a/server_addon/applications/public/icons/fusion.png and /dev/null differ diff --git a/server_addon/applications/public/icons/harmony.png b/server_addon/applications/public/icons/harmony.png deleted file mode 100644 index f0f6c82c6e..0000000000 Binary files a/server_addon/applications/public/icons/harmony.png and /dev/null differ diff --git a/server_addon/applications/public/icons/hiero.png b/server_addon/applications/public/icons/hiero.png deleted file mode 100644 index ba666c2fe0..0000000000 Binary files a/server_addon/applications/public/icons/hiero.png and /dev/null differ diff --git a/server_addon/applications/public/icons/houdini.png b/server_addon/applications/public/icons/houdini.png deleted file mode 100644 index 11cfa46dce..0000000000 Binary files a/server_addon/applications/public/icons/houdini.png and /dev/null differ diff --git a/server_addon/applications/public/icons/maya.png b/server_addon/applications/public/icons/maya.png deleted file mode 100644 index 95c605f50d..0000000000 Binary files a/server_addon/applications/public/icons/maya.png and /dev/null differ diff --git a/server_addon/applications/public/icons/nuke.png b/server_addon/applications/public/icons/nuke.png deleted file mode 100644 index e734b4984e..0000000000 Binary files a/server_addon/applications/public/icons/nuke.png and /dev/null differ diff --git a/server_addon/applications/public/icons/nukestudio.png b/server_addon/applications/public/icons/nukestudio.png deleted file mode 100644 index 601d4a591d..0000000000 Binary files a/server_addon/applications/public/icons/nukestudio.png and /dev/null differ diff --git a/server_addon/applications/public/icons/nukex.png b/server_addon/applications/public/icons/nukex.png deleted file mode 100644 index 980f150124..0000000000 Binary files a/server_addon/applications/public/icons/nukex.png and /dev/null differ diff --git a/server_addon/applications/public/icons/openrv.png b/server_addon/applications/public/icons/openrv.png deleted file mode 100644 index 30077b38e8..0000000000 Binary files a/server_addon/applications/public/icons/openrv.png and /dev/null differ diff --git a/server_addon/applications/public/icons/photoshop.png b/server_addon/applications/public/icons/photoshop.png deleted file mode 100644 index c7e9d14711..0000000000 Binary files a/server_addon/applications/public/icons/photoshop.png and /dev/null differ diff --git a/server_addon/applications/public/icons/premiere.png b/server_addon/applications/public/icons/premiere.png deleted file mode 100644 index eb5b3d1ba2..0000000000 Binary files a/server_addon/applications/public/icons/premiere.png and /dev/null differ diff --git a/server_addon/applications/public/icons/python.png b/server_addon/applications/public/icons/python.png deleted file mode 100644 index b3b5b2220a..0000000000 Binary files a/server_addon/applications/public/icons/python.png and /dev/null differ diff --git a/server_addon/applications/public/icons/resolve.png b/server_addon/applications/public/icons/resolve.png deleted file mode 100644 index d084288d90..0000000000 Binary files a/server_addon/applications/public/icons/resolve.png and /dev/null differ diff --git a/server_addon/applications/public/icons/shotgrid.png b/server_addon/applications/public/icons/shotgrid.png deleted file mode 100644 index 6d0cc047f9..0000000000 Binary files a/server_addon/applications/public/icons/shotgrid.png and /dev/null differ diff --git a/server_addon/applications/public/icons/storyboardpro.png b/server_addon/applications/public/icons/storyboardpro.png deleted file mode 100644 index ac9526f163..0000000000 Binary files a/server_addon/applications/public/icons/storyboardpro.png and /dev/null differ diff --git a/server_addon/applications/public/icons/substancepainter.png b/server_addon/applications/public/icons/substancepainter.png deleted file mode 100644 index dc46f25d74..0000000000 Binary files a/server_addon/applications/public/icons/substancepainter.png and /dev/null differ diff --git a/server_addon/applications/public/icons/tvpaint.png b/server_addon/applications/public/icons/tvpaint.png deleted file mode 100644 index adad6b2015..0000000000 Binary files a/server_addon/applications/public/icons/tvpaint.png and /dev/null differ diff --git a/server_addon/applications/public/icons/ue4.png b/server_addon/applications/public/icons/ue4.png deleted file mode 100644 index 39201de664..0000000000 Binary files a/server_addon/applications/public/icons/ue4.png and /dev/null differ diff --git a/server_addon/applications/public/icons/wrap.png b/server_addon/applications/public/icons/wrap.png deleted file mode 100644 index 34ae1d68ed..0000000000 Binary files a/server_addon/applications/public/icons/wrap.png and /dev/null differ diff --git a/server_addon/applications/public/icons/zbrush.png b/server_addon/applications/public/icons/zbrush.png deleted file mode 100644 index 4b0662580c..0000000000 Binary files a/server_addon/applications/public/icons/zbrush.png and /dev/null differ diff --git a/server_addon/applications/server/__init__.py b/server_addon/applications/server/__init__.py deleted file mode 100644 index d85678b77b..0000000000 --- a/server_addon/applications/server/__init__.py +++ /dev/null @@ -1,311 +0,0 @@ -import os -import json -import copy - -from ayon_server.addons import BaseServerAddon, AddonLibrary -from ayon_server.entities.core import attribute_library -from ayon_server.lib.postgres import Postgres - -from .settings import ApplicationsAddonSettings, DEFAULT_VALUES - -try: - import semver -except ImportError: - semver = None - - -def sort_versions(addon_versions, reverse=False): - if semver is None: - for addon_version in sorted(addon_versions, reverse=reverse): - yield addon_version - return - - version_objs = [] - invalid_versions = [] - for addon_version in addon_versions: - try: - version_objs.append( - (addon_version, semver.VersionInfo.parse(addon_version)) - ) - except ValueError: - invalid_versions.append(addon_version) - - valid_versions = [ - addon_version - for addon_version, _ in sorted(version_objs, key=lambda x: x[1]) - ] - sorted_versions = list(sorted(invalid_versions)) + valid_versions - if reverse: - sorted_versions = reversed(sorted_versions) - for addon_version in sorted_versions: - yield addon_version - - -def merge_groups(output, new_groups): - groups_by_name = { - o_group["name"]: o_group - for o_group in output - } - extend_groups = [] - for new_group in new_groups: - group_name = new_group["name"] - if group_name not in groups_by_name: - extend_groups.append(new_group) - continue - existing_group = groups_by_name[group_name] - existing_variants = existing_group["variants"] - existing_variants_by_name = { - variant["name"]: variant - for variant in existing_variants - } - for new_variant in new_group["variants"]: - if new_variant["name"] not in existing_variants_by_name: - existing_variants.append(new_variant) - - output.extend(extend_groups) - - -def get_enum_items_from_groups(groups): - label_by_name = {} - for group in groups: - group_name = group["name"] - group_label = group["label"] or group_name - for variant in group["variants"]: - variant_name = variant["name"] - if not variant_name: - continue - variant_label = variant["label"] or variant_name - full_name = f"{group_name}/{variant_name}" - full_label = f"{group_label} {variant_label}" - label_by_name[full_name] = full_label - - return [ - {"value": full_name, "label": label_by_name[full_name]} - for full_name in sorted(label_by_name) - ] - - -class ApplicationsAddon(BaseServerAddon): - settings_model = ApplicationsAddonSettings - - async def get_default_settings(self): - server_dir = os.path.join(self.addon_dir, "server") - applications_path = os.path.join(server_dir, "applications.json") - tools_path = os.path.join(server_dir, "tools.json") - default_values = copy.deepcopy(DEFAULT_VALUES) - with open(applications_path, "r") as stream: - default_values.update(json.load(stream)) - - with open(tools_path, "r") as stream: - default_values.update(json.load(stream)) - - return self.get_settings_model()(**default_values) - - async def pre_setup(self): - """Make sure older version of addon use the new way of attributes.""" - - instance = AddonLibrary.getinstance() - app_defs = instance.data.get(self.name) - old_addon = app_defs.versions.get("0.1.0") - if old_addon is not None: - # Override 'create_applications_attribute' for older versions - # - avoid infinite server restart loop - old_addon.create_applications_attribute = ( - self.create_applications_attribute - ) - - async def setup(self): - need_restart = await self.create_required_attributes() - if need_restart: - self.request_server_restart() - await self._update_enums() - - def _get_applications_def(self): - return { - "name": "applications", - "type": "list_of_strings", - "title": "Applications", - "scope": ["project"], - "enum":[], - } - - def _get_tools_def(self): - return { - "name": "tools", - "type": "list_of_strings", - "title": "Tools", - "scope": ["project", "folder", "task"], - "enum":[], - } - - async def create_applications_attribute(self) -> bool: - """Make sure there are required attributes which ftrack addon needs. - - Returns: - bool: 'True' if an attribute was created or updated. - """ - - need_restart = await self.create_required_attributes() - await self._update_enums() - return need_restart - - async def create_required_attributes(self) -> bool: - """Make sure there are required 'applications' and 'tools' attributes. - This only checks for the existence of the attributes, it does not populate - them with any data. When an attribute is added, server needs to be restarted, - while adding enum data to the attribute does not require a restart. - Returns: - bool: 'True' if an attribute was created or updated. - """ - - # keep track of the last attribute position (for adding new attributes) - apps_attribute_data = self._get_applications_def() - tools_attribute_data = self._get_tools_def() - - apps_attrib_name = apps_attribute_data["name"] - tools_attrib_name = tools_attribute_data["name"] - - async with Postgres.acquire() as conn, conn.transaction(): - query = "SELECT BOOL_OR(name = 'applications') AS has_applications, BOOL_OR(name = 'tools') AS has_tools FROM attributes;" - result = (await conn.fetch(query))[0] - - attributes_to_create = {} - if not result["has_applications"]: - attributes_to_create[apps_attrib_name] = { - "scope": apps_attribute_data["scope"], - "data": { - "title": apps_attribute_data["title"], - "type": apps_attribute_data["type"], - "enum": [], - } - } - - if not result["has_tools"]: - attributes_to_create[tools_attrib_name] = { - "scope": tools_attribute_data["scope"], - "data": { - "title": tools_attribute_data["title"], - "type": tools_attribute_data["type"], - "enum": [], - }, - } - - needs_restart = False - # when any of the required attributes are not present, add them - # and return 'True' to indicate that server needs to be restarted - for name, payload in attributes_to_create.items(): - insert_query = "INSERT INTO attributes (name, scope, data, position) VALUES ($1, $2, $3, (SELECT COALESCE(MAX(position), 0) + 1 FROM attributes)) ON CONFLICT DO NOTHING" - await conn.execute( - insert_query, - name, - payload["scope"], - payload["data"], - ) - needs_restart = True - - return needs_restart - - async def _update_enums(self): - """Updates applications and tools enums based on the addon settings. - This method is called when the addon is started (after we are sure that the - 'applications' and 'tools' attributes exist) and when the addon settings are - updated (using on_settings_updated method). - """ - - instance = AddonLibrary.getinstance() - app_defs = instance.data.get(self.name) - all_applications = [] - all_tools = [] - for addon_version in sort_versions( - app_defs.versions.keys(), reverse=True - ): - addon = app_defs.versions[addon_version] - for variant in ("production", "staging"): - settings_model = await addon.get_studio_settings(variant) - studio_settings = settings_model.dict() - application_settings = studio_settings["applications"] - app_groups = application_settings.pop("additional_apps") - for group_name, value in application_settings.items(): - value["name"] = group_name - app_groups.append(value) - merge_groups(all_applications, app_groups) - merge_groups(all_tools, studio_settings["tool_groups"]) - - apps_attrib_name = "applications" - tools_attrib_name = "tools" - - apps_enum = get_enum_items_from_groups(all_applications) - tools_enum = get_enum_items_from_groups(all_tools) - - apps_attribute_data = { - "type": "list_of_strings", - "title": "Applications", - "enum": apps_enum, - } - tools_attribute_data = { - "type": "list_of_strings", - "title": "Tools", - "enum": tools_enum, - } - - apps_scope = ["project"] - tools_scope = ["project", "folder", "task"] - - apps_matches = False - tools_matches = False - - async for row in Postgres.iterate( - "SELECT name, position, scope, data from public.attributes" - ): - if row["name"] == apps_attrib_name: - # Check if scope is matching ftrack addon requirements - if ( - set(row["scope"]) == set(apps_scope) - and row["data"].get("enum") == apps_enum - ): - apps_matches = True - - elif row["name"] == tools_attrib_name: - if ( - set(row["scope"]) == set(tools_scope) - and row["data"].get("enum") == tools_enum - ): - tools_matches = True - - if apps_matches and tools_matches: - return - - if not apps_matches: - await Postgres.execute( - """ - UPDATE attributes SET - scope = $1, - data = $2 - WHERE - name = $3 - """, - apps_scope, - apps_attribute_data, - apps_attrib_name, - ) - - if not tools_matches: - await Postgres.execute( - """ - UPDATE attributes SET - scope = $1, - data = $2 - WHERE - name = $3 - """, - tools_scope, - tools_attribute_data, - tools_attrib_name, - ) - - # Reset attributes cache on server - await attribute_library.load() - - async def on_settings_changed(self, *args, **kwargs): - _ = args, kwargs - await self._update_enums() diff --git a/server_addon/applications/server/applications.json b/server_addon/applications/server/applications.json deleted file mode 100644 index 1c83997dea..0000000000 --- a/server_addon/applications/server/applications.json +++ /dev/null @@ -1,1333 +0,0 @@ -{ - "applications": { - "maya": { - "enabled": true, - "label": "Maya", - "icon": "{}/app_icons/maya.png", - "host_name": "maya", - "environment": "{\n \"MAYA_DISABLE_CLIC_IPM\": \"Yes\",\n \"MAYA_DISABLE_CIP\": \"Yes\",\n \"MAYA_DISABLE_CER\": \"Yes\",\n \"PYMEL_SKIP_MEL_INIT\": \"Yes\",\n \"LC_ALL\": \"C\"\n}\n", - "variants": [ - { - "name": "2025", - "label": "2025", - "executables": { - "windows": [ - "C:\\Program Files\\Autodesk\\Maya2025\\bin\\maya.exe" - ], - "darwin": ["/Applications/Autodesk/maya2025/Maya.app"], - "linux": [ - "/usr/autodesk/maya2025/bin/maya" - ] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{\n \"MAYA_VERSION\": \"2025\"\n}", - "use_python_2": false - }, - { - "name": "2024", - "label": "2024", - "executables": { - "windows": [ - "C:\\Program Files\\Autodesk\\Maya2024\\bin\\maya.exe" - ], - "darwin": ["/Applications/Autodesk/maya2024/Maya.app"], - "linux": [ - "/usr/autodesk/maya2024/bin/maya" - ] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{\n \"MAYA_VERSION\": \"2024\"\n}", - "use_python_2": false - }, - { - "name": "2023", - "label": "2023", - "executables": { - "windows": [ - "C:\\Program Files\\Autodesk\\Maya2023\\bin\\maya.exe" - ], - "darwin": ["/Applications/Autodesk/maya2023/Maya.app"], - "linux": [ - "/usr/autodesk/maya2023/bin/maya" - ] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{\n \"MAYA_VERSION\": \"2023\"\n}", - "use_python_2": false - }, - { - "name": "2022", - "label": "2022", - "executables": { - "windows": [ - "C:\\Program Files\\Autodesk\\Maya2022\\bin\\maya.exe" - ], - "darwin": ["/Applications/Autodesk/maya2022/Maya.app"], - "linux": [ - "/usr/autodesk/maya2022/bin/maya" - ] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{\n \"MAYA_VERSION\": \"2022\"\n}", - "use_python_2": true - } - ] - }, - "mayapy": { - "enabled": true, - "label": "Maya", - "icon": "{}/app_icons/maya.png", - "host_name": "maya", - "environment": "{\n \"MAYA_DISABLE_CLIC_IPM\": \"Yes\",\n \"MAYA_DISABLE_CIP\": \"Yes\",\n \"MAYA_DISABLE_CER\": \"Yes\",\n \"PYMEL_SKIP_MEL_INIT\": \"Yes\",\n \"LC_ALL\": \"C\"\n}\n", - "variants": [ - { - "name": "2024", - "label": "2024", - "executables": { - "windows": [ - "C:\\Program Files\\Autodesk\\Maya2024\\bin\\mayapy.exe" - ], - "darwin": [], - "linux": [ - "/usr/autodesk/maya2024/bin/mayapy" - ] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{\n \"MAYA_VERSION\": \"2024\"\n}", - "use_python_2": false - }, - { - "name": "2023", - "label": "2023", - "executables": { - "windows": [ - "C:\\Program Files\\Autodesk\\Maya2023\\bin\\mayapy.exe" - ], - "darwin": [], - "linux": [ - "/usr/autodesk/maya2023/bin/mayapy" - ] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{\n \"MAYA_VERSION\": \"2023\"\n}", - "use_python_2": false - } - ] - }, - "adsk_3dsmax": { - "enabled": true, - "label": "3ds Max", - "icon": "{}/app_icons/3dsmax.png", - "host_name": "max", - "environment": "{\n \"ADSK_3DSMAX_STARTUPSCRIPTS_ADDON_DIR\": \"{OPENPYPE_ROOT}/openpype/hosts/max/startup\"\n}", - "variants": [ - { - "name": "2024", - "use_python_2": false, - "executables": { - "windows": [ - "C:\\Program Files\\Autodesk\\3ds Max 2024\\3dsmax.exe" - ], - "darwin": [], - "linux": [] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{\n \"3DSMAX_VERSION\": \"2024\"\n}" - }, - { - "name": "2023", - "use_python_2": false, - "executables": { - "windows": [ - "C:\\Program Files\\Autodesk\\3ds Max 2023\\3dsmax.exe" - ], - "darwin": [], - "linux": [] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{\n \"3DSMAX_VERSION\": \"2023\"\n}" - } - ] - }, - "flame": { - "enabled": true, - "label": "Flame", - "icon": "{}/app_icons/flame.png", - "host_name": "flame", - "environment": "{\n \"FLAME_SCRIPT_DIRS\": {\n \"windows\": \"\",\n \"darwin\": \"\",\n \"linux\": \"\"\n },\n \"FLAME_WIRETAP_HOSTNAME\": \"\",\n \"FLAME_WIRETAP_VOLUME\": \"stonefs\",\n \"FLAME_WIRETAP_GROUP\": \"staff\"\n}", - "variants": [ - { - "name": "2021", - "label": "2021", - "executables": { - "windows": [], - "darwin": [ - "/opt/Autodesk/flame_2021/bin/flame.app/Contents/MacOS/startApp" - ], - "linux": [ - "/opt/Autodesk/flame_2021/bin/startApplication" - ] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{\n \"AYON_FLAME_PYTHON_EXEC\": \"/opt/Autodesk/python/2021/bin/python2.7\",\n \"AYON_FLAME_PYTHONPATH\": \"/opt/Autodesk/flame_2021/python\",\n \"AYON_WIRETAP_TOOLS\": \"/opt/Autodesk/wiretap/tools/2021\"\n}", - "use_python_2": true - }, - { - "name": "2021_1", - "label": "2021.1", - "executables": { - "windows": [], - "darwin": [ - "/opt/Autodesk/flame_2021.1/bin/flame.app/Contents/MacOS/startApp" - ], - "linux": [ - "/opt/Autodesk/flame_2021.1/bin/startApplication" - ] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{\n \"AYON_FLAME_PYTHON_EXEC\": \"/opt/Autodesk/python/2021.1/bin/python2.7\",\n \"AYON_FLAME_PYTHONPATH\": \"/opt/Autodesk/flame_2021.1/python\",\n \"AYON_WIRETAP_TOOLS\": \"/opt/Autodesk/wiretap/tools/2021.1\"\n}", - "use_python_2": true - } - ] - }, - "nuke": { - "enabled": true, - "label": "Nuke", - "icon": "{}/app_icons/nuke.png", - "host_name": "nuke", - "environment": "{\n \"NUKE_PATH\": [\n \"{NUKE_PATH}\",\n \"{OPENPYPE_STUDIO_PLUGINS}/nuke\"\n ]\n}", - "variants": [ - { - "name": "15-0", - "label": "15.0", - "executables": { - "windows": [ - "C:\\Program Files\\Nuke15.0v2\\Nuke15.0.exe" - ], - "darwin": [ - "/Applications/Nuke15.0v2/Nuke15.0v2.app" - ], - "linux": [ - "/usr/local/Nuke5.0v2/Nuke15.0" - ] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{}", - "use_python_2": false - }, - { - "name": "14-0", - "label": "14.0", - "executables": { - "windows": [ - "C:\\Program Files\\Nuke14.0v5\\Nuke14.0.exe" - ], - "darwin": [ - "/Applications/Nuke14.0v5/Nuke14.0v5.app" - ], - "linux": [ - "/usr/local/Nuke14.0v5/Nuke14.0" - ] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{}", - "use_python_2": false - }, - { - "name": "13-2", - "label": "13.2", - "executables": { - "windows": [ - "C:\\Program Files\\Nuke13.2v5\\Nuke13.2.exe" - ], - "darwin": [ - "/Applications/Nuke13.2v5/Nuke13.2v5.app" - ], - "linux": [ - "/usr/local/Nuke13.2v5/Nuke13.2" - ] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{}", - "use_python_2": false - } - ] - }, - "nukeassist": { - "enabled": true, - "label": "Nuke Assist", - "icon": "{}/app_icons/nuke.png", - "host_name": "nuke", - "environment": "{\n \"NUKE_PATH\": [\n \"{NUKE_PATH}\",\n \"{OPENPYPE_STUDIO_PLUGINS}/nuke\"\n ]\n}", - "variants": [ - { - "name": "15-0", - "label": "15.0", - "executables": { - "windows": [ - "C:\\Program Files\\Nuke15.0v2\\Nuke15.0.exe" - ], - "darwin": [ - "/Applications/Nuke15.0v2/NukeAssist15.0v2.app" - ], - "linux": [ - "/usr/local/Nuke5.0v2/Nuke15.0" - ] - }, - "arguments": { - "windows": ["--nukeassist"], - "darwin": [], - "linux": ["--nukeassist"] - }, - "environment": "{}", - "use_python_2": false - }, - { - "name": "14-0", - "label": "14.0", - "executables": { - "windows": [ - "C:\\Program Files\\Nuke14.0v5\\Nuke14.0.exe" - ], - "darwin": [ - "/Applications/Nuke14.0v5/NukeAssist14.0v5.app" - ], - "linux": [ - "/usr/local/Nuke14.0v5/Nuke14.0" - ] - }, - "arguments": { - "windows": ["--nukeassist"], - "darwin": [], - "linux": ["--nukeassist"] - }, - "environment": "{}", - "use_python_2": false - }, - { - "name": "13-2", - "label": "13.2", - "executables": { - "windows": [ - "C:\\Program Files\\Nuke13.2v5\\Nuke13.2.exe" - ], - "darwin": [ - "/Applications/Nuke13.2v5/NukeAssist13.2v5.app" - ], - "linux": [ - "/usr/local/Nuke13.2v5/Nuke13.2" - ] - }, - "arguments": { - "windows": ["--nukeassist"], - "darwin": [], - "linux": ["--nukeassist"] - }, - "environment": "{}", - "use_python_2": false - } - ] - }, - "nukex": { - "enabled": true, - "label": "Nuke X", - "icon": "{}/app_icons/nukex.png", - "host_name": "nuke", - "environment": "{\n \"NUKE_PATH\": [\n \"{NUKE_PATH}\",\n \"{OPENPYPE_STUDIO_PLUGINS}/nuke\"\n ]\n}", - "variants": [ - { - "name": "15-0", - "label": "15.0", - "executables": { - "windows": [ - "C:\\Program Files\\Nuke15.0v2\\Nuke15.0.exe" - ], - "darwin": [ - "/Applications/Nuke15.0v2/NukeX15.0v2.app" - ], - "linux": [ - "/usr/local/Nuke5.0v2/Nuke15.0" - ] - }, - "arguments": { - "windows": ["--nukex"], - "darwin": [], - "linux": ["--nukex"] - }, - "environment": "{}", - "use_python_2": false - }, - { - "name": "14-0", - "label": "14.0", - "executables": { - "windows": [ - "C:\\Program Files\\Nuke14.0v5\\Nuke14.0.exe" - ], - "darwin": [ - "/Applications/Nuke14.0v5/NukeX14.0v5.app" - ], - "linux": [ - "/usr/local/Nuke14.0v5/Nuke14.0" - ] - }, - "arguments": { - "windows": ["--nukex"], - "darwin": [], - "linux": ["--nukex"] - }, - "environment": "{}", - "use_python_2": false - }, - { - "name": "13-2", - "label": "13.2", - "executables": { - "windows": [ - "C:\\Program Files\\Nuke13.2v5\\Nuke13.2.exe" - ], - "darwin": [ - "/Applications/Nuke13.2v5/NukeX13.2v5.app" - ], - "linux": [ - "/usr/local/Nuke13.2v5/Nuke13.2" - ] - }, - "arguments": { - "windows": ["--nukex"], - "darwin": [], - "linux": ["--nukex"] - }, - "environment": "{}", - "use_python_2": false - } - ] - }, - "nukestudio": { - "enabled": true, - "label": "Nuke Studio", - "icon": "{}/app_icons/nukestudio.png", - "host_name": "hiero", - "environment": "{\n \"WORKFILES_STARTUP\": \"0\",\n \"TAG_ASSETBUILD_STARTUP\": \"0\"\n}", - "variants": [ - { - "name": "15-0", - "label": "15.0", - "executables": { - "windows": [ - "C:\\Program Files\\Nuke15.0v2\\Nuke15.0.exe" - ], - "darwin": [ - "/Applications/Nuke15.0v2/NukeStudio15.0v2.app" - ], - "linux": [ - "/usr/local/Nuke5.0v2/Nuke15.0" - ] - }, - "arguments": { - "windows": ["--studio"], - "darwin": [], - "linux": ["--studio"] - }, - "environment": "{}", - "use_python_2": false - }, - { - "name": "14-0", - "label": "14.0", - "executables": { - "windows": [ - "C:\\Program Files\\Nuke14.0v5\\Nuke14.0.exe" - ], - "darwin": [ - "/Applications/Nuke14.0v5/NukeStudio14.0v5.app" - ], - "linux": [ - "/usr/local/Nuke14.0v5/Nuke14.0" - ] - }, - "arguments": { - "windows": ["--studio"], - "darwin": [], - "linux": ["--studio"] - }, - "environment": "{}", - "use_python_2": false - }, - { - "name": "13-2", - "label": "13.2", - "executables": { - "windows": [ - "C:\\Program Files\\Nuke13.2v5\\Nuke13.2.exe" - ], - "darwin": [ - "/Applications/Nuke13.2v5/NukeStudio13.2v5.app" - ], - "linux": [ - "/usr/local/Nuke13.2v5/Nuke13.2" - ] - }, - "arguments": { - "windows": ["--studio"], - "darwin": [], - "linux": ["--studio"] - }, - "environment": "{}", - "use_python_2": false - } - ] - }, - "hiero": { - "enabled": true, - "label": "Hiero", - "icon": "{}/app_icons/hiero.png", - "host_name": "hiero", - "environment": "{\n \"WORKFILES_STARTUP\": \"0\",\n \"TAG_ASSETBUILD_STARTUP\": \"0\"\n}", - "variants": [ - { - "name": "15-0", - "label": "15.0", - "executables": { - "windows": [ - "C:\\Program Files\\Nuke15.0v2\\Nuke15.0.exe" - ], - "darwin": [ - "/Applications/Nuke15.0v2/Hiero15.0v2.app" - ], - "linux": [ - "/usr/local/Nuke5.0v2/Nuke15.0" - ] - }, - "arguments": { - "windows": ["--hiero"], - "darwin": [], - "linux": ["--hiero"] - }, - "environment": "{}", - "use_python_2": false - }, - { - "name": "14-0", - "label": "14.0", - "executables": { - "windows": [ - "C:\\Program Files\\Nuke14.0v5\\Nuke14.0.exe" - ], - "darwin": [ - "/Applications/Nuke14.0v5/Hiero14.0v5.app" - ], - "linux": [ - "/usr/local/Nuke14.0v5/Nuke14.0" - ] - }, - "arguments": { - "windows": ["--hiero"], - "darwin": [], - "linux": ["--hiero"] - }, - "environment": "{}", - "use_python_2": false - }, - { - "name": "13-2", - "label": "13.2", - "executables": { - "windows": [ - "C:\\Program Files\\Nuke13.2v5\\Nuke13.2.exe" - ], - "darwin": [ - "/Applications/Nuke13.2v5/Hiero13.2v5.app" - ], - "linux": [ - "/usr/local/Nuke13.2v5/Nuke13.2" - ] - }, - "arguments": { - "windows": ["--hiero"], - "darwin": [], - "linux": ["--hiero"] - }, - "environment": "{}", - "use_python_2": false - } - ] - }, - "fusion": { - "enabled": true, - "label": "Fusion", - "icon": "{}/app_icons/fusion.png", - "host_name": "fusion", - "environment": "{\n \"FUSION_PYTHON3_HOME\": {\n \"windows\": \"{LOCALAPPDATA}/Programs/Python/Python36\",\n \"darwin\": \"~/Library/Python/3.6/bin\",\n \"linux\": \"/opt/Python/3.6/bin\"\n }\n}", - "variants": [ - { - "name": "18", - "label": "18", - "executables": { - "windows": [ - "C:\\Program Files\\Blackmagic Design\\Fusion 18\\Fusion.exe" - ], - "darwin": [], - "linux": [] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{}" - }, - { - "name": "17", - "label": "17", - "executables": { - "windows": [ - "C:\\Program Files\\Blackmagic Design\\Fusion 17\\Fusion.exe" - ], - "darwin": [], - "linux": [] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{}" - }, - { - "name": "16", - "label": "16", - "executables": { - "windows": [ - "C:\\Program Files\\Blackmagic Design\\Fusion 16\\Fusion.exe" - ], - "darwin": [], - "linux": [] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{}" - } - ] - }, - "resolve": { - "enabled": true, - "label": "Resolve", - "icon": "{}/app_icons/resolve.png", - "host_name": "resolve", - "environment": "{\n \"RESOLVE_UTILITY_SCRIPTS_SOURCE_DIR\": [],\n \"RESOLVE_PYTHON3_HOME\": {\n \"windows\": \"{LOCALAPPDATA}/Programs/Python/Python36\",\n \"darwin\": \"~/Library/Python/3.6/bin\",\n \"linux\": \"/opt/Python/3.6/bin\"\n }\n}", - "variants": [ - { - "name": "stable", - "label": "stable", - "executables": { - "windows": [ - "C:/Program Files/Blackmagic Design/DaVinci Resolve/Resolve.exe" - ], - "darwin": [], - "linux": [] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{}" - } - ] - }, - "houdini": { - "enabled": true, - "label": "Houdini", - "icon": "{}/app_icons/houdini.png", - "host_name": "houdini", - "environment": "{}", - "variants": [ - { - "name": "19-5", - "label": "19.5", - "executables": { - "windows": [ - "C:\\Program Files\\Side Effects Software\\Houdini 19.5.805\\bin\\houdini.exe" - ], - "darwin": [], - "linux": [] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{}", - "use_python_2": true - }, - { - "name": "19-0", - "label": "19.0", - "executables": { - "windows": [ - "C:\\Program Files\\Side Effects Software\\Houdini 19.0.720\\bin\\houdini.exe" - ], - "darwin": [], - "linux": [] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{}", - "use_python_2": true - }, - { - "name": "18-5", - "label": "18.5", - "executables": { - "windows": [ - "C:\\Program Files\\Side Effects Software\\Houdini 18.5.759\\bin\\houdini.exe" - ], - "darwin": [], - "linux": [] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{}", - "use_python_2": true - } - ] - }, - "blender": { - "enabled": true, - "label": "Blender", - "icon": "{}/app_icons/blender.png", - "host_name": "blender", - "environment": "{}", - "variants": [ - { - "name": "3-6-5", - "label": "3.6.5 LTS", - "executables": { - "windows": [ - "C:\\Program Files\\Blender Foundation\\Blender 3.6\\blender.exe" - ], - "darwin": [], - "linux": [] - }, - "arguments": { - "windows": [ - "--python-use-system-env" - ], - "darwin": [ - "--python-use-system-env" - ], - "linux": [ - "--python-use-system-env" - ] - }, - "environment": "{}" - }, - { - "name": "2-90", - "label": "2.90", - "executables": { - "windows": [ - "C:\\Program Files\\Blender Foundation\\Blender 2.90\\blender.exe" - ], - "darwin": [], - "linux": [] - }, - "arguments": { - "windows": [ - "--python-use-system-env" - ], - "darwin": [ - "--python-use-system-env" - ], - "linux": [ - "--python-use-system-env" - ] - }, - "environment": "{}" - }, - { - "name": "2-91", - "label": "2.91", - "executables": { - "windows": [ - "C:\\Program Files\\Blender Foundation\\Blender 2.91\\blender.exe" - ], - "darwin": [], - "linux": [] - }, - "arguments": { - "windows": [ - "--python-use-system-env" - ], - "darwin": [ - "--python-use-system-env" - ], - "linux": [ - "--python-use-system-env" - ] - }, - "environment": "{}" - } - ] - }, - "harmony": { - "enabled": true, - "label": "Harmony", - "icon": "{}/app_icons/harmony.png", - "host_name": "harmony", - "environment": "{\n \"AVALON_HARMONY_WORKFILES_ON_LAUNCH\": \"1\"\n}", - "variants": [ - { - "name": "22", - "label": "22", - "executables": { - "windows": [ - "c:\\Program Files (x86)\\Toon Boom Animation\\Toon Boom Harmony 22 Premium\\win64\\bin\\HarmonyPremium.exe" - ], - "darwin": [ - "/Applications/Toon Boom Harmony 22 Premium/Harmony Premium.app/Contents/MacOS/Harmony Premium" - ], - "linux": [] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{}" - }, - { - "name": "21", - "label": "21", - "executables": { - "windows": [ - "c:\\Program Files (x86)\\Toon Boom Animation\\Toon Boom Harmony 21 Premium\\win64\\bin\\HarmonyPremium.exe" - ], - "darwin": [ - "/Applications/Toon Boom Harmony 21 Premium/Harmony Premium.app/Contents/MacOS/Harmony Premium" - ], - "linux": [] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{}" - }, - { - "name": "20", - "label": "20", - "executables": { - "windows": [ - "c:\\Program Files (x86)\\Toon Boom Animation\\Toon Boom Harmony 20 Premium\\win64\\bin\\HarmonyPremium.exe" - ], - "darwin": [ - "/Applications/Toon Boom Harmony 20 Premium/Harmony Premium.app/Contents/MacOS/Harmony Premium" - ], - "linux": [] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{}" - }, - { - "name": "17", - "label": "17", - "executables": { - "windows": [ - "c:\\Program Files (x86)\\Toon Boom Animation\\Toon Boom Harmony 17 Premium\\win64\\bin\\HarmonyPremium.exe" - ], - "darwin": [ - "/Applications/Toon Boom Harmony 17 Premium/Harmony Premium.app/Contents/MacOS/Harmony Premium" - ], - "linux": [] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{}" - } - ] - }, - "tvpaint": { - "enabled": true, - "label": "TVPaint", - "icon": "{}/app_icons/tvpaint.png", - "host_name": "tvpaint", - "environment": "{}", - "variants": [ - { - "name": "animation_11-64bits", - "label": "11 (64bits)", - "executables": { - "windows": [ - "C:\\Program Files\\TVPaint Developpement\\TVPaint Animation 11 (64bits)\\TVPaint Animation 11 (64bits).exe" - ], - "darwin": [], - "linux": [] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{}" - }, - { - "name": "animation_11-32bits", - "label": "11 (32bits)", - "executables": { - "windows": [ - "C:\\Program Files (x86)\\TVPaint Developpement\\TVPaint Animation 11 (32bits)\\TVPaint Animation 11 (32bits).exe" - ], - "darwin": [], - "linux": [] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{}" - } - ] - }, - "photoshop": { - "enabled": true, - "label": "Photoshop", - "icon": "{}/app_icons/photoshop.png", - "host_name": "photoshop", - "environment": "{\n \"AVALON_PHOTOSHOP_WORKFILES_ON_LAUNCH\": \"1\",\n \"WORKFILES_SAVE_AS\": \"Yes\"\n}", - "variants": [ - { - "name": "2022", - "label": "2022", - "executables": { - "windows": [ - "C:\\Program Files\\Adobe\\Adobe Photoshop 2022\\Photoshop.exe" - ], - "darwin": [], - "linux": [] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{}" - }, - { - "name": "2023", - "label": "2023", - "executables": { - "windows": [ - "C:\\Program Files\\Adobe\\Adobe Photoshop 2023\\Photoshop.exe" - ], - "darwin": [], - "linux": [] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{}" - }, - { - "name": "2024", - "label": "2024", - "executables": { - "windows": [ - "C:\\Program Files\\Adobe\\Adobe Photoshop 2024\\Photoshop.exe" - ], - "darwin": [], - "linux": [] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{}" - } - ] - }, - "aftereffects": { - "enabled": true, - "label": "AfterEffects", - "icon": "{}/app_icons/aftereffects.png", - "host_name": "aftereffects", - "environment": "{\n \"AVALON_AFTEREFFECTS_WORKFILES_ON_LAUNCH\": \"1\",\n \"WORKFILES_SAVE_AS\": \"Yes\"\n}", - "variants": [ - { - "name": "2021", - "label": "2021", - "executables": { - "windows": [ - "C:\\Program Files\\Adobe\\Adobe After Effects 2021\\Support Files\\AfterFX.exe" - ], - "darwin": [], - "linux": [] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{}" - }, - { - "name": "2022", - "label": "2022", - "executables": { - "windows": [ - "C:\\Program Files\\Adobe\\Adobe After Effects 2022\\Support Files\\AfterFX.exe" - ], - "darwin": [], - "linux": [] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{\n \"MULTIPROCESS\": \"No\"\n}" - }, - { - "name": "2023", - "label": "2023", - "executables": { - "windows": [ - "C:\\Program Files\\Adobe\\Adobe After Effects 2023\\Support Files\\AfterFX.exe" - ], - "darwin": [], - "linux": [] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{\n \"MULTIPROCESS\": \"No\"\n}" - }, - { - "name": "2024", - "label": "2024", - "executables": { - "windows": [ - "C:\\Program Files\\Adobe\\Adobe After Effects 2024\\Support Files\\AfterFX.exe" - ], - "darwin": [], - "linux": [] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{\n \"MULTIPROCESS\": \"No\"\n}" - } - ] - }, - "celaction": { - "enabled": true, - "label": "CelAction 2D", - "icon": "app_icons/celaction.png", - "host_name": "celaction", - "environment": "{\n \"CELACTION_TEMPLATE\": \"{OPENPYPE_REPOS_ROOT}/openpype/hosts/celaction/celaction_template_scene.scn\"\n}", - "variants": [ - { - "name": "local", - "label": "local", - "executables": { - "windows": [], - "darwin": [], - "linux": [] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{}" - } - ] - }, - "substancepainter": { - "enabled": true, - "label": "Substance Painter", - "icon": "{}/app_icons/substancepainter.png", - "host_name": "substancepainter", - "environment": "{}", - "variants": [ - { - "name": "stable", - "label": "Stable", - "executables": { - "windows": [ - "C:\\Program Files\\Adobe\\Adobe Substance 3D Painter\\Adobe Substance 3D Painter.exe" - ], - "darwin": [], - "linux": [] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{}" - } - ] - }, - "unreal": { - "enabled": false, - "label": "Unreal Editor", - "icon": "{}/app_icons/ue4.png", - "host_name": "unreal", - "environment": "{}", - "variants": [ - { - "name": "5-0", - "label": "5.0", - "executables": { - "windows": [ - "C:\\Program Files\\Epic Games\\UE_5.0\\Engine\\Binaries\\Win64\\UnrealEditor.exe" - ], - "darwin": [], - "linux": [] - }, - "arguments": {}, - "environment": "{}" - }, - { - "name": "5-1", - "label": "5.1", - "executables": { - "windows": [ - "C:\\Program Files\\Epic Games\\UE_5.1\\Engine\\Binaries\\Win64\\UnrealEditor.exe" - ], - "darwin": [], - "linux": [] - }, - "arguments": {}, - "environment": "{}" - }, - { - "name": "5-2", - "label": "5.2", - "executables": { - "windows": [ - "C:\\Program Files\\Epic Games\\UE_5.2\\Engine\\Binaries\\Win64\\UnrealEditor.exe" - ], - "darwin": [], - "linux": [] - }, - "arguments": {}, - "environment": "{}" - } - ] - }, - "wrap": { - "enabled": true, - "label": "Wrap", - "icon": "{}/app_icons/wrap.png", - "host_name": "wrap", - "environment": "{\n \n}", - "variants": [ - { - "name": "2023", - "use_python_2": false, - "executables": { - "windows": [ - "c:\\Program Files\\Faceform\\Wrap 2023.10.2\\Wrap.exe" - ], - "darwin": [], - "linux": [] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{\n \n}" - } - ] - }, - "openrv": { - "enabled": true, - "label": "OpenRV", - "icon": "{}/app_icons/openrv.png", - "host_name": "openrv", - "environment": "{\n \n}", - "variants": [ - { - "name": "1.0.0", - "use_python_2": false, - "executables": { - "windows": [], - "darwin": [], - "linux": [] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{\n \n}" - } - ] - }, - "zbrush": { - "enabled": true, - "label": "Zbrush", - "icon": "{}/app_icons/zbrush.png", - "host_name": "zbrush", - "environment": "{\n \"ZBRUSH_PLUGIN_PATH\": [\n \"{ZBRUSH_PLUGIN_PATH}\",\n \"{OPENPYPE_STUDIO_PLUGINS}/zbrush/api/zscripts\"\n ]\n}", - "variants": [ - { - "name": "2024", - "use_python_2": false, - "executables": { - "windows": [ - "C:\\Program Files\\Maxon ZBrush 2024\\ZBrush.exe" - ], - "darwin": [], - "linux": [] - }, - "arguments": { - "windows": [], - "darwin": [], - "linux": [] - }, - "environment": "{}" - } - ] - }, - "equalizer": { - "enabled": true, - "label": "3DEqualizer", - "icon": "{}/app_icons/3de4.png", - "host_name": "equalizer", - "environment": "{}", - "variants": [ - { - "name": "7-1v2", - "label": "7.1v2", - "use_python_2": false, - "executables": { - "windows": [ - "C:\\Program Files\\3DE4_win64_r7.1v2\\bin\\3DE4.exe" - ], - "darwin": [], - "linux": [] - }, - "environment": "{}" - } - ] - }, - "motionbuilder": { - "enabled": true, - "label": "Motion Builder", - "icon": "{}/app_icons/motionbuilder.png", - "host_name": "motionbuilder", - "environment": "{}", - "variants": [ - { - "name": "2025", - "label": "2025", - "use_python_2": false, - "executables": { - "windows": [ - "C:\\Program Files\\Autodesk\\MotionBuilder 2025\\bin\\x64\\motionbuilder.exe" - ], - "darwin": [], - "linux": [] - }, - "environment": "{}" - }, - { - "name": "2024", - "label": "2024", - "use_python_2": false, - "executables": { - "windows": [ - "C:\\Program Files\\Autodesk\\MotionBuilder 2024\\bin\\x64\\motionbuilder.exe" - ], - "darwin": [], - "linux": [] - }, - "environment": "{}" - } - ] - }, - "additional_apps": [] - } -} diff --git a/server_addon/applications/server/settings.py b/server_addon/applications/server/settings.py deleted file mode 100644 index 23f37828a6..0000000000 --- a/server_addon/applications/server/settings.py +++ /dev/null @@ -1,233 +0,0 @@ -import json -from pydantic import validator - -from ayon_server.settings import ( - BaseSettingsModel, - SettingsField, - ensure_unique_names, -) -from ayon_server.exceptions import BadRequestException - - -def validate_json_dict(value): - if not value.strip(): - return "{}" - try: - converted_value = json.loads(value) - success = isinstance(converted_value, dict) - except json.JSONDecodeError as exc: - print(exc) - success = False - - if not success: - raise BadRequestException( - "Environment's can't be parsed as json object" - ) - return value - - -class MultiplatformStrList(BaseSettingsModel): - windows: list[str] = SettingsField(default_factory=list, title="Windows") - linux: list[str] = SettingsField(default_factory=list, title="Linux") - darwin: list[str] = SettingsField(default_factory=list, title="MacOS") - - -class AppVariant(BaseSettingsModel): - name: str = SettingsField("", title="Name") - label: str = SettingsField("", title="Label") - executables: MultiplatformStrList = SettingsField( - default_factory=MultiplatformStrList, title="Executables" - ) - arguments: MultiplatformStrList = SettingsField( - default_factory=MultiplatformStrList, title="Arguments" - ) - environment: str = SettingsField( - "{}", title="Environment", widget="textarea" - ) - - @validator("environment") - def validate_json(cls, value): - return validate_json_dict(value) - - -class AppVariantWithPython(AppVariant): - use_python_2: bool = SettingsField(False, title="Use Python 2") - - -class AppGroup(BaseSettingsModel): - enabled: bool = SettingsField(True) - label: str = SettingsField("", title="Label") - host_name: str = SettingsField("", title="Host name") - icon: str = SettingsField("", title="Icon") - environment: str = SettingsField( - "{}", title="Environment", widget="textarea" - ) - - variants: list[AppVariant] = SettingsField( - default_factory=list, - title="Variants", - description="Different variants of the applications", - section="Variants", - ) - - @validator("variants") - def validate_unique_name(cls, value): - ensure_unique_names(value) - return value - - -class AppGroupWithPython(AppGroup): - variants: list[AppVariantWithPython] = SettingsField( - default_factory=list, - title="Variants", - description="Different variants of the applications", - section="Variants", - ) - - -class AdditionalAppGroup(BaseSettingsModel): - enabled: bool = SettingsField(True) - name: str = SettingsField("", title="Name") - label: str = SettingsField("", title="Label") - host_name: str = SettingsField("", title="Host name") - icon: str = SettingsField("", title="Icon") - environment: str = SettingsField( - "{}", title="Environment", widget="textarea" - ) - - variants: list[AppVariantWithPython] = SettingsField( - default_factory=list, - title="Variants", - description="Different variants of the applications", - section="Variants", - ) - - @validator("variants") - def validate_unique_name(cls, value): - ensure_unique_names(value) - return value - - -class ToolVariantModel(BaseSettingsModel): - name: str = SettingsField("", title="Name") - label: str = SettingsField("", title="Label") - host_names: list[str] = SettingsField(default_factory=list, title="Hosts") - # TODO use applications enum if possible - app_variants: list[str] = SettingsField( - default_factory=list, title="Applications" - ) - environment: str = SettingsField( - "{}", title="Environments", widget="textarea" - ) - - @validator("environment") - def validate_json(cls, value): - return validate_json_dict(value) - - -class ToolGroupModel(BaseSettingsModel): - name: str = SettingsField("", title="Name") - label: str = SettingsField("", title="Label") - environment: str = SettingsField( - "{}", title="Environments", widget="textarea" - ) - variants: list[ToolVariantModel] = SettingsField(default_factory=list) - - @validator("environment") - def validate_json(cls, value): - return validate_json_dict(value) - - @validator("variants") - def validate_unique_name(cls, value): - ensure_unique_names(value) - return value - - -class ApplicationsSettings(BaseSettingsModel): - """Applications settings""" - - maya: AppGroupWithPython = SettingsField( - default_factory=AppGroupWithPython, title="Autodesk Maya") - adsk_3dsmax: AppGroupWithPython = SettingsField( - default_factory=AppGroupWithPython, title="Autodesk 3ds Max") - flame: AppGroupWithPython = SettingsField( - default_factory=AppGroupWithPython, title="Autodesk Flame") - nuke: AppGroupWithPython = SettingsField( - default_factory=AppGroupWithPython, title="Nuke") - nukeassist: AppGroupWithPython = SettingsField( - default_factory=AppGroupWithPython, title="Nuke Assist") - nukex: AppGroupWithPython = SettingsField( - default_factory=AppGroupWithPython, title="Nuke X") - nukestudio: AppGroupWithPython = SettingsField( - default_factory=AppGroupWithPython, title="Nuke Studio") - hiero: AppGroupWithPython = SettingsField( - default_factory=AppGroupWithPython, title="Hiero") - fusion: AppGroup = SettingsField( - default_factory=AppGroupWithPython, title="Fusion") - resolve: AppGroupWithPython = SettingsField( - default_factory=AppGroupWithPython, title="Resolve") - houdini: AppGroupWithPython = SettingsField( - default_factory=AppGroupWithPython, title="Houdini") - blender: AppGroup = SettingsField( - default_factory=AppGroupWithPython, title="Blender") - harmony: AppGroup = SettingsField( - default_factory=AppGroupWithPython, title="Harmony") - tvpaint: AppGroup = SettingsField( - default_factory=AppGroupWithPython, title="TVPaint") - photoshop: AppGroup = SettingsField( - default_factory=AppGroupWithPython, title="Adobe Photoshop") - aftereffects: AppGroup = SettingsField( - default_factory=AppGroupWithPython, title="Adobe After Effects") - celaction: AppGroup = SettingsField( - default_factory=AppGroupWithPython, title="Celaction 2D") - substancepainter: AppGroup = SettingsField( - default_factory=AppGroupWithPython, title="Substance Painter") - unreal: AppGroup = SettingsField( - default_factory=AppGroupWithPython, title="Unreal Editor") - wrap: AppGroup = SettingsField( - default_factory=AppGroupWithPython, title="Wrap") - openrv: AppGroup = SettingsField( - default_factory=AppGroupWithPython, title="OpenRV") - zbrush: AppGroup = SettingsField( - default_factory=AppGroupWithPython, title="Zbrush") - equalizer: AppGroup = SettingsField( - default_factory=AppGroupWithPython, title="3DEqualizer") - motionbuilder: AppGroup = SettingsField( - default_factory=AppGroupWithPython, title="Motion Builder") - additional_apps: list[AdditionalAppGroup] = SettingsField( - default_factory=list, title="Additional Applications") - - @validator("additional_apps") - def validate_unique_name(cls, value): - ensure_unique_names(value) - return value - - -class ApplicationsAddonSettings(BaseSettingsModel): - applications: ApplicationsSettings = SettingsField( - default_factory=ApplicationsSettings, - title="Applications", - scope=["studio"] - ) - tool_groups: list[ToolGroupModel] = SettingsField( - default_factory=list, - scope=["studio"] - ) - only_available: bool = SettingsField( - True, - title="Show only available applications", - description="Enable to show only applications in AYON Launcher" - " for which the executable paths are found on the running machine." - " This applies as an additional filter to the applications defined in a " - " project's anatomy settings to ignore unavailable applications." - ) - - @validator("tool_groups") - def validate_unique_name(cls, value): - ensure_unique_names(value) - return value - - -DEFAULT_VALUES = { - "only_available": True -} diff --git a/server_addon/applications/server/tools.json b/server_addon/applications/server/tools.json deleted file mode 100644 index 3d8f400200..0000000000 --- a/server_addon/applications/server/tools.json +++ /dev/null @@ -1,149 +0,0 @@ -{ - "tool_groups": [ - { - "name": "htoa", - "label": "Arnold for Houdini (example)", - "variants": [ - { - "name": "5-4-2-7", - "label": "", - "host_names": [ - "houdini" - ], - "environment": "{\n \"HTOA_VERSION\": \"5.4.2.7\"\n}", - "app_variants": [] - } - ], - "environment": "{\n \"_comment_\": \"{STUDIO_SW} points to software repository. Can be defined in Core addon globally\",\n\n \"HOUDINI_PATH\": [\n \"{STUDIO_SW}/APP/HTOA/{HTOA_VERSION}/HOUDINI{HOUDINI_VERSION}/WINDOWS/htoa-6.1.3.3_rdb15014_houdini-{HTOA_VERSION}\",\n \"{HOUDINI_PATH}\"\n ],\n \"PATH\": {\n \"windows\": [\n \"{STUDIO_SW}/APP/HTOA/{HTOA_VERSION}/HOUDINI{HOUDINI_VERSION}/WINDOWS/htoa-6.1.3.3_rdb15014_houdini-{HTOA_VERSION}/scripts/bin\",\n \"{PATH}\"\n ]\n }\n}" - }, - { - "name": "mtoa", - "label": "Arnold for Maya (example)", - "variants": [ - { - "name": "5-3-1-0", - "label": "", - "host_names": [], - "environment": "{\n \"MTOA_VERSION\": \"5.3.1.0\"\n}", - "app_variants": [] - }, - { - "name": "5-3-4-1", - "label": "", - "host_names": [], - "environment": "{\n \"MTOA_VERSION\": \"5.3.4.1\"\n}", - "app_variants": [] - } - ], - "environment": "{\n \"_comment_\": \"{STUDIO_SW} points to software repository. Can be defined in Core addon globally\",\n\n \"MTOA\": {\n \"darwin\": \"{STUDIO_SW}/APP/MTOA/{MTOA_VERSION}/MAYA{MAYA_VERSION}/MAC\",\n \"linux\": \"{STUDIO_SW}/APP/MTOA/{MTOA_VERSION}/MAYA{MAYA_VERSION}/LINUX\",\n \"windows\": \"{STUDIO_SW}/APP/MTOA/{MTOA_VERSION}/MAYA{MAYA_VERSION}/WINDOWS\"\n },\n \"MAYA_MODULE_PATH\": [\n \"{STUDIO_SW}/APP/MTOA\",\n \"{MAYA_MODULE_PATH}\"\n ],\n \"DYLD_LIBRARY_PATH\": {\n \"darwin\": \"{MTOA}/bin\"\n },\n \"PATH\": {\n \"windows\": [\n \"{MTOA}/bin\",\n \"{PATH}\"\n ]\n },\n \"XBMLANGPATH\": [\n \"{MTOA}/icons\",\n \"{XBMLANGPATH}\"\n ],\n \"MAYA_RENDER_DESC_PATH\": [\n \"{MTOA}\",\n \"{MAYA_RENDER_DESC_PATH}\"\n ],\n \"MTOA_STARTUP_LOG_VERBOSITY\": \"3\"\n}" - }, - { - "name": "redshiftMaya", - "label": "Redshift for Maya (example)", - "variants": [ - { - "name": "3-5-23", - "label": "", - "host_names": [], - "environment": "{\n \"REDSHIFT_VERSION\": \"3.5.23\"\n}", - "app_variants": [] - } - ], - "environment": "{\n \"_comment_\": \"{STUDIO_SW} points to software repository. Can be defined in Core addon globally\",\n\n \"REDSHIFT_COREDATAPATH\": {\n \"darwin\": \"{STUDIO_SW}/APP/REDSHIFT/{REDSHIFT_VERSION}/MAC\",\n \"linux\": \"{STUDIO_SW}/APP/REDSHIFT/{REDSHIFT_VERSION}/LINUX\",\n \"windows\": \"{STUDIO_SW}/APP/REDSHIFT/{REDSHIFT_VERSION}/WINDOWS\"\n },\n \"REDSHIFT_ABORTONLICENSEFAIL\": \"0\",\n \"MAYA_MODULE_PATH\": [\n \"{STUDIO_SW}/APP/REDSHIFT\",\n \"{MAYA_MODULE_PATH}\"\n ],\n \"MAYA_PLUG_IN_PATH\": {\n \"windows\": [\n \"{REDSHIFT_COREDATAPATH}/Plugins/Maya/{MAYA_VERSION}/nt-x86-64\",\n \"{MAYA_PLUG_IN_PATH}\"\n ],\n \"linux\": [\n \"{REDSHIFT_COREDATAPATH}/redshift4maya/{MAYA_VERSION}\",\n \"{MAYA_PLUG_IN_PATH}\"\n ],\n \"darwin\": [\n \"{REDSHIFT_COREDATAPATH}/redshift4maya/{MAYA_VERSION}\",\n \"{MAYA_PLUG_IN_PATH}\"\n ]\n },\n \"MAYA_SCRIPT_PATH\": {\n \"windows\": [\n \"{REDSHIFT_COREDATAPATH}/Plugins/Maya/Common/scripts\",\n \"{MAYA_SCRIPT_PATH}\"\n ],\n \"linux\": [\n \"{REDSHIFT_COREDATAPATH}/redshift4maya/common/scripts\",\n \"{MAYA_SCRIPT_PATH}\"\n ],\n \"darwin\": [\n \"{REDSHIFT_COREDATAPATH}/redshift4maya/common/scripts\",\n \"{MAYA_SCRIPT_PATH}\"\n ]\n },\n \"REDSHIFT_PROCEDURALSPATH\": {\n \"windows\": [\n \"{REDSHIFT_COREDATAPATH}/Procedurals\",\n \"{REDSHIFT_PROCEDURALSPATH}\"\n ],\n \"linux\": [\n \"{REDSHIFT_COREDATAPATH}/procedurals\",\n \"{REDSHIFT_PROCEDURALSPATH}\"\n ],\n \"darwin\": [\n \"{REDSHIFT_COREDATAPATH}/procedurals\",\n \"{REDSHIFT_PROCEDURALSPATH}\"\n ]\n },\n \"REDSHIFT_MAYAEXTENSIONSPATH\": {\n \"windows\": [\n \"{REDSHIFT_COREDATAPATH}/Plugins/Maya/{MAYA_VERSION}/nt-x86-64/extensions\",\n \"{REDSHIFT_MAYAEXTENSIONSPATH}\"\n ],\n \"linux\": [\n \"{REDSHIFT_COREDATAPATH}/redshift4maya/{MAYA_VERSION}/extensions\",\n \"{REDSHIFT_MAYAEXTENSIONSPATH}\"\n ],\n \"darwin\": [\n \"{REDSHIFT_COREDATAPATH}/redshift4maya/{MAYA_VERSION}/extensions\",\n \"{REDSHIFT_MAYAEXTENSIONSPATH}\"\n ]\n },\n \"XBMLANGPATH\": {\n \"windows\": [\n \"{REDSHIFT_COREDATAPATH}/Plugins/Maya/Common/icons\",\n \"{XBMLANGPATH}\"\n ],\n \"linux\": [\n \"{REDSHIFT_COREDATAPATH}/redshift4maya/common/icons\",\n \"{XBMLANGPATH}\"\n ],\n \"darwin\": [\n \"{REDSHIFT_COREDATAPATH}/redshift4maya/common/icons\",\n \"{XBMLANGPATH}\"\n ]\n },\n \"MAYA_RENDER_DESC_PATH\": {\n \"windows\": [\n \"{REDSHIFT_COREDATAPATH}/Plugins/Maya/Common/rendererDesc\",\n \"{MAYA_RENDER_DESC_PATH}\"\n ],\n \"linux\": [\n \"{REDSHIFT_COREDATAPATH}/redshift4maya/common/rendererDesc\",\n \"{MAYA_RENDER_DESC_PATH}\"\n ],\n \"darwin\": [\n \"{REDSHIFT_COREDATAPATH}/redshift4maya/common/rendererDesc\",\n \"{MAYA_RENDER_DESC_PATH}\"\n ]\n },\n \"MAYA_CUSTOM_TEMPLATE_PATH\": {\n \"windows\": [\n \"{REDSHIFT_COREDATAPATH}/Plugins/Maya/Common/scripts/NETemplates\",\n \"{MAYA_CUSTOM_TEMPLATE_PATH}\"\n ],\n \"linux\": [\n \"{REDSHIFT_COREDATAPATH}/redshift4maya/common/scripts/NETemplates\",\n \"{MAYA_CUSTOM_TEMPLATE_PATH}\"\n ],\n \"darwin\": [\n \"{REDSHIFT_COREDATAPATH}/redshift4maya/common/scripts/NETemplates\",\n \"{MAYA_CUSTOM_TEMPLATE_PATH}\"\n ]\n },\n \"PATH\": {\n \"windows\": [\n \"{REDSHIFT_COREDATAPATH}/bin\",\n \"{PATH}\"\n ]\n }\n}" - }, - { - "name": "redshift3dsmax", - "label": "Redshift for 3dsmax (example)", - "variants": [ - { - "name": "3-5-19", - "label": "", - "host_names": [ - "max" - ], - "environment": "{\n \"REDSHIFT_VERSION\": \"3.5.19\"\n}", - "app_variants": [] - } - ], - "environment": "{\n \"_comment_\": \"{STUDIO_SW} points to software repository. Can be defined in Core addon globally\",\n\n \"REDSHIFT_COREDATAPATH\": {\n \"darwin\": \"{STUDIO_SW}/APP/REDSHIFT/{REDSHIFT_VERSION}/MAC\",\n \"linux\": \"{STUDIO_SW}/APP/REDSHIFT/{REDSHIFT_VERSION}/LINUX\",\n \"windows\": \"{STUDIO_SW}/APP/REDSHIFT/{REDSHIFT_VERSION}/WINDOWS\"\n },\n \"REDSHIFT_ABORTONLICENSEFAIL\": \"0\",\n \"REDSHIFT_PROCEDURALSPATH\": {\n \"windows\": [\n \"{REDSHIFT_COREDATAPATH}/Procedurals\",\n \"{REDSHIFT_PROCEDURALSPATH}\"\n ],\n \"linux\": [\n \"{REDSHIFT_COREDATAPATH}/procedurals\",\n \"{REDSHIFT_PROCEDURALSPATH}\"\n ],\n \"darwin\": [\n \"{REDSHIFT_COREDATAPATH}/procedurals\",\n \"{REDSHIFT_PROCEDURALSPATH}\"\n ]\n },\n \"PATH\": {\n \"windows\": [\n \"{REDSHIFT_COREDATAPATH}/bin\",\n \"{PATH}\"\n ]\n }\n}" - }, - { - "name": "rendermanMaya", - "label": "Renderman for Maya (example)", - "variants": [ - { - "name": "24-3-maya", - "label": "24.3 RFM", - "host_names": [ - "maya" - ], - "environment": "{\n \"RFMTREE\": {\n \"windows\": \"C:\\\\Program Files\\\\Pixar\\\\RenderManForMaya-24.3\",\n \"darwin\": \"/Applications/Pixar/RenderManForMaya-24.3\",\n \"linux\": \"/opt/pixar/RenderManForMaya-24.3\"\n },\n \"RMANTREE\": {\n \"windows\": \"C:\\\\Program Files\\\\Pixar\\\\RenderManProServer-24.3\",\n \"darwin\": \"/Applications/Pixar/RenderManProServer-24.3\",\n \"linux\": \"/opt/pixar/RenderManProServer-24.3\"\n }\n}", - "app_variants": [ - "maya/2022" - ] - } - ], - "environment": "{\n \"_comment_\": \"{STUDIO_SW} points to software repository. Can be defined in Core addon globally\",\n\n \"RFMTREE\": {\n \"darwin\": \"{STUDIO_SW}/APP/RENDERMAN/{RM_VERSION}/MAC/MAYA\",\n \"linux\": \"{STUDIO_SW}/APP/RENDERMAN/{RM_VERSION}/LINUX/MAYA\",\n \"windows\": \"{STUDIO_SW}/APP/RENDERMAN/{RM_VERSION}/WINDOWS/MAYA\"\n },\n \"RMANTREE\": {\n \"darwin\": \"{STUDIO_SW}/APP/RENDERMAN/{RM_VERSION}/MAC/RenderManProServer-{RM_VERSION}\",\n \"linux\": \"{STUDIO_SW}/APP/RENDERMAN/{RM_VERSION}/LINUX/RenderManProServer-{RM_VERSION}\",\n \"windows\": \"{STUDIO_SW}/APP/RENDERMAN/{RM_VERSION}/WINDOWS/RenderManProServer-{RM_VERSION}\"\n },\n \"MAYA_MODULE_PATH\": [\n \"{STUDIO_SW}/APP/RENDERMAN\",\n \"{MAYA_MODULE_PATH}\"\n ],\n \"PIXAR_LICENSE_FILE\": \"{STUDIO_SW}/APP/RENDERMAN/pixar.license\",\n \"RFM_DO_NOT_CREATE_MODULE_FILE\": \"1\"\n}" - }, - { - "name": "mGear", - "label": "mGear for Maya (example)", - "variants": [ - { - "name": "4-0-7", - "label": "", - "host_names": [], - "environment": "{\n \"MGEAR_VERSION\": \"4.0.7\"\n}", - "app_variants": [] - } - ], - "environment": "{\n \"_comment_\": \"{STUDIO_SW} points to software repository. Can be defined in Core addon globally\",\n\n \"MGEAR_ROOT\": \"{STUDIO_SW}/APP/MGEAR/{MGEAR_VERSION}/MAYA{MAYA_VERSION}/windows/x64\",\n \"MAYA_MODULE_PATH\": [\n \"{STUDIO_SW}/APP/MGEAR/{MGEAR_VERSION}/release\",\n \"{MAYA_MODULE_PATH}\"\n ]\n}" - }, - { - "name": "yetiMaya", - "label": "Yeti for Maya (example)", - "variants": [ - { - "name": "4.2.11", - "label": "", - "host_names": [], - "environment": "{\n \"YETI_VERSION\": \"4.2.11\"\n}", - "app_variants": [] - } - ], - "environment": "{\n \"_comment_\": \"{STUDIO_SW} points to software repository. Can be defined in Core addon globally\",\n\n \"YETI_HOME\": {\n \"darwin\": \"{STUDIO_SW}/APP/YETI/{YETI_VERSION}/MAYA{MAYA_VERSION}/MAC\",\n \"linux\": \"{STUDIO_SW}/APP/YETI/{YETI_VERSION}/MAYA{MAYA_VERSION}/LINUX\",\n \"windows\": \"{STUDIO_SW}/APP/YETI/{YETI_VERSION}/MAYA{MAYA_VERSION}/WINDOWS\"\n },\n \"YETI_TMP\": {\n \"windows\": \"C:/temp\",\n \"darwin\": \"/tmp\",\n \"linux\": \"/tmp\"\n },\n \"peregrinel_LICENSE\": \"4202@35.158.197.250\",\n \"MAYA_MODULE_PATH\": [\n \"{STUDIO_SW}/APP/YETI\",\n \"{MAYA_MODULE_PATH}\"\n ]\n}" - }, - { - "name": "vrayMaya", - "label": "Vray for Maya (example)", - "variants": [ - { - "name": "6.10.01", - "label": "", - "host_names": [ - "" - ], - "environment": "{\n \"VRAY_VERSION\": \"6.10.01\"\n}", - "app_variants": [] - } - ], - "environment": "{\n \"_comment_\": \"{STUDIO_SW} points to software repository. Can be defined in Core addon globally\",\n\n \"MAYA_MODULE_PATH\": {\n \"windows\": [\n \"{STUDIO_SW}/APP/VRAY/{VRAY_VERSION}/MAYA{MAYA_VERSION}/WINDOWS/maya_root/modules\",\n \"{MAYA_MODULE_PATH}\"\n ],\n \"linux\": [\n \"{STUDIO_SW}/APP/VRAY/{VRAY_VERSION}/MAYA{MAYA_VERSION}/LINUX/maya_root/modules\",\n \"{MAYA_MODULE_PATH}\"\n ],\n \"darwin\": [\n \"{STUDIO_SW}/APP/VRAY/{VRAY_VERSION}/MAYA{MAYA_VERSION}/MAC/maya_root/modules\",\n \"{MAYA_MODULE_PATH}\"\n ]\n },\n \"VRAY_AUTH_CLIENT_FILE_PATH\": \"{STUDIO_SW}/APP/VRAY\"\n}" - }, - { - "name": "vraynuke", - "label": "Vray for Nuke (example)", - "variants": [ - { - "name": "5-20-00", - "label": "", - "host_names": [ - "nuke" - ], - "environment": "{\n \"VRAYNUKE_VERSION\": \"5.20.00\"\n}", - "app_variants": [] - } - ], - "environment": "{\n \"_comment_\": \"{STUDIO_SW} points to software repository. Can be defined in Core addon globally\",\n\n \"VRAY_FOR_NUKE_13_0_PLUGINS\": {\n \"windows\": \"{STUDIO_SW}/APP/VRAYNUKE/{VRAYNUKE_VERSION}/NUKE{NUKE_VRAY_VERSION}/WINDOWS/nuke_vray/plugins/vray\"\n },\n \"NUKE_PATH\": {\n \"windows\": [\n \"{STUDIO_SW}/APP/VRAYNUKE/{VRAYNUKE_VERSION}/NUKE{NUKE_VRAY_VERSION}/WINDOWS/nuke_root\",\n \"{NUKE_PATH}\"\n ]\n },\n \"PATH\": {\n \"windows\": [\n \"{STUDIO_SW}/APP/VRAYNUKE/{VRAYNUKE_VERSION}/NUKE{NUKE_VRAY_VERSION}/WINDOWS/nuke_vray\",\n \"{PATH}\"\n ]\n },\n \"VRAY_AUTH_CLIENT_FILE_PATH\": \"{STUDIO_SW}/APP/VRAY\"\n}" - } - ] -} \ No newline at end of file diff --git a/server_addon/fusion/client/ayon_fusion/__init__.py b/server_addon/fusion/client/ayon_fusion/__init__.py deleted file mode 100644 index f2ddccdd87..0000000000 --- a/server_addon/fusion/client/ayon_fusion/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -from .version import __version__ -from .addon import ( - get_fusion_version, - FusionAddon, - FUSION_ADDON_ROOT, - FUSION_VERSIONS_DICT, -) - - -__all__ = ( - "__version__", - - "get_fusion_version", - "FusionAddon", - "FUSION_ADDON_ROOT", - "FUSION_VERSIONS_DICT", -) diff --git a/server_addon/fusion/client/ayon_fusion/addon.py b/server_addon/fusion/client/ayon_fusion/addon.py deleted file mode 100644 index ffc70b6ff4..0000000000 --- a/server_addon/fusion/client/ayon_fusion/addon.py +++ /dev/null @@ -1,72 +0,0 @@ -import os -import re -from ayon_core.addon import AYONAddon, IHostAddon -from ayon_core.lib import Logger - -from .version import __version__ - -FUSION_ADDON_ROOT = os.path.dirname(os.path.abspath(__file__)) - -# FUSION_VERSIONS_DICT is used by the pre-launch hooks -# The keys correspond to all currently supported Fusion versions -# Each value is a list of corresponding Python home variables and a profile -# number, which is used by the profile hook to set Fusion profile variables. -FUSION_VERSIONS_DICT = { - 9: ("FUSION_PYTHON36_HOME", 9), - 16: ("FUSION16_PYTHON36_HOME", 16), - 17: ("FUSION16_PYTHON36_HOME", 16), - 18: ("FUSION_PYTHON3_HOME", 16), -} - - -def get_fusion_version(app_name): - """ - The function is triggered by the prelaunch hooks to get the fusion version. - - `app_name` is obtained by prelaunch hooks from the - `launch_context.env.get("AYON_APP_NAME")`. - - To get a correct Fusion version, a version number should be present - in the `applications/fusion/variants` key - of the Blackmagic Fusion Application Settings. - """ - - log = Logger.get_logger(__name__) - - if not app_name: - return - - app_version_candidates = re.findall(r"\d+", app_name) - if not app_version_candidates: - return - for app_version in app_version_candidates: - if int(app_version) in FUSION_VERSIONS_DICT: - return int(app_version) - else: - log.info( - "Unsupported Fusion version: {app_version}".format( - app_version=app_version - ) - ) - - -class FusionAddon(AYONAddon, IHostAddon): - name = "fusion" - version = __version__ - host_name = "fusion" - - def get_launch_hook_paths(self, app): - if app.host_name != self.host_name: - return [] - return [os.path.join(FUSION_ADDON_ROOT, "hooks")] - - def add_implementation_envs(self, env, app): - # Set default values if are not already set via settings - - defaults = {"AYON_LOG_NO_COLORS": "1"} - for key, value in defaults.items(): - if not env.get(key): - env[key] = value - - def get_workfile_extensions(self): - return [".comp"] diff --git a/server_addon/fusion/client/ayon_fusion/api/__init__.py b/server_addon/fusion/client/ayon_fusion/api/__init__.py deleted file mode 100644 index d2feee6d23..0000000000 --- a/server_addon/fusion/client/ayon_fusion/api/__init__.py +++ /dev/null @@ -1,39 +0,0 @@ -from .pipeline import ( - FusionHost, - ls, - - imprint_container, - parse_container -) - -from .lib import ( - maintained_selection, - update_frame_range, - set_current_context_framerange, - get_current_comp, - get_bmd_library, - comp_lock_and_undo_chunk -) - -from .menu import launch_ayon_menu - - -__all__ = [ - # pipeline - "FusionHost", - "ls", - - "imprint_container", - "parse_container", - - # lib - "maintained_selection", - "update_frame_range", - "set_current_context_framerange", - "get_current_comp", - "get_bmd_library", - "comp_lock_and_undo_chunk", - - # menu - "launch_ayon_menu", -] diff --git a/server_addon/fusion/client/ayon_fusion/api/action.py b/server_addon/fusion/client/ayon_fusion/api/action.py deleted file mode 100644 index 02cd96f56c..0000000000 --- a/server_addon/fusion/client/ayon_fusion/api/action.py +++ /dev/null @@ -1,112 +0,0 @@ -import pyblish.api - - -from ayon_fusion.api.lib import get_current_comp -from ayon_core.pipeline.publish import get_errored_instances_from_context - - -class SelectInvalidAction(pyblish.api.Action): - """Select invalid nodes in Fusion when plug-in failed. - - To retrieve the invalid nodes this assumes a static `get_invalid()` - method is available on the plugin. - - """ - - label = "Select invalid" - on = "failed" # This action is only available on a failed plug-in - icon = "search" # Icon from Awesome Icon - - def process(self, context, plugin): - errored_instances = get_errored_instances_from_context( - context, - plugin=plugin, - ) - - # Get the invalid nodes for the plug-ins - self.log.info("Finding invalid nodes..") - invalid = list() - for instance in errored_instances: - invalid_nodes = plugin.get_invalid(instance) - if invalid_nodes: - if isinstance(invalid_nodes, (list, tuple)): - invalid.extend(invalid_nodes) - else: - self.log.warning( - "Plug-in returned to be invalid, " - "but has no selectable nodes." - ) - - if not invalid: - # Assume relevant comp is current comp and clear selection - self.log.info("No invalid tools found.") - comp = get_current_comp() - flow = comp.CurrentFrame.FlowView - flow.Select() # No args equals clearing selection - return - - # Assume a single comp - first_tool = invalid[0] - comp = first_tool.Comp() - flow = comp.CurrentFrame.FlowView - flow.Select() # No args equals clearing selection - names = set() - for tool in invalid: - flow.Select(tool, True) - comp.SetActiveTool(tool) - names.add(tool.Name) - self.log.info( - "Selecting invalid tools: %s" % ", ".join(sorted(names)) - ) - - -class SelectToolAction(pyblish.api.Action): - """Select invalid output tool in Fusion when plug-in failed. - - """ - - label = "Select saver" - on = "failed" # This action is only available on a failed plug-in - icon = "search" # Icon from Awesome Icon - - def process(self, context, plugin): - errored_instances = get_errored_instances_from_context( - context, - plugin=plugin, - ) - - # Get the invalid nodes for the plug-ins - self.log.info("Finding invalid nodes..") - tools = [] - for instance in errored_instances: - - tool = instance.data.get("tool") - if tool is not None: - tools.append(tool) - else: - self.log.warning( - "Plug-in returned to be invalid, " - f"but has no saver for instance {instance.name}." - ) - - if not tools: - # Assume relevant comp is current comp and clear selection - self.log.info("No invalid tools found.") - comp = get_current_comp() - flow = comp.CurrentFrame.FlowView - flow.Select() # No args equals clearing selection - return - - # Assume a single comp - first_tool = tools[0] - comp = first_tool.Comp() - flow = comp.CurrentFrame.FlowView - flow.Select() # No args equals clearing selection - names = set() - for tool in tools: - flow.Select(tool, True) - comp.SetActiveTool(tool) - names.add(tool.Name) - self.log.info( - "Selecting invalid tools: %s" % ", ".join(sorted(names)) - ) diff --git a/server_addon/fusion/client/ayon_fusion/api/lib.py b/server_addon/fusion/client/ayon_fusion/api/lib.py deleted file mode 100644 index 7f7d20010d..0000000000 --- a/server_addon/fusion/client/ayon_fusion/api/lib.py +++ /dev/null @@ -1,402 +0,0 @@ -import os -import sys -import re -import contextlib - -from ayon_core.lib import Logger, BoolDef, UILabelDef -from ayon_core.style import load_stylesheet -from ayon_core.pipeline import registered_host -from ayon_core.pipeline.create import CreateContext -from ayon_core.pipeline.context_tools import get_current_folder_entity - -self = sys.modules[__name__] -self._project = None - - -def update_frame_range(start, end, comp=None, set_render_range=True, - handle_start=0, handle_end=0): - """Set Fusion comp's start and end frame range - - Args: - start (float, int): start frame - end (float, int): end frame - comp (object, Optional): comp object from fusion - set_render_range (bool, Optional): When True this will also set the - composition's render start and end frame. - handle_start (float, int, Optional): frame handles before start frame - handle_end (float, int, Optional): frame handles after end frame - - Returns: - None - - """ - - if not comp: - comp = get_current_comp() - - # Convert any potential none type to zero - handle_start = handle_start or 0 - handle_end = handle_end or 0 - - attrs = { - "COMPN_GlobalStart": start - handle_start, - "COMPN_GlobalEnd": end + handle_end - } - - # set frame range - if set_render_range: - attrs.update({ - "COMPN_RenderStart": start, - "COMPN_RenderEnd": end - }) - - with comp_lock_and_undo_chunk(comp): - comp.SetAttrs(attrs) - - -def set_current_context_framerange(folder_entity=None): - """Set Comp's frame range based on current folder.""" - if folder_entity is None: - folder_entity = get_current_folder_entity( - fields={"attrib.frameStart", - "attrib.frameEnd", - "attrib.handleStart", - "attrib.handleEnd"}) - - folder_attributes = folder_entity["attrib"] - start = folder_attributes["frameStart"] - end = folder_attributes["frameEnd"] - handle_start = folder_attributes["handleStart"] - handle_end = folder_attributes["handleEnd"] - update_frame_range(start, end, set_render_range=True, - handle_start=handle_start, - handle_end=handle_end) - - -def set_current_context_fps(folder_entity=None): - """Set Comp's frame rate (FPS) to based on current asset""" - if folder_entity is None: - folder_entity = get_current_folder_entity(fields={"attrib.fps"}) - - fps = float(folder_entity["attrib"].get("fps", 24.0)) - comp = get_current_comp() - comp.SetPrefs({ - "Comp.FrameFormat.Rate": fps, - }) - - -def set_current_context_resolution(folder_entity=None): - """Set Comp's resolution width x height default based on current folder""" - if folder_entity is None: - folder_entity = get_current_folder_entity( - fields={"attrib.resolutionWidth", "attrib.resolutionHeight"}) - - folder_attributes = folder_entity["attrib"] - width = folder_attributes["resolutionWidth"] - height = folder_attributes["resolutionHeight"] - comp = get_current_comp() - - print("Setting comp frame format resolution to {}x{}".format(width, - height)) - comp.SetPrefs({ - "Comp.FrameFormat.Width": width, - "Comp.FrameFormat.Height": height, - }) - - -def validate_comp_prefs(comp=None, force_repair=False): - """Validate current comp defaults with folder settings. - - Validates fps, resolutionWidth, resolutionHeight, aspectRatio. - - This does *not* validate frameStart, frameEnd, handleStart and handleEnd. - """ - - if comp is None: - comp = get_current_comp() - - log = Logger.get_logger("validate_comp_prefs") - - fields = { - "path", - "attrib.fps", - "attrib.resolutionWidth", - "attrib.resolutionHeight", - "attrib.pixelAspect", - } - folder_entity = get_current_folder_entity(fields=fields) - folder_path = folder_entity["path"] - folder_attributes = folder_entity["attrib"] - - comp_frame_format_prefs = comp.GetPrefs("Comp.FrameFormat") - - # Pixel aspect ratio in Fusion is set as AspectX and AspectY so we convert - # the data to something that is more sensible to Fusion - folder_attributes["pixelAspectX"] = folder_attributes.pop("pixelAspect") - folder_attributes["pixelAspectY"] = 1.0 - - validations = [ - ("fps", "Rate", "FPS"), - ("resolutionWidth", "Width", "Resolution Width"), - ("resolutionHeight", "Height", "Resolution Height"), - ("pixelAspectX", "AspectX", "Pixel Aspect Ratio X"), - ("pixelAspectY", "AspectY", "Pixel Aspect Ratio Y") - ] - - invalid = [] - for key, comp_key, label in validations: - folder_value = folder_attributes[key] - comp_value = comp_frame_format_prefs.get(comp_key) - if folder_value != comp_value: - invalid_msg = "{} {} should be {}".format(label, - comp_value, - folder_value) - invalid.append(invalid_msg) - - if not force_repair: - # Do not log warning if we force repair anyway - log.warning( - "Comp {pref} {value} does not match folder " - "'{folder_path}' {pref} {folder_value}".format( - pref=label, - value=comp_value, - folder_path=folder_path, - folder_value=folder_value) - ) - - if invalid: - - def _on_repair(): - attributes = dict() - for key, comp_key, _label in validations: - value = folder_attributes[key] - comp_key_full = "Comp.FrameFormat.{}".format(comp_key) - attributes[comp_key_full] = value - comp.SetPrefs(attributes) - - if force_repair: - log.info("Applying default Comp preferences..") - _on_repair() - return - - from . import menu - from ayon_core.tools.utils import SimplePopup - dialog = SimplePopup(parent=menu.menu) - dialog.setWindowTitle("Fusion comp has invalid configuration") - - msg = "Comp preferences mismatches '{}'".format(folder_path) - msg += "\n" + "\n".join(invalid) - dialog.set_message(msg) - dialog.set_button_text("Repair") - dialog.on_clicked.connect(_on_repair) - dialog.show() - dialog.raise_() - dialog.activateWindow() - dialog.setStyleSheet(load_stylesheet()) - - -@contextlib.contextmanager -def maintained_selection(comp=None): - """Reset comp selection from before the context after the context""" - if comp is None: - comp = get_current_comp() - - previous_selection = comp.GetToolList(True).values() - try: - yield - finally: - flow = comp.CurrentFrame.FlowView - flow.Select() # No args equals clearing selection - if previous_selection: - for tool in previous_selection: - flow.Select(tool, True) - - -@contextlib.contextmanager -def maintained_comp_range(comp=None, - global_start=True, - global_end=True, - render_start=True, - render_end=True): - """Reset comp frame ranges from before the context after the context""" - if comp is None: - comp = get_current_comp() - - comp_attrs = comp.GetAttrs() - preserve_attrs = {} - if global_start: - preserve_attrs["COMPN_GlobalStart"] = comp_attrs["COMPN_GlobalStart"] - if global_end: - preserve_attrs["COMPN_GlobalEnd"] = comp_attrs["COMPN_GlobalEnd"] - if render_start: - preserve_attrs["COMPN_RenderStart"] = comp_attrs["COMPN_RenderStart"] - if render_end: - preserve_attrs["COMPN_RenderEnd"] = comp_attrs["COMPN_RenderEnd"] - - try: - yield - finally: - comp.SetAttrs(preserve_attrs) - - -def get_frame_path(path): - """Get filename for the Fusion Saver with padded number as '#' - - >>> get_frame_path("C:/test.exr") - ('C:/test', 4, '.exr') - - >>> get_frame_path("filename.00.tif") - ('filename.', 2, '.tif') - - >>> get_frame_path("foobar35.tif") - ('foobar', 2, '.tif') - - Args: - path (str): The path to render to. - - Returns: - tuple: head, padding, tail (extension) - - """ - filename, ext = os.path.splitext(path) - - # Find a final number group - match = re.match('.*?([0-9]+)$', filename) - if match: - padding = len(match.group(1)) - # remove number from end since fusion - # will swap it with the frame number - filename = filename[:-padding] - else: - padding = 4 # default Fusion padding - - return filename, padding, ext - - -def get_fusion_module(): - """Get current Fusion instance""" - fusion = getattr(sys.modules["__main__"], "fusion", None) - return fusion - - -def get_bmd_library(): - """Get bmd library""" - bmd = getattr(sys.modules["__main__"], "bmd", None) - return bmd - - -def get_current_comp(): - """Get current comp in this session""" - fusion = get_fusion_module() - if fusion is not None: - comp = fusion.CurrentComp - return comp - - -@contextlib.contextmanager -def comp_lock_and_undo_chunk( - comp, - undo_queue_name="Script CMD", - keep_undo=True, -): - """Lock comp and open an undo chunk during the context""" - try: - comp.Lock() - comp.StartUndo(undo_queue_name) - yield - finally: - comp.Unlock() - comp.EndUndo(keep_undo) - - -def update_content_on_context_change(): - """Update all Creator instances to current asset""" - host = registered_host() - context = host.get_current_context() - - folder_path = context["folder_path"] - task = context["task_name"] - - create_context = CreateContext(host, reset=True) - - for instance in create_context.instances: - instance_folder_path = instance.get("folderPath") - if instance_folder_path and instance_folder_path != folder_path: - instance["folderPath"] = folder_path - instance_task = instance.get("task") - if instance_task and instance_task != task: - instance["task"] = task - - create_context.save_changes() - - -def prompt_reset_context(): - """Prompt the user what context settings to reset. - This prompt is used on saving to a different task to allow the scene to - get matched to the new context. - """ - # TODO: Cleanup this prototyped mess of imports and odd dialog - from ayon_core.tools.attribute_defs.dialog import ( - AttributeDefinitionsDialog - ) - from qtpy import QtCore - - definitions = [ - UILabelDef( - label=( - "You are saving your workfile into a different folder or task." - "\n\n" - "Would you like to update some settings to the new context?\n" - ) - ), - BoolDef( - "fps", - label="FPS", - tooltip="Reset Comp FPS", - default=True - ), - BoolDef( - "frame_range", - label="Frame Range", - tooltip="Reset Comp start and end frame ranges", - default=True - ), - BoolDef( - "resolution", - label="Comp Resolution", - tooltip="Reset Comp resolution", - default=True - ), - BoolDef( - "instances", - label="Publish instances", - tooltip="Update all publish instance's folder and task to match " - "the new folder and task", - default=True - ), - ] - - dialog = AttributeDefinitionsDialog(definitions) - dialog.setWindowFlags( - dialog.windowFlags() | QtCore.Qt.WindowStaysOnTopHint - ) - dialog.setWindowTitle("Saving to different context.") - dialog.setStyleSheet(load_stylesheet()) - if not dialog.exec_(): - return None - - options = dialog.get_values() - folder_entity = get_current_folder_entity() - if options["frame_range"]: - set_current_context_framerange(folder_entity) - - if options["fps"]: - set_current_context_fps(folder_entity) - - if options["resolution"]: - set_current_context_resolution(folder_entity) - - if options["instances"]: - update_content_on_context_change() - - dialog.deleteLater() diff --git a/server_addon/fusion/client/ayon_fusion/api/menu.py b/server_addon/fusion/client/ayon_fusion/api/menu.py deleted file mode 100644 index 38d8c36bb1..0000000000 --- a/server_addon/fusion/client/ayon_fusion/api/menu.py +++ /dev/null @@ -1,190 +0,0 @@ -import os -import sys - -from qtpy import QtWidgets, QtCore, QtGui - -from ayon_core.tools.utils import host_tools -from ayon_core.style import load_stylesheet -from ayon_core.lib import register_event_callback -from ayon_fusion.scripts import ( - duplicate_with_inputs, -) -from ayon_fusion.api.lib import ( - set_current_context_framerange, - set_current_context_resolution, -) -from ayon_core.pipeline import get_current_folder_path -from ayon_core.resources import get_ayon_icon_filepath -from ayon_core.tools.utils import get_qt_app - -from .pipeline import FusionEventHandler -from .pulse import FusionPulse - - -MENU_LABEL = os.environ["AYON_MENU_LABEL"] - - -self = sys.modules[__name__] -self.menu = None - - -class AYONMenu(QtWidgets.QWidget): - def __init__(self, *args, **kwargs): - super(AYONMenu, self).__init__(*args, **kwargs) - - self.setObjectName(f"{MENU_LABEL}Menu") - - icon_path = get_ayon_icon_filepath() - icon = QtGui.QIcon(icon_path) - self.setWindowIcon(icon) - - self.setWindowFlags( - QtCore.Qt.Window - | QtCore.Qt.CustomizeWindowHint - | QtCore.Qt.WindowTitleHint - | QtCore.Qt.WindowMinimizeButtonHint - | QtCore.Qt.WindowCloseButtonHint - | QtCore.Qt.WindowStaysOnTopHint - ) - self.render_mode_widget = None - self.setWindowTitle(MENU_LABEL) - - context_label = QtWidgets.QLabel("Context", self) - context_label.setStyleSheet( - """QLabel { - font-size: 14px; - font-weight: 600; - color: #5f9fb8; - }""" - ) - context_label.setAlignment(QtCore.Qt.AlignHCenter) - - workfiles_btn = QtWidgets.QPushButton("Workfiles...", self) - create_btn = QtWidgets.QPushButton("Create...", self) - load_btn = QtWidgets.QPushButton("Load...", self) - publish_btn = QtWidgets.QPushButton("Publish...", self) - manager_btn = QtWidgets.QPushButton("Manage...", self) - libload_btn = QtWidgets.QPushButton("Library...", self) - set_framerange_btn = QtWidgets.QPushButton("Set Frame Range", self) - set_resolution_btn = QtWidgets.QPushButton("Set Resolution", self) - duplicate_with_inputs_btn = QtWidgets.QPushButton( - "Duplicate with input connections", self - ) - - layout = QtWidgets.QVBoxLayout(self) - layout.setContentsMargins(10, 20, 10, 20) - - layout.addWidget(context_label) - - layout.addSpacing(20) - - layout.addWidget(workfiles_btn) - - layout.addSpacing(20) - - layout.addWidget(create_btn) - layout.addWidget(load_btn) - layout.addWidget(publish_btn) - layout.addWidget(manager_btn) - - layout.addSpacing(20) - - layout.addWidget(libload_btn) - - layout.addSpacing(20) - - layout.addWidget(set_framerange_btn) - layout.addWidget(set_resolution_btn) - - layout.addSpacing(20) - - layout.addWidget(duplicate_with_inputs_btn) - - self.setLayout(layout) - - # Store reference so we can update the label - self.context_label = context_label - - workfiles_btn.clicked.connect(self.on_workfile_clicked) - create_btn.clicked.connect(self.on_create_clicked) - publish_btn.clicked.connect(self.on_publish_clicked) - load_btn.clicked.connect(self.on_load_clicked) - manager_btn.clicked.connect(self.on_manager_clicked) - libload_btn.clicked.connect(self.on_libload_clicked) - duplicate_with_inputs_btn.clicked.connect( - self.on_duplicate_with_inputs_clicked - ) - set_resolution_btn.clicked.connect(self.on_set_resolution_clicked) - set_framerange_btn.clicked.connect(self.on_set_framerange_clicked) - - self._callbacks = [] - self.register_callback("taskChanged", self.on_task_changed) - self.on_task_changed() - - # Force close current process if Fusion is closed - self._pulse = FusionPulse(parent=self) - self._pulse.start() - - # Detect Fusion events as AYON events - self._event_handler = FusionEventHandler(parent=self) - self._event_handler.start() - - def on_task_changed(self): - # Update current context label - label = get_current_folder_path() - self.context_label.setText(label) - - def register_callback(self, name, fn): - # Create a wrapper callback that we only store - # for as long as we want it to persist as callback - def _callback(*args): - fn() - - self._callbacks.append(_callback) - register_event_callback(name, _callback) - - def deregister_all_callbacks(self): - self._callbacks[:] = [] - - def on_workfile_clicked(self): - host_tools.show_workfiles() - - def on_create_clicked(self): - host_tools.show_publisher(tab="create") - - def on_publish_clicked(self): - host_tools.show_publisher(tab="publish") - - def on_load_clicked(self): - host_tools.show_loader(use_context=True) - - def on_manager_clicked(self): - host_tools.show_scene_inventory() - - def on_libload_clicked(self): - host_tools.show_library_loader() - - def on_duplicate_with_inputs_clicked(self): - duplicate_with_inputs.duplicate_with_input_connections() - - def on_set_resolution_clicked(self): - set_current_context_resolution() - - def on_set_framerange_clicked(self): - set_current_context_framerange() - - -def launch_ayon_menu(): - app = get_qt_app() - - ayon_menu = AYONMenu() - - stylesheet = load_stylesheet() - ayon_menu.setStyleSheet(stylesheet) - - ayon_menu.show() - self.menu = ayon_menu - - result = app.exec_() - print("Shutting down..") - sys.exit(result) diff --git a/server_addon/fusion/client/ayon_fusion/api/pipeline.py b/server_addon/fusion/client/ayon_fusion/api/pipeline.py deleted file mode 100644 index 04f0d3db9a..0000000000 --- a/server_addon/fusion/client/ayon_fusion/api/pipeline.py +++ /dev/null @@ -1,439 +0,0 @@ -""" -Basic avalon integration -""" -import os -import sys -import logging -import contextlib -from pathlib import Path - -import pyblish.api -from qtpy import QtCore - -from ayon_core.lib import ( - Logger, - register_event_callback, - emit_event -) -from ayon_core.pipeline import ( - register_loader_plugin_path, - register_creator_plugin_path, - register_inventory_action_path, - AVALON_CONTAINER_ID, -) -from ayon_core.pipeline.load import any_outdated_containers -from ayon_core.host import HostBase, IWorkfileHost, ILoadHost, IPublishHost -from ayon_core.tools.utils import host_tools -from ayon_fusion import FUSION_ADDON_ROOT - - -from .lib import ( - get_current_comp, - validate_comp_prefs, - prompt_reset_context -) - -log = Logger.get_logger(__name__) - -PLUGINS_DIR = os.path.join(FUSION_ADDON_ROOT, "plugins") - -PUBLISH_PATH = os.path.join(PLUGINS_DIR, "publish") -LOAD_PATH = os.path.join(PLUGINS_DIR, "load") -CREATE_PATH = os.path.join(PLUGINS_DIR, "create") -INVENTORY_PATH = os.path.join(PLUGINS_DIR, "inventory") - -# Track whether the workfile tool is about to save -_about_to_save = False - - -class FusionLogHandler(logging.Handler): - # Keep a reference to fusion's Print function (Remote Object) - _print = None - - @property - def print(self): - if self._print is not None: - # Use cached - return self._print - - _print = getattr(sys.modules["__main__"], "fusion").Print - if _print is None: - # Backwards compatibility: Print method on Fusion instance was - # added around Fusion 17.4 and wasn't available on PyRemote Object - # before - _print = get_current_comp().Print - self._print = _print - return _print - - def emit(self, record): - entry = self.format(record) - self.print(entry) - - -class FusionHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost): - name = "fusion" - - def install(self): - """Install fusion-specific functionality of AYON. - - This is where you install menus and register families, data - and loaders into fusion. - - It is called automatically when installing via - `ayon_core.pipeline.install_host(ayon_fusion.api)` - - See the Maya equivalent for inspiration on how to implement this. - - """ - # Remove all handlers associated with the root logger object, because - # that one always logs as "warnings" incorrectly. - for handler in logging.root.handlers[:]: - logging.root.removeHandler(handler) - - # Attach default logging handler that prints to active comp - logger = logging.getLogger() - formatter = logging.Formatter(fmt="%(message)s\n") - handler = FusionLogHandler() - handler.setFormatter(formatter) - logger.addHandler(handler) - logger.setLevel(logging.DEBUG) - - pyblish.api.register_host("fusion") - pyblish.api.register_plugin_path(PUBLISH_PATH) - log.info("Registering Fusion plug-ins..") - - register_loader_plugin_path(LOAD_PATH) - register_creator_plugin_path(CREATE_PATH) - register_inventory_action_path(INVENTORY_PATH) - - # Register events - register_event_callback("open", on_after_open) - register_event_callback("workfile.save.before", before_workfile_save) - register_event_callback("save", on_save) - register_event_callback("new", on_new) - register_event_callback("taskChanged", on_task_changed) - - # region workfile io api - def has_unsaved_changes(self): - comp = get_current_comp() - return comp.GetAttrs()["COMPB_Modified"] - - def get_workfile_extensions(self): - return [".comp"] - - def save_workfile(self, dst_path=None): - comp = get_current_comp() - comp.Save(dst_path) - - def open_workfile(self, filepath): - # Hack to get fusion, see - # ayon_fusion.api.pipeline.get_current_comp() - fusion = getattr(sys.modules["__main__"], "fusion", None) - - return fusion.LoadComp(filepath) - - def get_current_workfile(self): - comp = get_current_comp() - current_filepath = comp.GetAttrs()["COMPS_FileName"] - if not current_filepath: - return None - - return current_filepath - - def work_root(self, session): - work_dir = session["AYON_WORKDIR"] - scene_dir = session.get("AVALON_SCENEDIR") - if scene_dir: - return os.path.join(work_dir, scene_dir) - else: - return work_dir - # endregion - - @contextlib.contextmanager - def maintained_selection(self): - from .lib import maintained_selection - return maintained_selection() - - def get_containers(self): - return ls() - - def update_context_data(self, data, changes): - comp = get_current_comp() - comp.SetData("openpype", data) - - def get_context_data(self): - comp = get_current_comp() - return comp.GetData("openpype") or {} - - -def on_new(event): - comp = event["Rets"]["comp"] - validate_comp_prefs(comp, force_repair=True) - - -def on_save(event): - comp = event["sender"] - validate_comp_prefs(comp) - - # We are now starting the actual save directly - global _about_to_save - _about_to_save = False - - -def on_task_changed(): - global _about_to_save - print(f"Task changed: {_about_to_save}") - # TODO: Only do this if not headless - if _about_to_save: - # Let's prompt the user to update the context settings or not - prompt_reset_context() - - -def on_after_open(event): - comp = event["sender"] - validate_comp_prefs(comp) - - if any_outdated_containers(): - log.warning("Scene has outdated content.") - - # Find AYON menu to attach to - from . import menu - - def _on_show_scene_inventory(): - # ensure that comp is active - frame = comp.CurrentFrame - if not frame: - print("Comp is closed, skipping show scene inventory") - return - frame.ActivateFrame() # raise comp window - host_tools.show_scene_inventory() - - from ayon_core.tools.utils import SimplePopup - from ayon_core.style import load_stylesheet - dialog = SimplePopup(parent=menu.menu) - dialog.setWindowTitle("Fusion comp has outdated content") - dialog.set_message("There are outdated containers in " - "your Fusion comp.") - dialog.on_clicked.connect(_on_show_scene_inventory) - dialog.show() - dialog.raise_() - dialog.activateWindow() - dialog.setStyleSheet(load_stylesheet()) - - -def before_workfile_save(event): - # Due to Fusion's external python process design we can't really - # detect whether the current Fusion environment matches the one the artists - # expects it to be. For example, our pipeline python process might - # have been shut down, and restarted - which will restart it to the - # environment Fusion started with; not necessarily where the artist - # is currently working. - # The `_about_to_save` var is used to detect context changes when - # saving into another asset. If we keep it False it will be ignored - # as context change. As such, before we change tasks we will only - # consider it the current filepath is within the currently known - # AVALON_WORKDIR. This way we avoid false positives of thinking it's - # saving to another context and instead sometimes just have false negatives - # where we fail to show the "Update on task change" prompt. - comp = get_current_comp() - filepath = comp.GetAttrs()["COMPS_FileName"] - workdir = os.environ.get("AYON_WORKDIR") - if Path(workdir) in Path(filepath).parents: - global _about_to_save - _about_to_save = True - - -def ls(): - """List containers from active Fusion scene - - This is the host-equivalent of api.ls(), but instead of listing - assets on disk, it lists assets already loaded in Fusion; once loaded - they are called 'containers' - - Yields: - dict: container - - """ - - comp = get_current_comp() - tools = comp.GetToolList(False).values() - - for tool in tools: - container = parse_container(tool) - if container: - yield container - - -def imprint_container(tool, - name, - namespace, - context, - loader=None): - """Imprint a Loader with metadata - - Containerisation enables a tracking of version, author and origin - for loaded assets. - - Arguments: - tool (object): The node in Fusion to imprint as container, usually a - Loader. - name (str): Name of resulting assembly - namespace (str): Namespace under which to host container - context (dict): Asset information - loader (str, optional): Name of loader used to produce this container. - - Returns: - None - - """ - - data = [ - ("schema", "openpype:container-2.0"), - ("id", AVALON_CONTAINER_ID), - ("name", str(name)), - ("namespace", str(namespace)), - ("loader", str(loader)), - ("representation", context["representation"]["id"]), - ] - - for key, value in data: - tool.SetData("avalon.{}".format(key), value) - - -def parse_container(tool): - """Returns imprinted container data of a tool - - This reads the imprinted data from `imprint_container`. - - """ - - data = tool.GetData('avalon') - if not isinstance(data, dict): - return - - # If not all required data return the empty container - required = ['schema', 'id', 'name', - 'namespace', 'loader', 'representation'] - if not all(key in data for key in required): - return - - container = {key: data[key] for key in required} - - # Store the tool's name - container["objectName"] = tool.Name - - # Store reference to the tool object - container["_tool"] = tool - - return container - - -class FusionEventThread(QtCore.QThread): - """QThread which will periodically ping Fusion app for any events. - The fusion.UIManager must be set up to be notified of events before they'll - be reported by this thread, for example: - fusion.UIManager.AddNotify("Comp_Save", None) - - """ - - on_event = QtCore.Signal(dict) - - def run(self): - - app = getattr(sys.modules["__main__"], "app", None) - if app is None: - # No Fusion app found - return - - # As optimization store the GetEvent method directly because every - # getattr of UIManager.GetEvent tries to resolve the Remote Function - # through the PyRemoteObject - get_event = app.UIManager.GetEvent - delay = int(os.environ.get("AYON_FUSION_CALLBACK_INTERVAL", 1000)) - while True: - if self.isInterruptionRequested(): - return - - # Process all events that have been queued up until now - while True: - event = get_event(False) - if not event: - break - self.on_event.emit(event) - - # Wait some time before processing events again - # to not keep blocking the UI - self.msleep(delay) - - -class FusionEventHandler(QtCore.QObject): - """Emits AYON events based on Fusion events captured in a QThread. - - This will emit the following AYON events based on Fusion actions: - save: Comp_Save, Comp_SaveAs - open: Comp_Opened - new: Comp_New - - To use this you can attach it to you Qt UI so it runs in the background. - E.g. - >>> handler = FusionEventHandler(parent=window) - >>> handler.start() - - """ - ACTION_IDS = [ - "Comp_Save", - "Comp_SaveAs", - "Comp_New", - "Comp_Opened" - ] - - def __init__(self, parent=None): - super(FusionEventHandler, self).__init__(parent=parent) - - # Set up Fusion event callbacks - fusion = getattr(sys.modules["__main__"], "fusion", None) - ui = fusion.UIManager - - # Add notifications for the ones we want to listen to - notifiers = [] - for action_id in self.ACTION_IDS: - notifier = ui.AddNotify(action_id, None) - notifiers.append(notifier) - - # TODO: Not entirely sure whether these must be kept to avoid - # garbage collection - self._notifiers = notifiers - - self._event_thread = FusionEventThread(parent=self) - self._event_thread.on_event.connect(self._on_event) - - def start(self): - self._event_thread.start() - - def stop(self): - self._event_thread.stop() - - def _on_event(self, event): - """Handle Fusion events to emit AYON events""" - if not event: - return - - what = event["what"] - - # Comp Save - if what in {"Comp_Save", "Comp_SaveAs"}: - if not event["Rets"].get("success"): - # If the Save action is cancelled it will still emit an - # event but with "success": False so we ignore those cases - return - # Comp was saved - emit_event("save", data=event) - return - - # Comp New - elif what in {"Comp_New"}: - emit_event("new", data=event) - - # Comp Opened - elif what in {"Comp_Opened"}: - emit_event("open", data=event) diff --git a/server_addon/fusion/client/ayon_fusion/api/plugin.py b/server_addon/fusion/client/ayon_fusion/api/plugin.py deleted file mode 100644 index 48e133cc63..0000000000 --- a/server_addon/fusion/client/ayon_fusion/api/plugin.py +++ /dev/null @@ -1,278 +0,0 @@ -from copy import deepcopy -import os - -from ayon_fusion.api import ( - get_current_comp, - comp_lock_and_undo_chunk, -) - -from ayon_core.lib import ( - BoolDef, - EnumDef, -) -from ayon_core.pipeline import ( - Creator, - CreatedInstance, - AVALON_INSTANCE_ID, - AYON_INSTANCE_ID, -) -from ayon_core.pipeline.workfile import get_workdir -from ayon_api import ( - get_project, - get_folder_by_path, - get_task_by_name -) - - -class GenericCreateSaver(Creator): - default_variants = ["Main", "Mask"] - description = "Fusion Saver to generate image sequence" - icon = "fa5.eye" - - instance_attributes = [ - "reviewable" - ] - - settings_category = "fusion" - - image_format = "exr" - - # TODO: This should be renamed together with Nuke so it is aligned - temp_rendering_path_template = ( - "{workdir}/renders/fusion/{product[name]}/" - "{product[name]}.{frame}.{ext}" - ) - - def create(self, product_name, instance_data, pre_create_data): - self.pass_pre_attributes_to_instance(instance_data, pre_create_data) - - instance = CreatedInstance( - product_type=self.product_type, - product_name=product_name, - data=instance_data, - creator=self, - ) - data = instance.data_to_store() - comp = get_current_comp() - with comp_lock_and_undo_chunk(comp): - args = (-32768, -32768) # Magical position numbers - saver = comp.AddTool("Saver", *args) - - self._update_tool_with_data(saver, data=data) - - # Register the CreatedInstance - self._imprint(saver, data) - - # Insert the transient data - instance.transient_data["tool"] = saver - - self._add_instance_to_context(instance) - - return instance - - def collect_instances(self): - comp = get_current_comp() - tools = comp.GetToolList(False, "Saver").values() - for tool in tools: - data = self.get_managed_tool_data(tool) - if not data: - continue - - # Add instance - created_instance = CreatedInstance.from_existing(data, self) - - # Collect transient data - created_instance.transient_data["tool"] = tool - - self._add_instance_to_context(created_instance) - - def update_instances(self, update_list): - for created_inst, _changes in update_list: - new_data = created_inst.data_to_store() - tool = created_inst.transient_data["tool"] - self._update_tool_with_data(tool, new_data) - self._imprint(tool, new_data) - - def remove_instances(self, instances): - for instance in instances: - # Remove the tool from the scene - - tool = instance.transient_data["tool"] - if tool: - tool.Delete() - - # Remove the collected CreatedInstance to remove from UI directly - self._remove_instance_from_context(instance) - - def _imprint(self, tool, data): - # Save all data in a "openpype.{key}" = value data - - # Instance id is the tool's name so we don't need to imprint as data - data.pop("instance_id", None) - - active = data.pop("active", None) - if active is not None: - # Use active value to set the passthrough state - tool.SetAttrs({"TOOLB_PassThrough": not active}) - - for key, value in data.items(): - tool.SetData(f"openpype.{key}", value) - - def _update_tool_with_data(self, tool, data): - """Update tool node name and output path based on product data""" - if "productName" not in data: - return - - original_product_name = tool.GetData("openpype.productName") - original_format = tool.GetData( - "openpype.creator_attributes.image_format" - ) - - product_name = data["productName"] - if ( - original_product_name != product_name - or tool.GetData("openpype.task") != data["task"] - or tool.GetData("openpype.folderPath") != data["folderPath"] - or original_format != data["creator_attributes"]["image_format"] - ): - self._configure_saver_tool(data, tool, product_name) - - def _configure_saver_tool(self, data, tool, product_name): - formatting_data = deepcopy(data) - - # get frame padding from anatomy templates - frame_padding = self.project_anatomy.templates_obj.frame_padding - - # get output format - ext = data["creator_attributes"]["image_format"] - - # Product change detected - product_type = formatting_data["productType"] - f_product_name = formatting_data["productName"] - - folder_path = formatting_data["folderPath"] - folder_name = folder_path.rsplit("/", 1)[-1] - - # If the folder path and task do not match the current context then the - # workdir is not just the `AYON_WORKDIR`. Hence, we need to actually - # compute the resulting workdir - if ( - data["folderPath"] == self.create_context.get_current_folder_path() - and data["task"] == self.create_context.get_current_task_name() - ): - workdir = os.path.normpath(os.getenv("AYON_WORKDIR")) - else: - # TODO: Optimize this logic - project_name = self.create_context.get_current_project_name() - project_entity = get_project(project_name) - folder_entity = get_folder_by_path(project_name, - data["folderPath"]) - task_entity = get_task_by_name(project_name, - folder_id=folder_entity["id"], - task_name=data["task"]) - workdir = get_workdir( - project_entity=project_entity, - folder_entity=folder_entity, - task_entity=task_entity, - host_name=self.create_context.host_name, - ) - - formatting_data.update({ - "workdir": workdir, - "frame": "0" * frame_padding, - "ext": ext, - "product": { - "name": f_product_name, - "type": product_type, - }, - # TODO add more variants for 'folder' and 'task' - "folder": { - "name": folder_name, - }, - "task": { - "name": data["task"], - }, - # Backwards compatibility - "asset": folder_name, - "subset": f_product_name, - "family": product_type, - }) - - # build file path to render - # TODO make sure the keys are available in 'formatting_data' - temp_rendering_path_template = ( - self.temp_rendering_path_template - .replace("{task}", "{task[name]}") - ) - - filepath = temp_rendering_path_template.format(**formatting_data) - - comp = get_current_comp() - tool["Clip"] = comp.ReverseMapPath(os.path.normpath(filepath)) - - # Rename tool - if tool.Name != product_name: - print(f"Renaming {tool.Name} -> {product_name}") - tool.SetAttrs({"TOOLS_Name": product_name}) - - def get_managed_tool_data(self, tool): - """Return data of the tool if it matches creator identifier""" - data = tool.GetData("openpype") - if not isinstance(data, dict): - return - - if ( - data.get("creator_identifier") != self.identifier - or data.get("id") not in { - AYON_INSTANCE_ID, AVALON_INSTANCE_ID - } - ): - return - - # Get active state from the actual tool state - attrs = tool.GetAttrs() - passthrough = attrs["TOOLB_PassThrough"] - data["active"] = not passthrough - - # Override publisher's UUID generation because tool names are - # already unique in Fusion in a comp - data["instance_id"] = tool.Name - - return data - - def get_instance_attr_defs(self): - """Settings for publish page""" - return self.get_pre_create_attr_defs() - - def pass_pre_attributes_to_instance(self, instance_data, pre_create_data): - creator_attrs = instance_data["creator_attributes"] = {} - for pass_key in pre_create_data.keys(): - creator_attrs[pass_key] = pre_create_data[pass_key] - - def _get_render_target_enum(self): - rendering_targets = { - "local": "Local machine rendering", - "frames": "Use existing frames", - } - if "farm_rendering" in self.instance_attributes: - rendering_targets["farm"] = "Farm rendering" - - return EnumDef( - "render_target", items=rendering_targets, label="Render target" - ) - - def _get_reviewable_bool(self): - return BoolDef( - "review", - default=("reviewable" in self.instance_attributes), - label="Review", - ) - - def _get_image_format_enum(self): - image_format_options = ["exr", "tga", "tif", "png", "jpg"] - return EnumDef( - "image_format", - items=image_format_options, - default=self.image_format, - label="Output Image Format", - ) diff --git a/server_addon/fusion/client/ayon_fusion/api/pulse.py b/server_addon/fusion/client/ayon_fusion/api/pulse.py deleted file mode 100644 index 7128b7e1ff..0000000000 --- a/server_addon/fusion/client/ayon_fusion/api/pulse.py +++ /dev/null @@ -1,63 +0,0 @@ -import os -import sys - -from qtpy import QtCore - - -class PulseThread(QtCore.QThread): - no_response = QtCore.Signal() - - def __init__(self, parent=None): - super(PulseThread, self).__init__(parent=parent) - - def run(self): - app = getattr(sys.modules["__main__"], "app", None) - - # Interval in milliseconds - interval = os.environ.get("AYON_FUSION_PULSE_INTERVAL", 1000) - - while True: - if self.isInterruptionRequested(): - return - - # We don't need to call Test because PyRemoteObject of the app - # will actually fail to even resolve the Test function if it has - # gone down. So we can actually already just check by confirming - # the method is still getting resolved. (Optimization) - if app.Test is None: - self.no_response.emit() - - self.msleep(interval) - - -class FusionPulse(QtCore.QObject): - """A Timer that checks whether host app is still alive. - - This checks whether the Fusion process is still active at a certain - interval. This is useful due to how Fusion runs its scripts. Each script - runs in its own environment and process (a `fusionscript` process each). - If Fusion would go down and we have a UI process running at the same time - then it can happen that the `fusionscript.exe` will remain running in the - background in limbo due to e.g. a Qt interface's QApplication that keeps - running infinitely. - - Warning: - When the host is not detected this will automatically exit - the current process. - - """ - - def __init__(self, parent=None): - super(FusionPulse, self).__init__(parent=parent) - self._thread = PulseThread(parent=self) - self._thread.no_response.connect(self.on_no_response) - - def on_no_response(self): - print("Pulse detected no response from Fusion..") - sys.exit(1) - - def start(self): - self._thread.start() - - def stop(self): - self._thread.requestInterruption() diff --git a/server_addon/fusion/client/ayon_fusion/deploy/MenuScripts/README.md b/server_addon/fusion/client/ayon_fusion/deploy/MenuScripts/README.md deleted file mode 100644 index e291b8d8f2..0000000000 --- a/server_addon/fusion/client/ayon_fusion/deploy/MenuScripts/README.md +++ /dev/null @@ -1,6 +0,0 @@ -### AYON deploy MenuScripts - -Note that this `MenuScripts` is not an official Fusion folder. -AYON only uses this folder in `{fusion}/deploy/` to trigger the AYON menu actions. - -They are used in the actions defined in `.fu` files in `{fusion}/deploy/Config`. \ No newline at end of file diff --git a/server_addon/fusion/client/ayon_fusion/deploy/MenuScripts/install_pyside2.py b/server_addon/fusion/client/ayon_fusion/deploy/MenuScripts/install_pyside2.py deleted file mode 100644 index e1240fd677..0000000000 --- a/server_addon/fusion/client/ayon_fusion/deploy/MenuScripts/install_pyside2.py +++ /dev/null @@ -1,29 +0,0 @@ -# This is just a quick hack for users running Py3 locally but having no -# Qt library installed -import os -import subprocess -import importlib - - -try: - from qtpy import API_NAME - - print(f"Qt binding: {API_NAME}") - mod = importlib.import_module(API_NAME) - print(f"Qt path: {mod.__file__}") - print("Qt library found, nothing to do..") - -except ImportError: - print("Assuming no Qt library is installed..") - print('Installing PySide2 for Python 3.6: ' - f'{os.environ["FUSION16_PYTHON36_HOME"]}') - - # Get full path to python executable - exe = "python.exe" if os.name == 'nt' else "python" - python = os.path.join(os.environ["FUSION16_PYTHON36_HOME"], exe) - assert os.path.exists(python), f"Python doesn't exist: {python}" - - # Do python -m pip install PySide2 - args = [python, "-m", "pip", "install", "PySide2"] - print(f"Args: {args}") - subprocess.Popen(args) diff --git a/server_addon/fusion/client/ayon_fusion/deploy/MenuScripts/launch_menu.py b/server_addon/fusion/client/ayon_fusion/deploy/MenuScripts/launch_menu.py deleted file mode 100644 index 0c5010f6a7..0000000000 --- a/server_addon/fusion/client/ayon_fusion/deploy/MenuScripts/launch_menu.py +++ /dev/null @@ -1,47 +0,0 @@ -import os -import sys - -if sys.version_info < (3, 7): - # hack to handle discrepancy between distributed libraries and Python 3.6 - # mostly because wrong version of urllib3 - # TODO remove when not necessary - from ayon_fusion import FUSION_ADDON_ROOT - - vendor_path = os.path.join(FUSION_ADDON_ROOT, "vendor") - if vendor_path not in sys.path: - sys.path.insert(0, vendor_path) - - print(f"Added vendorized libraries from {vendor_path}") - -from ayon_core.lib import Logger -from ayon_core.pipeline import ( - install_host, - registered_host, -) - - -def main(env): - # This script working directory starts in Fusion application folder. - # However the contents of that folder can conflict with Qt library dlls - # so we make sure to move out of it to avoid DLL Load Failed errors. - os.chdir("..") - from ayon_fusion.api import FusionHost - from ayon_fusion.api import menu - - # activate resolve from pype - install_host(FusionHost()) - - log = Logger.get_logger(__name__) - log.info(f"Registered host: {registered_host()}") - - menu.launch_ayon_menu() - - # Initiate a QTimer to check if Fusion is still alive every X interval - # If Fusion is not found - kill itself - # todo(roy): Implement timer that ensures UI doesn't remain when e.g. - # Fusion closes down - - -if __name__ == "__main__": - result = main(os.environ) - sys.exit(not bool(result)) diff --git a/server_addon/fusion/client/ayon_fusion/deploy/ayon/Config/menu.fu b/server_addon/fusion/client/ayon_fusion/deploy/ayon/Config/menu.fu deleted file mode 100644 index c968a1bb3d..0000000000 --- a/server_addon/fusion/client/ayon_fusion/deploy/ayon/Config/menu.fu +++ /dev/null @@ -1,60 +0,0 @@ -{ - Action - { - ID = "AYON_Menu", - Category = "AYON", - Name = "AYON Menu", - - Targets = - { - Composition = - { - Execute = _Lua [=[ - local scriptPath = app:MapPath("AYON:../MenuScripts/launch_menu.py") - if bmd.fileexists(scriptPath) == false then - print("[AYON Error] Can't run file: " .. scriptPath) - else - target:RunScript(scriptPath) - end - ]=], - }, - }, - }, - Action - { - ID = "AYON_Install_PySide2", - Category = "AYON", - Name = "Install PySide2", - - Targets = - { - Composition = - { - Execute = _Lua [=[ - local scriptPath = app:MapPath("AYON:../MenuScripts/install_pyside2.py") - if bmd.fileexists(scriptPath) == false then - print("[AYON Error] Can't run file: " .. scriptPath) - else - target:RunScript(scriptPath) - end - ]=], - }, - }, - }, - Menus - { - Target = "ChildFrame", - - Before "Help" - { - Sub "AYON" - { - "AYON_Menu{}", - "_", - Sub "Admin" { - "AYON_Install_PySide2{}" - } - } - }, - }, -} diff --git a/server_addon/fusion/client/ayon_fusion/deploy/ayon/fusion_shared.prefs b/server_addon/fusion/client/ayon_fusion/deploy/ayon/fusion_shared.prefs deleted file mode 100644 index 59b0f82bad..0000000000 --- a/server_addon/fusion/client/ayon_fusion/deploy/ayon/fusion_shared.prefs +++ /dev/null @@ -1,19 +0,0 @@ -{ -Locked = true, -Global = { - Paths = { - Map = { - ["AYON:"] = "$(AYON_FUSION_ROOT)/deploy/ayon", - ["Config:"] = "UserPaths:Config;AYON:Config", - ["Scripts:"] = "UserPaths:Scripts;Reactor:System/Scripts", - }, - }, - Script = { - PythonVersion = 3, - Python3Forced = true - }, - UserInterface = { - Language = "en_US" - }, - }, -} diff --git a/server_addon/fusion/client/ayon_fusion/hooks/pre_fusion_launch_menu_hook.py b/server_addon/fusion/client/ayon_fusion/hooks/pre_fusion_launch_menu_hook.py deleted file mode 100644 index 035cbb8d97..0000000000 --- a/server_addon/fusion/client/ayon_fusion/hooks/pre_fusion_launch_menu_hook.py +++ /dev/null @@ -1,36 +0,0 @@ -import os -from ayon_applications import PreLaunchHook -from ayon_fusion import FUSION_ADDON_ROOT - - -class FusionLaunchMenuHook(PreLaunchHook): - """Launch AYON menu on start of Fusion""" - app_groups = ["fusion"] - order = 9 - - def execute(self): - # Prelaunch hook is optional - settings = self.data["project_settings"][self.host_name] - if not settings["hooks"]["FusionLaunchMenuHook"]["enabled"]: - return - - variant = self.application.name - if variant.isnumeric(): - version = int(variant) - if version < 18: - print("Skipping launch of OpenPype menu on Fusion start " - "because Fusion version below 18.0 does not support " - "/execute argument on launch. " - f"Version detected: {version}") - return - else: - print(f"Application variant is not numeric: {variant}. " - "Validation for Fusion version 18+ for /execute " - "prelaunch argument skipped.") - - path = os.path.join(FUSION_ADDON_ROOT, - "deploy", - "MenuScripts", - "launch_menu.py").replace("\\", "/") - script = f"fusion:RunScript('{path}')" - self.launch_context.launch_args.extend(["/execute", script]) diff --git a/server_addon/fusion/client/ayon_fusion/hooks/pre_fusion_profile_hook.py b/server_addon/fusion/client/ayon_fusion/hooks/pre_fusion_profile_hook.py deleted file mode 100644 index 7758798bb6..0000000000 --- a/server_addon/fusion/client/ayon_fusion/hooks/pre_fusion_profile_hook.py +++ /dev/null @@ -1,169 +0,0 @@ -import os -import shutil -import platform -from pathlib import Path -from ayon_fusion import ( - FUSION_ADDON_ROOT, - FUSION_VERSIONS_DICT, - get_fusion_version, -) -from ayon_applications import ( - PreLaunchHook, - LaunchTypes, - ApplicationLaunchFailed, -) - - -class FusionCopyPrefsPrelaunch(PreLaunchHook): - """ - Prepares local Fusion profile directory, copies existing Fusion profile. - This also sets FUSION MasterPrefs variable, which is used - to apply Master.prefs file to override some Fusion profile settings to: - - enable the AYON menu - - force Python 3 over Python 2 - - force English interface - Master.prefs is defined in openpype/hosts/fusion/deploy/fusion_shared.prefs - """ - - app_groups = {"fusion"} - order = 2 - launch_types = {LaunchTypes.local} - - def get_fusion_profile_name(self, profile_version) -> str: - # Returns 'Default', unless FUSION16_PROFILE is set - return os.getenv(f"FUSION{profile_version}_PROFILE", "Default") - - def get_fusion_profile_dir(self, profile_version) -> Path: - # Get FUSION_PROFILE_DIR variable - fusion_profile = self.get_fusion_profile_name(profile_version) - fusion_var_prefs_dir = os.getenv( - f"FUSION{profile_version}_PROFILE_DIR" - ) - - # Check if FUSION_PROFILE_DIR exists - if fusion_var_prefs_dir and Path(fusion_var_prefs_dir).is_dir(): - fu_prefs_dir = Path(fusion_var_prefs_dir, fusion_profile) - self.log.info(f"{fusion_var_prefs_dir} is set to {fu_prefs_dir}") - return fu_prefs_dir - - def get_profile_source(self, profile_version) -> Path: - """Get Fusion preferences profile location. - See Per-User_Preferences_and_Paths on VFXpedia for reference. - """ - fusion_profile = self.get_fusion_profile_name(profile_version) - profile_source = self.get_fusion_profile_dir(profile_version) - if profile_source: - return profile_source - # otherwise get default location of the profile folder - fu_prefs_dir = f"Blackmagic Design/Fusion/Profiles/{fusion_profile}" - if platform.system() == "Windows": - profile_source = Path(os.getenv("AppData"), fu_prefs_dir) - elif platform.system() == "Darwin": - profile_source = Path( - "~/Library/Application Support/", fu_prefs_dir - ).expanduser() - elif platform.system() == "Linux": - profile_source = Path("~/.fusion", fu_prefs_dir).expanduser() - self.log.info( - f"Locating source Fusion prefs directory: {profile_source}" - ) - return profile_source - - def get_copy_fusion_prefs_settings(self): - # Get copy preferences options from the global application settings - - copy_fusion_settings = self.data["project_settings"]["fusion"].get( - "copy_fusion_settings", {} - ) - if not copy_fusion_settings: - self.log.error("Copy prefs settings not found") - copy_status = copy_fusion_settings.get("copy_status", False) - force_sync = copy_fusion_settings.get("force_sync", False) - copy_path = copy_fusion_settings.get("copy_path") or None - if copy_path: - copy_path = Path(copy_path).expanduser() - return copy_status, copy_path, force_sync - - def copy_fusion_profile( - self, copy_from: Path, copy_to: Path, force_sync: bool - ) -> None: - """On the first Fusion launch copy the contents of Fusion profile - directory to the working predefined location. If the Openpype profile - folder exists, skip copying, unless re-sync is checked. - If the prefs were not copied on the first launch, - clean Fusion profile will be created in fu_profile_dir. - """ - if copy_to.exists() and not force_sync: - self.log.info( - "Destination Fusion preferences folder already exists: " - f"{copy_to} " - ) - return - self.log.info("Starting copying Fusion preferences") - self.log.debug(f"force_sync option is set to {force_sync}") - try: - copy_to.mkdir(exist_ok=True, parents=True) - except PermissionError: - self.log.warning(f"Creating the folder not permitted at {copy_to}") - return - if not copy_from.exists(): - self.log.warning(f"Fusion preferences not found in {copy_from}") - return - for file in copy_from.iterdir(): - if file.suffix in ( - ".prefs", - ".def", - ".blocklist", - ".fu", - ".toolbars", - ): - # convert Path to str to be compatible with Python 3.6+ - shutil.copy(str(file), str(copy_to)) - self.log.info( - f"Successfully copied preferences: {copy_from} to {copy_to}" - ) - - def execute(self): - ( - copy_status, - fu_profile_dir, - force_sync, - ) = self.get_copy_fusion_prefs_settings() - - # Get launched application context and return correct app version - app_name = self.launch_context.env.get("AYON_APP_NAME") - app_version = get_fusion_version(app_name) - if app_version is None: - version_names = ", ".join(str(x) for x in FUSION_VERSIONS_DICT) - raise ApplicationLaunchFailed( - "Unable to detect valid Fusion version number from app " - f"name: {app_name}.\nMake sure to include at least a digit " - "to indicate the Fusion version like '18'.\n" - f"Detectable Fusion versions are: {version_names}" - ) - - _, profile_version = FUSION_VERSIONS_DICT[app_version] - fu_profile = self.get_fusion_profile_name(profile_version) - - # do a copy of Fusion profile if copy_status toggle is enabled - if copy_status and fu_profile_dir is not None: - profile_source = self.get_profile_source(profile_version) - dest_folder = Path(fu_profile_dir, fu_profile) - self.copy_fusion_profile(profile_source, dest_folder, force_sync) - - # Add temporary profile directory variables to customize Fusion - # to define where it can read custom scripts and tools from - fu_profile_dir_variable = f"FUSION{profile_version}_PROFILE_DIR" - self.log.info(f"Setting {fu_profile_dir_variable}: {fu_profile_dir}") - self.launch_context.env[fu_profile_dir_variable] = str(fu_profile_dir) - - # Add custom Fusion Master Prefs and the temporary - # profile directory variables to customize Fusion - # to define where it can read custom scripts and tools from - master_prefs_variable = f"FUSION{profile_version}_MasterPrefs" - - master_prefs = Path( - FUSION_ADDON_ROOT, "deploy", "ayon", "fusion_shared.prefs") - - self.log.info(f"Setting {master_prefs_variable}: {master_prefs}") - self.launch_context.env[master_prefs_variable] = str(master_prefs) diff --git a/server_addon/fusion/client/ayon_fusion/hooks/pre_fusion_setup.py b/server_addon/fusion/client/ayon_fusion/hooks/pre_fusion_setup.py deleted file mode 100644 index 25cf40f18d..0000000000 --- a/server_addon/fusion/client/ayon_fusion/hooks/pre_fusion_setup.py +++ /dev/null @@ -1,71 +0,0 @@ -import os -from ayon_applications import ( - PreLaunchHook, - LaunchTypes, - ApplicationLaunchFailed, -) -from ayon_fusion import ( - FUSION_ADDON_ROOT, - FUSION_VERSIONS_DICT, - get_fusion_version, -) - - -class FusionPrelaunch(PreLaunchHook): - """ - Prepares AYON Fusion environment. - Requires correct Python home variable to be defined in the environment - settings for Fusion to point at a valid Python 3 build for Fusion. - Python3 versions that are supported by Fusion: - Fusion 9, 16, 17 : Python 3.6 - Fusion 18 : Python 3.6 - 3.10 - """ - - app_groups = {"fusion"} - order = 1 - launch_types = {LaunchTypes.local} - - def execute(self): - # making sure python 3 is installed at provided path - # Py 3.3-3.10 for Fusion 18+ or Py 3.6 for Fu 16-17 - app_data = self.launch_context.env.get("AYON_APP_NAME") - app_version = get_fusion_version(app_data) - if not app_version: - raise ApplicationLaunchFailed( - "Fusion version information not found in System settings.\n" - "The key field in the 'applications/fusion/variants' should " - "consist a number, corresponding to major Fusion version." - ) - py3_var, _ = FUSION_VERSIONS_DICT[app_version] - fusion_python3_home = self.launch_context.env.get(py3_var, "") - - for path in fusion_python3_home.split(os.pathsep): - # Allow defining multiple paths, separated by os.pathsep, - # to allow "fallback" to other path. - # But make to set only a single path as final variable. - py3_dir = os.path.normpath(path) - if os.path.isdir(py3_dir): - break - else: - raise ApplicationLaunchFailed( - "Python 3 is not installed at the provided path.\n" - "Make sure the environment in fusion settings has " - "'FUSION_PYTHON3_HOME' set correctly and make sure " - "Python 3 is installed in the given path." - f"\n\nPYTHON PATH: {fusion_python3_home}" - ) - - self.log.info(f"Setting {py3_var}: '{py3_dir}'...") - self.launch_context.env[py3_var] = py3_dir - - # Fusion 18+ requires FUSION_PYTHON3_HOME to also be on PATH - if app_version >= 18: - self.launch_context.env["PATH"] += os.pathsep + py3_dir - - self.launch_context.env[py3_var] = py3_dir - - # for hook installing PySide2 - self.data["fusion_python3_home"] = py3_dir - - self.log.info(f"Setting AYON_FUSION_ROOT: {FUSION_ADDON_ROOT}") - self.launch_context.env["AYON_FUSION_ROOT"] = FUSION_ADDON_ROOT diff --git a/server_addon/fusion/client/ayon_fusion/hooks/pre_pyside_install.py b/server_addon/fusion/client/ayon_fusion/hooks/pre_pyside_install.py deleted file mode 100644 index 4678d5bac7..0000000000 --- a/server_addon/fusion/client/ayon_fusion/hooks/pre_pyside_install.py +++ /dev/null @@ -1,185 +0,0 @@ -import os -import subprocess -import platform -import uuid - -from ayon_applications import PreLaunchHook, LaunchTypes - - -class InstallPySideToFusion(PreLaunchHook): - """Automatically installs Qt binding to fusion's python packages. - - Check if fusion has installed PySide2 and will try to install if not. - - For pipeline implementation is required to have Qt binding installed in - fusion's python packages. - """ - - app_groups = {"fusion"} - order = 2 - launch_types = {LaunchTypes.local} - - def execute(self): - # Prelaunch hook is not crucial - try: - settings = self.data["project_settings"][self.host_name] - if not settings["hooks"]["InstallPySideToFusion"]["enabled"]: - return - self.inner_execute() - except Exception: - self.log.warning( - "Processing of {} crashed.".format(self.__class__.__name__), - exc_info=True - ) - - def inner_execute(self): - self.log.debug("Check for PySide2 installation.") - - fusion_python3_home = self.data.get("fusion_python3_home") - if not fusion_python3_home: - self.log.warning("'fusion_python3_home' was not provided. " - "Installation of PySide2 not possible") - return - - if platform.system().lower() == "windows": - exe_filenames = ["python.exe"] - else: - exe_filenames = ["python3", "python"] - - for exe_filename in exe_filenames: - python_executable = os.path.join(fusion_python3_home, exe_filename) - if os.path.exists(python_executable): - break - - if not os.path.exists(python_executable): - self.log.warning( - "Couldn't find python executable for fusion. {}".format( - python_executable - ) - ) - return - - # Check if PySide2 is installed and skip if yes - if self._is_pyside_installed(python_executable): - self.log.debug("Fusion has already installed PySide2.") - return - - self.log.debug("Installing PySide2.") - # Install PySide2 in fusion's python - if self._windows_require_permissions( - os.path.dirname(python_executable)): - result = self._install_pyside_windows(python_executable) - else: - result = self._install_pyside(python_executable) - - if result: - self.log.info("Successfully installed PySide2 module to fusion.") - else: - self.log.warning("Failed to install PySide2 module to fusion.") - - def _install_pyside_windows(self, python_executable): - """Install PySide2 python module to fusion's python. - - Installation requires administration rights that's why it is required - to use "pywin32" module which can execute command's and ask for - administration rights. - """ - try: - import win32con - import win32process - import win32event - import pywintypes - from win32comext.shell.shell import ShellExecuteEx - from win32comext.shell import shellcon - except Exception: - self.log.warning("Couldn't import \"pywin32\" modules") - return False - - try: - # Parameters - # - use "-m pip" as module pip to install PySide2 and argument - # "--ignore-installed" is to force install module to fusion's - # site-packages and make sure it is binary compatible - parameters = "-m pip install --ignore-installed PySide2" - - # Execute command and ask for administrator's rights - process_info = ShellExecuteEx( - nShow=win32con.SW_SHOWNORMAL, - fMask=shellcon.SEE_MASK_NOCLOSEPROCESS, - lpVerb="runas", - lpFile=python_executable, - lpParameters=parameters, - lpDirectory=os.path.dirname(python_executable) - ) - process_handle = process_info["hProcess"] - win32event.WaitForSingleObject(process_handle, - win32event.INFINITE) - returncode = win32process.GetExitCodeProcess(process_handle) - return returncode == 0 - except pywintypes.error: - return False - - def _install_pyside(self, python_executable): - """Install PySide2 python module to fusion's python.""" - try: - # Parameters - # - use "-m pip" as module pip to install PySide2 and argument - # "--ignore-installed" is to force install module to fusion's - # site-packages and make sure it is binary compatible - env = dict(os.environ) - del env['PYTHONPATH'] - args = [ - python_executable, - "-m", - "pip", - "install", - "--ignore-installed", - "PySide2", - ] - process = subprocess.Popen( - args, stdout=subprocess.PIPE, universal_newlines=True, - env=env - ) - process.communicate() - return process.returncode == 0 - except PermissionError: - self.log.warning( - "Permission denied with command:" - "\"{}\".".format(" ".join(args)) - ) - except OSError as error: - self.log.warning(f"OS error has occurred: \"{error}\".") - except subprocess.SubprocessError: - pass - - def _is_pyside_installed(self, python_executable): - """Check if PySide2 module is in fusion's pip list.""" - args = [python_executable, "-c", "from qtpy import QtWidgets"] - process = subprocess.Popen(args, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - _, stderr = process.communicate() - stderr = stderr.decode() - if stderr: - return False - return True - - def _windows_require_permissions(self, dirpath): - if platform.system().lower() != "windows": - return False - - try: - # Attempt to create a temporary file in the folder - temp_file_path = os.path.join(dirpath, uuid.uuid4().hex) - with open(temp_file_path, "w"): - pass - os.remove(temp_file_path) # Clean up temporary file - return False - - except PermissionError: - return True - - except BaseException as exc: - print(("Failed to determine if root requires permissions." - "Unexpected error: {}").format(exc)) - return False diff --git a/server_addon/fusion/client/ayon_fusion/plugins/create/create_image_saver.py b/server_addon/fusion/client/ayon_fusion/plugins/create/create_image_saver.py deleted file mode 100644 index d88219b268..0000000000 --- a/server_addon/fusion/client/ayon_fusion/plugins/create/create_image_saver.py +++ /dev/null @@ -1,63 +0,0 @@ -from ayon_core.lib import NumberDef - -from ayon_fusion.api.plugin import GenericCreateSaver - - -class CreateImageSaver(GenericCreateSaver): - """Fusion Saver to generate single image. - - Created to explicitly separate single ('image') or - multi frame('render) outputs. - - This might be temporary creator until 'alias' functionality will be - implemented to limit creation of additional product types with similar, but - not the same workflows. - """ - identifier = "io.openpype.creators.fusion.imagesaver" - label = "Image (saver)" - name = "image" - product_type = "image" - description = "Fusion Saver to generate image" - - default_frame = 0 - - def get_detail_description(self): - return """Fusion Saver to generate single image. - - This creator is expected for publishing of single frame `image` product - type. - - Artist should provide frame number (integer) to specify which frame - should be published. It must be inside of global timeline frame range. - - Supports local and deadline rendering. - - Supports selection from predefined set of output file extensions: - - exr - - tga - - png - - tif - - jpg - - Created to explicitly separate single frame ('image') or - multi frame ('render') outputs. - """ - - def get_pre_create_attr_defs(self): - """Settings for create page""" - attr_defs = [ - self._get_render_target_enum(), - self._get_reviewable_bool(), - self._get_frame_int(), - self._get_image_format_enum(), - ] - return attr_defs - - def _get_frame_int(self): - return NumberDef( - "frame", - default=self.default_frame, - label="Frame", - tooltip="Set frame to be rendered, must be inside of global " - "timeline range" - ) diff --git a/server_addon/fusion/client/ayon_fusion/plugins/create/create_saver.py b/server_addon/fusion/client/ayon_fusion/plugins/create/create_saver.py deleted file mode 100644 index 3e7d9486ce..0000000000 --- a/server_addon/fusion/client/ayon_fusion/plugins/create/create_saver.py +++ /dev/null @@ -1,149 +0,0 @@ -from ayon_core.lib import ( - UILabelDef, - NumberDef, - EnumDef -) - -from ayon_fusion.api.plugin import GenericCreateSaver -from ayon_fusion.api.lib import get_current_comp - - -class CreateSaver(GenericCreateSaver): - """Fusion Saver to generate image sequence of 'render' product type. - - Original Saver creator targeted for 'render' product type. It uses - original not to descriptive name because of values in Settings. - """ - identifier = "io.openpype.creators.fusion.saver" - label = "Render (saver)" - name = "render" - product_type = "render" - description = "Fusion Saver to generate image sequence" - - default_frame_range_option = "current_folder" - - def get_detail_description(self): - return """Fusion Saver to generate image sequence. - - This creator is expected for publishing of image sequences for 'render' - product type. (But can publish even single frame 'render'.) - - Select what should be source of render range: - - "Current Folder context" - values set on folder on AYON server - - "From render in/out" - from node itself - - "From composition timeline" - from timeline - - Supports local and farm rendering. - - Supports selection from predefined set of output file extensions: - - exr - - tga - - png - - tif - - jpg - """ - - def get_pre_create_attr_defs(self): - """Settings for create page""" - attr_defs = [ - self._get_render_target_enum(), - self._get_reviewable_bool(), - self._get_frame_range_enum(), - self._get_image_format_enum(), - *self._get_custom_frame_range_attribute_defs() - ] - return attr_defs - - def _get_frame_range_enum(self): - frame_range_options = { - "current_folder": "Current Folder context", - "render_range": "From render in/out", - "comp_range": "From composition timeline", - "custom_range": "Custom frame range", - } - - return EnumDef( - "frame_range_source", - items=frame_range_options, - label="Frame range source", - default=self.default_frame_range_option - ) - - @staticmethod - def _get_custom_frame_range_attribute_defs() -> list: - - # Define custom frame range defaults based on current comp - # timeline settings (if a comp is currently open) - comp = get_current_comp() - if comp is not None: - attrs = comp.GetAttrs() - frame_defaults = { - "frameStart": int(attrs["COMPN_GlobalStart"]), - "frameEnd": int(attrs["COMPN_GlobalEnd"]), - "handleStart": int( - attrs["COMPN_RenderStart"] - attrs["COMPN_GlobalStart"] - ), - "handleEnd": int( - attrs["COMPN_GlobalEnd"] - attrs["COMPN_RenderEnd"] - ), - } - else: - frame_defaults = { - "frameStart": 1001, - "frameEnd": 1100, - "handleStart": 0, - "handleEnd": 0 - } - - return [ - UILabelDef( - label="
Custom Frame Range
" - "only used with 'Custom frame range' source" - ), - NumberDef( - "custom_frameStart", - label="Frame Start", - default=frame_defaults["frameStart"], - minimum=0, - decimals=0, - tooltip=( - "Set the start frame for the export.\n" - "Only used if frame range source is 'Custom frame range'." - ) - ), - NumberDef( - "custom_frameEnd", - label="Frame End", - default=frame_defaults["frameEnd"], - minimum=0, - decimals=0, - tooltip=( - "Set the end frame for the export.\n" - "Only used if frame range source is 'Custom frame range'." - ) - ), - NumberDef( - "custom_handleStart", - label="Handle Start", - default=frame_defaults["handleStart"], - minimum=0, - decimals=0, - tooltip=( - "Set the start handles for the export, this will be " - "added before the start frame.\n" - "Only used if frame range source is 'Custom frame range'." - ) - ), - NumberDef( - "custom_handleEnd", - label="Handle End", - default=frame_defaults["handleEnd"], - minimum=0, - decimals=0, - tooltip=( - "Set the end handles for the export, this will be added " - "after the end frame.\n" - "Only used if frame range source is 'Custom frame range'." - ) - ) - ] diff --git a/server_addon/fusion/client/ayon_fusion/plugins/create/create_workfile.py b/server_addon/fusion/client/ayon_fusion/plugins/create/create_workfile.py deleted file mode 100644 index 3dc14861df..0000000000 --- a/server_addon/fusion/client/ayon_fusion/plugins/create/create_workfile.py +++ /dev/null @@ -1,132 +0,0 @@ -import ayon_api - -from ayon_fusion.api import ( - get_current_comp -) -from ayon_core.pipeline import ( - AutoCreator, - CreatedInstance, -) - - -class FusionWorkfileCreator(AutoCreator): - identifier = "workfile" - product_type = "workfile" - label = "Workfile" - icon = "fa5.file" - - default_variant = "Main" - - create_allow_context_change = False - - data_key = "openpype_workfile" - - def collect_instances(self): - - comp = get_current_comp() - data = comp.GetData(self.data_key) - if not data: - return - - product_name = data.get("productName") - if product_name is None: - product_name = data["subset"] - instance = CreatedInstance( - product_type=self.product_type, - product_name=product_name, - data=data, - creator=self - ) - instance.transient_data["comp"] = comp - - self._add_instance_to_context(instance) - - def update_instances(self, update_list): - for created_inst, _changes in update_list: - comp = created_inst.transient_data["comp"] - if not hasattr(comp, "SetData"): - # Comp is not alive anymore, likely closed by the user - self.log.error("Workfile comp not found for existing instance." - " Comp might have been closed in the meantime.") - continue - - # Imprint data into the comp - data = created_inst.data_to_store() - comp.SetData(self.data_key, data) - - def create(self, options=None): - comp = get_current_comp() - if not comp: - self.log.error("Unable to find current comp") - return - - existing_instance = None - for instance in self.create_context.instances: - if instance.product_type == self.product_type: - existing_instance = instance - break - - project_name = self.create_context.get_current_project_name() - folder_path = self.create_context.get_current_folder_path() - task_name = self.create_context.get_current_task_name() - host_name = self.create_context.host_name - - existing_folder_path = None - if existing_instance is not None: - existing_folder_path = existing_instance["folderPath"] - - if existing_instance is None: - folder_entity = ayon_api.get_folder_by_path( - project_name, folder_path - ) - task_entity = ayon_api.get_task_by_name( - project_name, folder_entity["id"], task_name - ) - product_name = self.get_product_name( - project_name, - folder_entity, - task_entity, - self.default_variant, - host_name, - ) - data = { - "folderPath": folder_path, - "task": task_name, - "variant": self.default_variant, - } - data.update(self.get_dynamic_data( - project_name, - folder_entity, - task_entity, - self.default_variant, - host_name, - None - - )) - - new_instance = CreatedInstance( - self.product_type, product_name, data, self - ) - new_instance.transient_data["comp"] = comp - self._add_instance_to_context(new_instance) - - elif ( - existing_folder_path != folder_path - or existing_instance["task"] != task_name - ): - folder_entity = ayon_api.get_folder_by_path( - project_name, folder_path - ) - task_entity = ayon_api.get_task_by_name( - project_name, folder_entity["id"], task_name - ) - product_name = self.get_product_name( - project_name, - folder_entity, - task_entity, - self.default_variant, - host_name, - ) - existing_instance["folderPath"] = folder_path - existing_instance["task"] = task_name - existing_instance["productName"] = product_name diff --git a/server_addon/fusion/client/ayon_fusion/plugins/inventory/select_containers.py b/server_addon/fusion/client/ayon_fusion/plugins/inventory/select_containers.py deleted file mode 100644 index e863c58ab3..0000000000 --- a/server_addon/fusion/client/ayon_fusion/plugins/inventory/select_containers.py +++ /dev/null @@ -1,27 +0,0 @@ -from ayon_core.pipeline import InventoryAction - - -class FusionSelectContainers(InventoryAction): - - label = "Select Containers" - icon = "mouse-pointer" - color = "#d8d8d8" - - def process(self, containers): - from ayon_fusion.api import ( - get_current_comp, - comp_lock_and_undo_chunk - ) - - tools = [i["_tool"] for i in containers] - - comp = get_current_comp() - flow = comp.CurrentFrame.FlowView - - with comp_lock_and_undo_chunk(comp, self.label): - # Clear selection - flow.Select() - - # Select tool - for tool in tools: - flow.Select(tool) diff --git a/server_addon/fusion/client/ayon_fusion/plugins/inventory/set_tool_color.py b/server_addon/fusion/client/ayon_fusion/plugins/inventory/set_tool_color.py deleted file mode 100644 index 2c02afe32c..0000000000 --- a/server_addon/fusion/client/ayon_fusion/plugins/inventory/set_tool_color.py +++ /dev/null @@ -1,72 +0,0 @@ -from qtpy import QtGui, QtWidgets - -from ayon_core.pipeline import InventoryAction -from ayon_core import style -from ayon_fusion.api import ( - get_current_comp, - comp_lock_and_undo_chunk -) - - -class FusionSetToolColor(InventoryAction): - """Update the color of the selected tools""" - - label = "Set Tool Color" - icon = "plus" - color = "#d8d8d8" - _fallback_color = QtGui.QColor(1.0, 1.0, 1.0) - - def process(self, containers): - """Color all selected tools the selected colors""" - - result = [] - comp = get_current_comp() - - # Get tool color - first = containers[0] - tool = first["_tool"] - color = tool.TileColor - - if color is not None: - qcolor = QtGui.QColor().fromRgbF(color["R"], color["G"], color["B"]) - else: - qcolor = self._fallback_color - - # Launch pick color - picked_color = self.get_color_picker(qcolor) - if not picked_color: - return - - with comp_lock_and_undo_chunk(comp): - for container in containers: - # Convert color to RGB 0-1 floats - rgb_f = picked_color.getRgbF() - rgb_f_table = {"R": rgb_f[0], "G": rgb_f[1], "B": rgb_f[2]} - - # Update tool - tool = container["_tool"] - tool.TileColor = rgb_f_table - - result.append(container) - - return result - - def get_color_picker(self, color): - """Launch color picker and return chosen color - - Args: - color(QtGui.QColor): Start color to display - - Returns: - QtGui.QColor - - """ - - color_dialog = QtWidgets.QColorDialog(color) - color_dialog.setStyleSheet(style.load_stylesheet()) - - accepted = color_dialog.exec_() - if not accepted: - return - - return color_dialog.selectedColor() diff --git a/server_addon/fusion/client/ayon_fusion/plugins/load/actions.py b/server_addon/fusion/client/ayon_fusion/plugins/load/actions.py deleted file mode 100644 index dfa73e0b7a..0000000000 --- a/server_addon/fusion/client/ayon_fusion/plugins/load/actions.py +++ /dev/null @@ -1,81 +0,0 @@ -"""A module containing generic loader actions that will display in the Loader. - -""" - -from ayon_core.pipeline import load - - -class FusionSetFrameRangeLoader(load.LoaderPlugin): - """Set frame range excluding pre- and post-handles""" - - product_types = { - "animation", - "camera", - "imagesequence", - "render", - "yeticache", - "pointcache", - "render", - } - representations = {"*"} - extensions = {"*"} - - label = "Set frame range" - order = 11 - icon = "clock-o" - color = "white" - - def load(self, context, name, namespace, data): - - from ayon_fusion.api import lib - - version_attributes = context["version"]["attrib"] - - start = version_attributes.get("frameStart", None) - end = version_attributes.get("frameEnd", None) - - if start is None or end is None: - print("Skipping setting frame range because start or " - "end frame data is missing..") - return - - lib.update_frame_range(start, end) - - -class FusionSetFrameRangeWithHandlesLoader(load.LoaderPlugin): - """Set frame range including pre- and post-handles""" - - product_types = { - "animation", - "camera", - "imagesequence", - "render", - "yeticache", - "pointcache", - "render", - } - representations = {"*"} - - label = "Set frame range (with handles)" - order = 12 - icon = "clock-o" - color = "white" - - def load(self, context, name, namespace, data): - - from ayon_fusion.api import lib - - version_attributes = context["version"]["attrib"] - start = version_attributes.get("frameStart", None) - end = version_attributes.get("frameEnd", None) - - if start is None or end is None: - print("Skipping setting frame range because start or " - "end frame data is missing..") - return - - # Include handles - start -= version_attributes.get("handleStart", 0) - end += version_attributes.get("handleEnd", 0) - - lib.update_frame_range(start, end) diff --git a/server_addon/fusion/client/ayon_fusion/plugins/load/load_alembic.py b/server_addon/fusion/client/ayon_fusion/plugins/load/load_alembic.py deleted file mode 100644 index 2e763b5330..0000000000 --- a/server_addon/fusion/client/ayon_fusion/plugins/load/load_alembic.py +++ /dev/null @@ -1,72 +0,0 @@ -from ayon_core.pipeline import ( - load, - get_representation_path, -) -from ayon_fusion.api import ( - imprint_container, - get_current_comp, - comp_lock_and_undo_chunk -) - - -class FusionLoadAlembicMesh(load.LoaderPlugin): - """Load Alembic mesh into Fusion""" - - product_types = {"pointcache", "model"} - representations = {"*"} - extensions = {"abc"} - - label = "Load alembic mesh" - order = -10 - icon = "code-fork" - color = "orange" - - tool_type = "SurfaceAlembicMesh" - - def load(self, context, name, namespace, data): - # Fallback to folder name when namespace is None - if namespace is None: - namespace = context["folder"]["name"] - - # Create the Loader with the filename path set - comp = get_current_comp() - with comp_lock_and_undo_chunk(comp, "Create tool"): - - path = self.filepath_from_context(context) - - args = (-32768, -32768) - tool = comp.AddTool(self.tool_type, *args) - tool["Filename"] = path - - imprint_container(tool, - name=name, - namespace=namespace, - context=context, - loader=self.__class__.__name__) - - def switch(self, container, context): - self.update(container, context) - - def update(self, container, context): - """Update Alembic path""" - - tool = container["_tool"] - assert tool.ID == self.tool_type, f"Must be {self.tool_type}" - comp = tool.Comp() - - repre_entity = context["representation"] - path = get_representation_path(repre_entity) - - with comp_lock_and_undo_chunk(comp, "Update tool"): - tool["Filename"] = path - - # Update the imprinted representation - tool.SetData("avalon.representation", repre_entity["id"]) - - def remove(self, container): - tool = container["_tool"] - assert tool.ID == self.tool_type, f"Must be {self.tool_type}" - comp = tool.Comp() - - with comp_lock_and_undo_chunk(comp, "Remove tool"): - tool.Delete() diff --git a/server_addon/fusion/client/ayon_fusion/plugins/load/load_fbx.py b/server_addon/fusion/client/ayon_fusion/plugins/load/load_fbx.py deleted file mode 100644 index a080fa3983..0000000000 --- a/server_addon/fusion/client/ayon_fusion/plugins/load/load_fbx.py +++ /dev/null @@ -1,87 +0,0 @@ -from ayon_core.pipeline import ( - load, - get_representation_path, -) -from ayon_fusion.api import ( - imprint_container, - get_current_comp, - comp_lock_and_undo_chunk, -) - - -class FusionLoadFBXMesh(load.LoaderPlugin): - """Load FBX mesh into Fusion""" - - product_types = {"*"} - representations = {"*"} - extensions = { - "3ds", - "amc", - "aoa", - "asf", - "bvh", - "c3d", - "dae", - "dxf", - "fbx", - "htr", - "mcd", - "obj", - "trc", - } - - label = "Load FBX mesh" - order = -10 - icon = "code-fork" - color = "orange" - - tool_type = "SurfaceFBXMesh" - - def load(self, context, name, namespace, data): - # Fallback to folder name when namespace is None - if namespace is None: - namespace = context["folder"]["name"] - - # Create the Loader with the filename path set - comp = get_current_comp() - with comp_lock_and_undo_chunk(comp, "Create tool"): - path = self.filepath_from_context(context) - - args = (-32768, -32768) - tool = comp.AddTool(self.tool_type, *args) - tool["ImportFile"] = path - - imprint_container( - tool, - name=name, - namespace=namespace, - context=context, - loader=self.__class__.__name__, - ) - - def switch(self, container, context): - self.update(container, context) - - def update(self, container, context): - """Update path""" - - tool = container["_tool"] - assert tool.ID == self.tool_type, f"Must be {self.tool_type}" - comp = tool.Comp() - - repre_entity = context["representation"] - path = get_representation_path(repre_entity) - - with comp_lock_and_undo_chunk(comp, "Update tool"): - tool["ImportFile"] = path - - # Update the imprinted representation - tool.SetData("avalon.representation", repre_entity["id"]) - - def remove(self, container): - tool = container["_tool"] - assert tool.ID == self.tool_type, f"Must be {self.tool_type}" - comp = tool.Comp() - - with comp_lock_and_undo_chunk(comp, "Remove tool"): - tool.Delete() diff --git a/server_addon/fusion/client/ayon_fusion/plugins/load/load_sequence.py b/server_addon/fusion/client/ayon_fusion/plugins/load/load_sequence.py deleted file mode 100644 index 233f1d7021..0000000000 --- a/server_addon/fusion/client/ayon_fusion/plugins/load/load_sequence.py +++ /dev/null @@ -1,291 +0,0 @@ -import contextlib - -import ayon_core.pipeline.load as load -from ayon_fusion.api import ( - imprint_container, - get_current_comp, - comp_lock_and_undo_chunk, -) -from ayon_core.lib.transcoding import IMAGE_EXTENSIONS, VIDEO_EXTENSIONS - -comp = get_current_comp() - - -@contextlib.contextmanager -def preserve_inputs(tool, inputs): - """Preserve the tool's inputs after context""" - - comp = tool.Comp() - - values = {} - for name in inputs: - tool_input = getattr(tool, name) - value = tool_input[comp.TIME_UNDEFINED] - values[name] = value - - try: - yield - finally: - for name, value in values.items(): - tool_input = getattr(tool, name) - tool_input[comp.TIME_UNDEFINED] = value - - -@contextlib.contextmanager -def preserve_trim(loader, log=None): - """Preserve the relative trim of the Loader tool. - - This tries to preserve the loader's trim (trim in and trim out) after - the context by reapplying the "amount" it trims on the clip's length at - start and end. - - """ - - # Get original trim as amount of "trimming" from length - time = loader.Comp().TIME_UNDEFINED - length = loader.GetAttrs()["TOOLIT_Clip_Length"][1] - 1 - trim_from_start = loader["ClipTimeStart"][time] - trim_from_end = length - loader["ClipTimeEnd"][time] - - try: - yield - finally: - length = loader.GetAttrs()["TOOLIT_Clip_Length"][1] - 1 - if trim_from_start > length: - trim_from_start = length - if log: - log.warning( - "Reducing trim in to %d " - "(because of less frames)" % trim_from_start - ) - - remainder = length - trim_from_start - if trim_from_end > remainder: - trim_from_end = remainder - if log: - log.warning( - "Reducing trim in to %d " - "(because of less frames)" % trim_from_end - ) - - loader["ClipTimeStart"][time] = trim_from_start - loader["ClipTimeEnd"][time] = length - trim_from_end - - -def loader_shift(loader, frame, relative=True): - """Shift global in time by i preserving duration - - This moves the loader by i frames preserving global duration. When relative - is False it will shift the global in to the start frame. - - Args: - loader (tool): The fusion loader tool. - frame (int): The amount of frames to move. - relative (bool): When True the shift is relative, else the shift will - change the global in to frame. - - Returns: - int: The resulting relative frame change (how much it moved) - - """ - comp = loader.Comp() - time = comp.TIME_UNDEFINED - - old_in = loader["GlobalIn"][time] - old_out = loader["GlobalOut"][time] - - if relative: - shift = frame - else: - shift = frame - old_in - - if not shift: - return 0 - - # Shifting global in will try to automatically compensate for the change - # in the "ClipTimeStart" and "HoldFirstFrame" inputs, so we preserve those - # input values to "just shift" the clip - with preserve_inputs( - loader, - inputs=[ - "ClipTimeStart", - "ClipTimeEnd", - "HoldFirstFrame", - "HoldLastFrame", - ], - ): - # GlobalIn cannot be set past GlobalOut or vice versa - # so we must apply them in the order of the shift. - if shift > 0: - loader["GlobalOut"][time] = old_out + shift - loader["GlobalIn"][time] = old_in + shift - else: - loader["GlobalIn"][time] = old_in + shift - loader["GlobalOut"][time] = old_out + shift - - return int(shift) - - -class FusionLoadSequence(load.LoaderPlugin): - """Load image sequence into Fusion""" - - product_types = { - "imagesequence", - "review", - "render", - "plate", - "image", - "online", - } - representations = {"*"} - extensions = set( - ext.lstrip(".") for ext in IMAGE_EXTENSIONS.union(VIDEO_EXTENSIONS) - ) - - label = "Load sequence" - order = -10 - icon = "code-fork" - color = "orange" - - def load(self, context, name, namespace, data): - # Fallback to folder name when namespace is None - if namespace is None: - namespace = context["folder"]["name"] - - # Use the first file for now - path = self.filepath_from_context(context) - - # Create the Loader with the filename path set - comp = get_current_comp() - with comp_lock_and_undo_chunk(comp, "Create Loader"): - args = (-32768, -32768) - tool = comp.AddTool("Loader", *args) - tool["Clip"] = comp.ReverseMapPath(path) - - # Set global in point to start frame (if in version.data) - start = self._get_start(context["version"], tool) - loader_shift(tool, start, relative=False) - - imprint_container( - tool, - name=name, - namespace=namespace, - context=context, - loader=self.__class__.__name__, - ) - - def switch(self, container, context): - self.update(container, context) - - def update(self, container, context): - """Update the Loader's path - - Fusion automatically tries to reset some variables when changing - the loader's path to a new file. These automatic changes are to its - inputs: - - ClipTimeStart: Fusion reset to 0 if duration changes - - We keep the trim in as close as possible to the previous value. - When there are less frames then the amount of trim we reduce - it accordingly. - - - ClipTimeEnd: Fusion reset to 0 if duration changes - - We keep the trim out as close as possible to the previous value - within new amount of frames after trim in (ClipTimeStart) has - been set. - - - GlobalIn: Fusion reset to comp's global in if duration changes - - We change it to the "frameStart" - - - GlobalEnd: Fusion resets to globalIn + length if duration changes - - We do the same like Fusion - allow fusion to take control. - - - HoldFirstFrame: Fusion resets this to 0 - - We preserve the value. - - - HoldLastFrame: Fusion resets this to 0 - - We preserve the value. - - - Reverse: Fusion resets to disabled if "Loop" is not enabled. - - We preserve the value. - - - Depth: Fusion resets to "Format" - - We preserve the value. - - - KeyCode: Fusion resets to "" - - We preserve the value. - - - TimeCodeOffset: Fusion resets to 0 - - We preserve the value. - - """ - - tool = container["_tool"] - assert tool.ID == "Loader", "Must be Loader" - comp = tool.Comp() - - repre_entity = context["representation"] - path = self.filepath_from_context(context) - - # Get start frame from version data - start = self._get_start(context["version"], tool) - - with comp_lock_and_undo_chunk(comp, "Update Loader"): - # Update the loader's path whilst preserving some values - with preserve_trim(tool, log=self.log): - with preserve_inputs( - tool, - inputs=( - "HoldFirstFrame", - "HoldLastFrame", - "Reverse", - "Depth", - "KeyCode", - "TimeCodeOffset", - ), - ): - tool["Clip"] = comp.ReverseMapPath(path) - - # Set the global in to the start frame of the sequence - global_in_changed = loader_shift(tool, start, relative=False) - if global_in_changed: - # Log this change to the user - self.log.debug( - "Changed '%s' global in: %d" % (tool.Name, start) - ) - - # Update the imprinted representation - tool.SetData("avalon.representation", repre_entity["id"]) - - def remove(self, container): - tool = container["_tool"] - assert tool.ID == "Loader", "Must be Loader" - comp = tool.Comp() - - with comp_lock_and_undo_chunk(comp, "Remove Loader"): - tool.Delete() - - def _get_start(self, version_entity, tool): - """Return real start frame of published files (incl. handles)""" - attributes = version_entity["attrib"] - - # Get start frame directly with handle if it's in data - start = attributes.get("frameStartHandle") - if start is not None: - return start - - # Get frame start without handles - start = attributes.get("frameStart") - if start is None: - self.log.warning( - "Missing start frame for version " - "assuming starts at frame 0 for: " - "{}".format(tool.Name) - ) - return 0 - - # Use `handleStart` if the data is available - handle_start = attributes.get("handleStart") - if handle_start: - start -= handle_start - - return start diff --git a/server_addon/fusion/client/ayon_fusion/plugins/load/load_usd.py b/server_addon/fusion/client/ayon_fusion/plugins/load/load_usd.py deleted file mode 100644 index 42ce339faf..0000000000 --- a/server_addon/fusion/client/ayon_fusion/plugins/load/load_usd.py +++ /dev/null @@ -1,87 +0,0 @@ -from ayon_core.pipeline import ( - load, - get_representation_path, -) -from ayon_fusion.api import ( - imprint_container, - get_current_comp, - comp_lock_and_undo_chunk -) -from ayon_fusion.api.lib import get_fusion_module - - -class FusionLoadUSD(load.LoaderPlugin): - """Load USD into Fusion - - Support for USD was added since Fusion 18.5 - """ - - product_types = {"*"} - representations = {"*"} - extensions = {"usd", "usda", "usdz"} - - label = "Load USD" - order = -10 - icon = "code-fork" - color = "orange" - - tool_type = "uLoader" - - @classmethod - def apply_settings(cls, project_settings): - super(FusionLoadUSD, cls).apply_settings(project_settings) - if cls.enabled: - # Enable only in Fusion 18.5+ - fusion = get_fusion_module() - version = fusion.GetVersion() - major = version[1] - minor = version[2] - is_usd_supported = (major, minor) >= (18, 5) - cls.enabled = is_usd_supported - - def load(self, context, name, namespace, data): - # Fallback to folder name when namespace is None - if namespace is None: - namespace = context["folder"]["name"] - - # Create the Loader with the filename path set - comp = get_current_comp() - with comp_lock_and_undo_chunk(comp, "Create tool"): - - path = self.fname - - args = (-32768, -32768) - tool = comp.AddTool(self.tool_type, *args) - tool["Filename"] = path - - imprint_container(tool, - name=name, - namespace=namespace, - context=context, - loader=self.__class__.__name__) - - def switch(self, container, context): - self.update(container, context) - - def update(self, container, context): - - tool = container["_tool"] - assert tool.ID == self.tool_type, f"Must be {self.tool_type}" - comp = tool.Comp() - - repre_entity = context["representation"] - path = get_representation_path(repre_entity) - - with comp_lock_and_undo_chunk(comp, "Update tool"): - tool["Filename"] = path - - # Update the imprinted representation - tool.SetData("avalon.representation", repre_entity["id"]) - - def remove(self, container): - tool = container["_tool"] - assert tool.ID == self.tool_type, f"Must be {self.tool_type}" - comp = tool.Comp() - - with comp_lock_and_undo_chunk(comp, "Remove tool"): - tool.Delete() diff --git a/server_addon/fusion/client/ayon_fusion/plugins/load/load_workfile.py b/server_addon/fusion/client/ayon_fusion/plugins/load/load_workfile.py deleted file mode 100644 index c728f6b4aa..0000000000 --- a/server_addon/fusion/client/ayon_fusion/plugins/load/load_workfile.py +++ /dev/null @@ -1,33 +0,0 @@ -"""Import workfiles into your current comp. -As all imported nodes are free floating and will probably be changed there -is no update or reload function added for this plugin -""" - -from ayon_core.pipeline import load - -from ayon_fusion.api import ( - get_current_comp, - get_bmd_library, -) - - -class FusionLoadWorkfile(load.LoaderPlugin): - """Load the content of a workfile into Fusion""" - - product_types = {"workfile"} - representations = {"*"} - extensions = {"comp"} - - label = "Load Workfile" - order = -10 - icon = "code-fork" - color = "orange" - - def load(self, context, name, namespace, data): - # Get needed elements - bmd = get_bmd_library() - comp = get_current_comp() - path = self.filepath_from_context(context) - - # Paste the content of the file into the current comp - comp.Paste(bmd.readfile(path)) diff --git a/server_addon/fusion/client/ayon_fusion/plugins/publish/collect_comp.py b/server_addon/fusion/client/ayon_fusion/plugins/publish/collect_comp.py deleted file mode 100644 index 2e5bcd63db..0000000000 --- a/server_addon/fusion/client/ayon_fusion/plugins/publish/collect_comp.py +++ /dev/null @@ -1,22 +0,0 @@ -import pyblish.api - -from ayon_fusion.api import get_current_comp - - -class CollectCurrentCompFusion(pyblish.api.ContextPlugin): - """Collect current comp""" - - order = pyblish.api.CollectorOrder - 0.4 - label = "Collect Current Comp" - hosts = ["fusion"] - - def process(self, context): - """Collect all image sequence tools""" - - current_comp = get_current_comp() - assert current_comp, "Must have active Fusion composition" - context.data["currentComp"] = current_comp - - # Store path to current file - filepath = current_comp.GetAttrs().get("COMPS_FileName", "") - context.data['currentFile'] = filepath diff --git a/server_addon/fusion/client/ayon_fusion/plugins/publish/collect_comp_frame_range.py b/server_addon/fusion/client/ayon_fusion/plugins/publish/collect_comp_frame_range.py deleted file mode 100644 index 24a9a92337..0000000000 --- a/server_addon/fusion/client/ayon_fusion/plugins/publish/collect_comp_frame_range.py +++ /dev/null @@ -1,44 +0,0 @@ -import pyblish.api - - -def get_comp_render_range(comp): - """Return comp's start-end render range and global start-end range.""" - comp_attrs = comp.GetAttrs() - start = comp_attrs["COMPN_RenderStart"] - end = comp_attrs["COMPN_RenderEnd"] - global_start = comp_attrs["COMPN_GlobalStart"] - global_end = comp_attrs["COMPN_GlobalEnd"] - - # Whenever render ranges are undefined fall back - # to the comp's global start and end - if start == -1000000000: - start = global_start - if end == -1000000000: - end = global_end - - return start, end, global_start, global_end - - -class CollectFusionCompFrameRanges(pyblish.api.ContextPlugin): - """Collect current comp""" - - # We run this after CollectorOrder - 0.1 otherwise it gets - # overridden by global plug-in `CollectContextEntities` - order = pyblish.api.CollectorOrder - 0.05 - label = "Collect Comp Frame Ranges" - hosts = ["fusion"] - - def process(self, context): - """Collect all image sequence tools""" - - comp = context.data["currentComp"] - - # Store comp render ranges - start, end, global_start, global_end = get_comp_render_range(comp) - - context.data.update({ - "renderFrameStart": int(start), - "renderFrameEnd": int(end), - "compFrameStart": int(global_start), - "compFrameEnd": int(global_end) - }) diff --git a/server_addon/fusion/client/ayon_fusion/plugins/publish/collect_inputs.py b/server_addon/fusion/client/ayon_fusion/plugins/publish/collect_inputs.py deleted file mode 100644 index 002c0a5672..0000000000 --- a/server_addon/fusion/client/ayon_fusion/plugins/publish/collect_inputs.py +++ /dev/null @@ -1,116 +0,0 @@ -import pyblish.api - -from ayon_core.pipeline import registered_host - - -def collect_input_containers(tools): - """Collect containers that contain any of the node in `nodes`. - - This will return any loaded Avalon container that contains at least one of - the nodes. As such, the Avalon container is an input for it. Or in short, - there are member nodes of that container. - - Returns: - list: Input avalon containers - - """ - - # Lookup by node ids - lookup = frozenset([tool.Name for tool in tools]) - - containers = [] - host = registered_host() - for container in host.ls(): - - name = container["_tool"].Name - - # We currently assume no "groups" as containers but just single tools - # like a single "Loader" operator. As such we just check whether the - # Loader is part of the processing queue. - if name in lookup: - containers.append(container) - - return containers - - -def iter_upstream(tool): - """Yields all upstream inputs for the current tool. - - Yields: - tool: The input tools. - - """ - - def get_connected_input_tools(tool): - """Helper function that returns connected input tools for a tool.""" - inputs = [] - - # Filter only to actual types that will have sensible upstream - # connections. So we ignore just "Number" inputs as they can be - # many to iterate, slowing things down quite a bit - and in practice - # they don't have upstream connections. - VALID_INPUT_TYPES = ['Image', 'Particles', 'Mask', 'DataType3D'] - for type_ in VALID_INPUT_TYPES: - for input_ in tool.GetInputList(type_).values(): - output = input_.GetConnectedOutput() - if output: - input_tool = output.GetTool() - inputs.append(input_tool) - - return inputs - - # Initialize process queue with the node's inputs itself - queue = get_connected_input_tools(tool) - - # We keep track of which node names we have processed so far, to ensure we - # don't process the same hierarchy again. We are not pushing the tool - # itself into the set as that doesn't correctly recognize the same tool. - # Since tool names are unique in a comp in Fusion we rely on that. - collected = set(tool.Name for tool in queue) - - # Traverse upstream references for all nodes and yield them as we - # process the queue. - while queue: - upstream_tool = queue.pop() - yield upstream_tool - - # Find upstream tools that are not collected yet. - upstream_inputs = get_connected_input_tools(upstream_tool) - upstream_inputs = [t for t in upstream_inputs if - t.Name not in collected] - - queue.extend(upstream_inputs) - collected.update(tool.Name for tool in upstream_inputs) - - -class CollectUpstreamInputs(pyblish.api.InstancePlugin): - """Collect source input containers used for this publish. - - This will include `inputs` data of which loaded publishes were used in the - generation of this publish. This leaves an upstream trace to what was used - as input. - - """ - - label = "Collect Inputs" - order = pyblish.api.CollectorOrder + 0.2 - hosts = ["fusion"] - families = ["render", "image"] - - def process(self, instance): - - # Get all upstream and include itself - if not any(instance[:]): - self.log.debug("No tool found in instance, skipping..") - return - - tool = instance[0] - nodes = list(iter_upstream(tool)) - nodes.append(tool) - - # Collect containers for the given set of nodes - containers = collect_input_containers(nodes) - - inputs = [c["representation"] for c in containers] - instance.data["inputRepresentations"] = inputs - self.log.debug("Collected inputs: %s" % inputs) diff --git a/server_addon/fusion/client/ayon_fusion/plugins/publish/collect_instances.py b/server_addon/fusion/client/ayon_fusion/plugins/publish/collect_instances.py deleted file mode 100644 index 921c282877..0000000000 --- a/server_addon/fusion/client/ayon_fusion/plugins/publish/collect_instances.py +++ /dev/null @@ -1,109 +0,0 @@ -import pyblish.api - - -class CollectInstanceData(pyblish.api.InstancePlugin): - """Collect Fusion saver instances - - This additionally stores the Comp start and end render range in the - current context's data as "frameStart" and "frameEnd". - - """ - - order = pyblish.api.CollectorOrder - label = "Collect Instances Data" - hosts = ["fusion"] - - def process(self, instance): - """Collect all image sequence tools""" - - context = instance.context - - # Include creator attributes directly as instance data - creator_attributes = instance.data["creator_attributes"] - instance.data.update(creator_attributes) - - frame_range_source = creator_attributes.get("frame_range_source") - instance.data["frame_range_source"] = frame_range_source - - # get folder frame ranges to all instances - # render product type instances `current_folder` render target - start = context.data["frameStart"] - end = context.data["frameEnd"] - handle_start = context.data["handleStart"] - handle_end = context.data["handleEnd"] - start_with_handle = start - handle_start - end_with_handle = end + handle_end - - # conditions for render product type instances - if frame_range_source == "render_range": - # set comp render frame ranges - start = context.data["renderFrameStart"] - end = context.data["renderFrameEnd"] - handle_start = 0 - handle_end = 0 - start_with_handle = start - end_with_handle = end - - if frame_range_source == "comp_range": - comp_start = context.data["compFrameStart"] - comp_end = context.data["compFrameEnd"] - render_start = context.data["renderFrameStart"] - render_end = context.data["renderFrameEnd"] - # set comp frame ranges - start = render_start - end = render_end - handle_start = render_start - comp_start - handle_end = comp_end - render_end - start_with_handle = comp_start - end_with_handle = comp_end - - if frame_range_source == "custom_range": - start = int(instance.data["custom_frameStart"]) - end = int(instance.data["custom_frameEnd"]) - handle_start = int(instance.data["custom_handleStart"]) - handle_end = int(instance.data["custom_handleEnd"]) - start_with_handle = start - handle_start - end_with_handle = end + handle_end - - frame = instance.data["creator_attributes"].get("frame") - # explicitly publishing only single frame - if frame is not None: - frame = int(frame) - - start = frame - end = frame - handle_start = 0 - handle_end = 0 - start_with_handle = frame - end_with_handle = frame - - # Include start and end render frame in label - product_name = instance.data["productName"] - label = ( - "{product_name} ({start}-{end}) [{handle_start}-{handle_end}]" - ).format( - product_name=product_name, - start=int(start), - end=int(end), - handle_start=int(handle_start), - handle_end=int(handle_end) - ) - - instance.data.update({ - "label": label, - - # todo: Allow custom frame range per instance - "frameStart": start, - "frameEnd": end, - "frameStartHandle": start_with_handle, - "frameEndHandle": end_with_handle, - "handleStart": handle_start, - "handleEnd": handle_end, - "fps": context.data["fps"], - }) - - # Add review family if the instance is marked as 'review' - # This could be done through a 'review' Creator attribute. - if instance.data.get("review", False): - self.log.debug("Adding review family..") - instance.data["families"].append("review") diff --git a/server_addon/fusion/client/ayon_fusion/plugins/publish/collect_render.py b/server_addon/fusion/client/ayon_fusion/plugins/publish/collect_render.py deleted file mode 100644 index af52aee861..0000000000 --- a/server_addon/fusion/client/ayon_fusion/plugins/publish/collect_render.py +++ /dev/null @@ -1,208 +0,0 @@ -import os -import attr -import pyblish.api - -from ayon_core.pipeline import publish -from ayon_core.pipeline.publish import RenderInstance -from ayon_fusion.api.lib import get_frame_path - - -@attr.s -class FusionRenderInstance(RenderInstance): - # extend generic, composition name is needed - fps = attr.ib(default=None) - projectEntity = attr.ib(default=None) - stagingDir = attr.ib(default=None) - app_version = attr.ib(default=None) - tool = attr.ib(default=None) - workfileComp = attr.ib(default=None) - publish_attributes = attr.ib(default={}) - frameStartHandle = attr.ib(default=None) - frameEndHandle = attr.ib(default=None) - - -class CollectFusionRender( - publish.AbstractCollectRender, - publish.ColormanagedPyblishPluginMixin -): - - order = pyblish.api.CollectorOrder + 0.09 - label = "Collect Fusion Render" - hosts = ["fusion"] - - def get_instances(self, context): - - comp = context.data.get("currentComp") - comp_frame_format_prefs = comp.GetPrefs("Comp.FrameFormat") - aspect_x = comp_frame_format_prefs["AspectX"] - aspect_y = comp_frame_format_prefs["AspectY"] - - - current_file = context.data["currentFile"] - version = context.data["version"] - - project_entity = context.data["projectEntity"] - - instances = [] - for inst in context: - if not inst.data.get("active", True): - continue - - product_type = inst.data["productType"] - if product_type not in ["render", "image"]: - continue - - task_name = inst.data["task"] - tool = inst.data["transientData"]["tool"] - - instance_families = inst.data.get("families", []) - product_name = inst.data["productName"] - instance = FusionRenderInstance( - tool=tool, - workfileComp=comp, - productType=product_type, - family=product_type, - families=instance_families, - version=version, - time="", - source=current_file, - label=inst.data["label"], - productName=product_name, - folderPath=inst.data["folderPath"], - task=task_name, - attachTo=False, - setMembers='', - publish=True, - name=product_name, - resolutionWidth=comp_frame_format_prefs.get("Width"), - resolutionHeight=comp_frame_format_prefs.get("Height"), - pixelAspect=aspect_x / aspect_y, - tileRendering=False, - tilesX=0, - tilesY=0, - review="review" in instance_families, - frameStart=inst.data["frameStart"], - frameEnd=inst.data["frameEnd"], - handleStart=inst.data["handleStart"], - handleEnd=inst.data["handleEnd"], - frameStartHandle=inst.data["frameStartHandle"], - frameEndHandle=inst.data["frameEndHandle"], - frameStep=1, - fps=comp_frame_format_prefs.get("Rate"), - app_version=comp.GetApp().Version, - publish_attributes=inst.data.get("publish_attributes", {}), - - # The source instance this render instance replaces - source_instance=inst - ) - - render_target = inst.data["creator_attributes"]["render_target"] - - # Add render target family - render_target_family = f"render.{render_target}" - if render_target_family not in instance.families: - instance.families.append(render_target_family) - - # Add render target specific data - if render_target in {"local", "frames"}: - instance.projectEntity = project_entity - - if render_target == "farm": - fam = "render.farm" - if fam not in instance.families: - instance.families.append(fam) - instance.farm = True # to skip integrate - if "review" in instance.families: - # to skip ExtractReview locally - instance.families.remove("review") - instance.deadline = inst.data.get("deadline") - - instances.append(instance) - - return instances - - def post_collecting_action(self): - for instance in self._context: - if "render.frames" in instance.data.get("families", []): - # adding representation data to the instance - self._update_for_frames(instance) - - def get_expected_files(self, render_instance): - """ - Returns list of rendered files that should be created by - Deadline. These are not published directly, they are source - for later 'submit_publish_job'. - - Args: - render_instance (RenderInstance): to pull anatomy and parts used - in url - - Returns: - (list) of absolute urls to rendered file - """ - start = render_instance.frameStart - render_instance.handleStart - end = render_instance.frameEnd + render_instance.handleEnd - - comp = render_instance.workfileComp - path = comp.MapPath( - render_instance.tool["Clip"][ - render_instance.workfileComp.TIME_UNDEFINED - ] - ) - output_dir = os.path.dirname(path) - render_instance.outputDir = output_dir - - basename = os.path.basename(path) - - head, padding, ext = get_frame_path(basename) - - expected_files = [] - for frame in range(start, end + 1): - expected_files.append( - os.path.join( - output_dir, - f"{head}{str(frame).zfill(padding)}{ext}" - ) - ) - - return expected_files - - def _update_for_frames(self, instance): - """Updating instance for render.frames family - - Adding representation data to the instance. Also setting - colorspaceData to the representation based on file rules. - """ - - expected_files = instance.data["expectedFiles"] - - start = instance.data["frameStart"] - instance.data["handleStart"] - - path = expected_files[0] - basename = os.path.basename(path) - staging_dir = os.path.dirname(path) - _, padding, ext = get_frame_path(basename) - - repre = { - "name": ext[1:], - "ext": ext[1:], - "frameStart": f"%0{padding}d" % start, - "files": [os.path.basename(f) for f in expected_files], - "stagingDir": staging_dir, - } - - self.set_representation_colorspace( - representation=repre, - context=instance.context, - ) - - # review representation - if instance.data.get("review", False): - repre["tags"] = ["review"] - - # add the repre to the instance - if "representations" not in instance.data: - instance.data["representations"] = [] - instance.data["representations"].append(repre) - - return instance diff --git a/server_addon/fusion/client/ayon_fusion/plugins/publish/collect_workfile.py b/server_addon/fusion/client/ayon_fusion/plugins/publish/collect_workfile.py deleted file mode 100644 index 4c288edb3e..0000000000 --- a/server_addon/fusion/client/ayon_fusion/plugins/publish/collect_workfile.py +++ /dev/null @@ -1,26 +0,0 @@ -import os - -import pyblish.api - - -class CollectFusionWorkfile(pyblish.api.InstancePlugin): - """Collect Fusion workfile representation.""" - - order = pyblish.api.CollectorOrder + 0.1 - label = "Collect Workfile" - hosts = ["fusion"] - families = ["workfile"] - - def process(self, instance): - - current_file = instance.context.data["currentFile"] - - folder, file = os.path.split(current_file) - filename, ext = os.path.splitext(file) - - instance.data['representations'] = [{ - 'name': ext.lstrip("."), - 'ext': ext.lstrip("."), - 'files': file, - "stagingDir": folder, - }] diff --git a/server_addon/fusion/client/ayon_fusion/plugins/publish/extract_render_local.py b/server_addon/fusion/client/ayon_fusion/plugins/publish/extract_render_local.py deleted file mode 100644 index bbcba5366d..0000000000 --- a/server_addon/fusion/client/ayon_fusion/plugins/publish/extract_render_local.py +++ /dev/null @@ -1,207 +0,0 @@ -import os -import logging -import contextlib -import collections -import pyblish.api - -from ayon_core.pipeline import publish -from ayon_fusion.api import comp_lock_and_undo_chunk -from ayon_fusion.api.lib import get_frame_path, maintained_comp_range - -log = logging.getLogger(__name__) - - -@contextlib.contextmanager -def enabled_savers(comp, savers): - """Enable only the `savers` in Comp during the context. - - Any Saver tool in the passed composition that is not in the savers list - will be set to passthrough during the context. - - Args: - comp (object): Fusion composition object. - savers (list): List of Saver tool objects. - - """ - passthrough_key = "TOOLB_PassThrough" - original_states = {} - enabled_saver_names = {saver.Name for saver in savers} - - all_savers = comp.GetToolList(False, "Saver").values() - savers_by_name = {saver.Name: saver for saver in all_savers} - - try: - for saver in all_savers: - original_state = saver.GetAttrs()[passthrough_key] - original_states[saver.Name] = original_state - - # The passthrough state we want to set (passthrough != enabled) - state = saver.Name not in enabled_saver_names - if state != original_state: - saver.SetAttrs({passthrough_key: state}) - yield - finally: - for saver_name, original_state in original_states.items(): - saver = savers_by_name[saver_name] - saver.SetAttrs({"TOOLB_PassThrough": original_state}) - - -class FusionRenderLocal( - pyblish.api.InstancePlugin, - publish.ColormanagedPyblishPluginMixin -): - """Render the current Fusion composition locally.""" - - order = pyblish.api.ExtractorOrder - 0.2 - label = "Render Local" - hosts = ["fusion"] - families = ["render.local"] - - is_rendered_key = "_fusionrenderlocal_has_rendered" - - def process(self, instance): - - # Start render - result = self.render(instance) - if result is False: - raise RuntimeError(f"Comp render failed for {instance}") - - self._add_representation(instance) - - # Log render status - self.log.info( - "Rendered '{}' for folder '{}' under the task '{}'".format( - instance.data["name"], - instance.data["folderPath"], - instance.data["task"], - ) - ) - - def render(self, instance): - """Render instance. - - We try to render the minimal amount of times by combining the instances - that have a matching frame range in one Fusion render. Then for the - batch of instances we store whether the render succeeded or failed. - - """ - - if self.is_rendered_key in instance.data: - # This instance was already processed in batch with another - # instance, so we just return the render result directly - self.log.debug(f"Instance {instance} was already rendered") - return instance.data[self.is_rendered_key] - - instances_by_frame_range = self.get_render_instances_by_frame_range( - instance.context - ) - - # Render matching batch of instances that share the same frame range - frame_range = self.get_instance_render_frame_range(instance) - render_instances = instances_by_frame_range[frame_range] - - # We initialize render state false to indicate it wasn't successful - # yet to keep track of whether Fusion succeeded. This is for cases - # where an error below this might cause the comp render result not - # to be stored for the instances of this batch - for render_instance in render_instances: - render_instance.data[self.is_rendered_key] = False - - savers_to_render = [inst.data["tool"] for inst in render_instances] - current_comp = instance.context.data["currentComp"] - frame_start, frame_end = frame_range - - self.log.info( - f"Starting Fusion render frame range {frame_start}-{frame_end}" - ) - saver_names = ", ".join(saver.Name for saver in savers_to_render) - self.log.info(f"Rendering tools: {saver_names}") - - with comp_lock_and_undo_chunk(current_comp): - with maintained_comp_range(current_comp): - with enabled_savers(current_comp, savers_to_render): - result = current_comp.Render( - { - "Start": frame_start, - "End": frame_end, - "Wait": True, - } - ) - - # Store the render state for all the rendered instances - for render_instance in render_instances: - render_instance.data[self.is_rendered_key] = bool(result) - - return result - - def _add_representation(self, instance): - """Add representation to instance""" - - expected_files = instance.data["expectedFiles"] - - start = instance.data["frameStart"] - instance.data["handleStart"] - - path = expected_files[0] - _, padding, ext = get_frame_path(path) - - staging_dir = os.path.dirname(path) - - files = [os.path.basename(f) for f in expected_files] - if len(expected_files) == 1: - files = files[0] - - repre = { - "name": ext[1:], - "ext": ext[1:], - "frameStart": f"%0{padding}d" % start, - "files": files, - "stagingDir": staging_dir, - } - - self.set_representation_colorspace( - representation=repre, - context=instance.context, - ) - - # review representation - if instance.data.get("review", False): - repre["tags"] = ["review"] - - # add the repre to the instance - if "representations" not in instance.data: - instance.data["representations"] = [] - instance.data["representations"].append(repre) - - return instance - - def get_render_instances_by_frame_range(self, context): - """Return enabled render.local instances grouped by their frame range. - - Arguments: - context (pyblish.Context): The pyblish context - - Returns: - dict: (start, end): instances mapping - - """ - - instances_to_render = [ - instance for instance in context if - # Only active instances - instance.data.get("publish", True) and - # Only render.local instances - "render.local" in instance.data.get("families", []) - ] - - # Instances by frame ranges - instances_by_frame_range = collections.defaultdict(list) - for instance in instances_to_render: - start, end = self.get_instance_render_frame_range(instance) - instances_by_frame_range[(start, end)].append(instance) - - return dict(instances_by_frame_range) - - def get_instance_render_frame_range(self, instance): - start = instance.data["frameStartHandle"] - end = instance.data["frameEndHandle"] - return start, end diff --git a/server_addon/fusion/client/ayon_fusion/plugins/publish/increment_current_file.py b/server_addon/fusion/client/ayon_fusion/plugins/publish/increment_current_file.py deleted file mode 100644 index bcff27b988..0000000000 --- a/server_addon/fusion/client/ayon_fusion/plugins/publish/increment_current_file.py +++ /dev/null @@ -1,44 +0,0 @@ -import pyblish.api - -from ayon_core.pipeline import OptionalPyblishPluginMixin -from ayon_core.pipeline import KnownPublishError - - -class FusionIncrementCurrentFile( - pyblish.api.ContextPlugin, OptionalPyblishPluginMixin -): - """Increment the current file. - - Saves the current file with an increased version number. - - """ - - label = "Increment workfile version" - order = pyblish.api.IntegratorOrder + 9.0 - hosts = ["fusion"] - optional = True - - def process(self, context): - if not self.is_active(context.data): - return - - from ayon_core.lib import version_up - from ayon_core.pipeline.publish import get_errored_plugins_from_context - - errored_plugins = get_errored_plugins_from_context(context) - if any( - plugin.__name__ == "FusionSubmitDeadline" - for plugin in errored_plugins - ): - raise KnownPublishError( - "Skipping incrementing current file because " - "submission to render farm failed." - ) - - comp = context.data.get("currentComp") - assert comp, "Must have comp" - - current_filepath = context.data["currentFile"] - new_filepath = version_up(current_filepath) - - comp.Save(new_filepath) diff --git a/server_addon/fusion/client/ayon_fusion/plugins/publish/save_scene.py b/server_addon/fusion/client/ayon_fusion/plugins/publish/save_scene.py deleted file mode 100644 index da9b6ce41f..0000000000 --- a/server_addon/fusion/client/ayon_fusion/plugins/publish/save_scene.py +++ /dev/null @@ -1,21 +0,0 @@ -import pyblish.api - - -class FusionSaveComp(pyblish.api.ContextPlugin): - """Save current comp""" - - label = "Save current file" - order = pyblish.api.ExtractorOrder - 0.49 - hosts = ["fusion"] - families = ["render", "image", "workfile"] - - def process(self, context): - - comp = context.data.get("currentComp") - assert comp, "Must have comp" - - current = comp.GetAttrs().get("COMPS_FileName", "") - assert context.data['currentFile'] == current - - self.log.info("Saving current file: {}".format(current)) - comp.Save() diff --git a/server_addon/fusion/client/ayon_fusion/plugins/publish/validate_background_depth.py b/server_addon/fusion/client/ayon_fusion/plugins/publish/validate_background_depth.py deleted file mode 100644 index 90b6b110a4..0000000000 --- a/server_addon/fusion/client/ayon_fusion/plugins/publish/validate_background_depth.py +++ /dev/null @@ -1,54 +0,0 @@ -import pyblish.api - -from ayon_core.pipeline import ( - publish, - OptionalPyblishPluginMixin, - PublishValidationError, -) - -from ayon_fusion.api.action import SelectInvalidAction - - -class ValidateBackgroundDepth( - pyblish.api.InstancePlugin, OptionalPyblishPluginMixin -): - """Validate if all Background tool are set to float32 bit""" - - order = pyblish.api.ValidatorOrder - label = "Validate Background Depth 32 bit" - hosts = ["fusion"] - families = ["render", "image"] - optional = True - - actions = [SelectInvalidAction, publish.RepairAction] - - @classmethod - def get_invalid(cls, instance): - context = instance.context - comp = context.data.get("currentComp") - assert comp, "Must have Comp object" - - backgrounds = comp.GetToolList(False, "Background").values() - if not backgrounds: - return [] - - return [i for i in backgrounds if i.GetInput("Depth") != 4.0] - - def process(self, instance): - if not self.is_active(instance.data): - return - - invalid = self.get_invalid(instance) - if invalid: - raise PublishValidationError( - "Found {} Backgrounds tools which" - " are not set to float32".format(len(invalid)), - title=self.label, - ) - - @classmethod - def repair(cls, instance): - comp = instance.context.data.get("currentComp") - invalid = cls.get_invalid(instance) - for i in invalid: - i.SetInput("Depth", 4.0, comp.TIME_UNDEFINED) diff --git a/server_addon/fusion/client/ayon_fusion/plugins/publish/validate_comp_saved.py b/server_addon/fusion/client/ayon_fusion/plugins/publish/validate_comp_saved.py deleted file mode 100644 index ba56c40b65..0000000000 --- a/server_addon/fusion/client/ayon_fusion/plugins/publish/validate_comp_saved.py +++ /dev/null @@ -1,32 +0,0 @@ -import os - -import pyblish.api -from ayon_core.pipeline import PublishValidationError - - -class ValidateFusionCompSaved(pyblish.api.ContextPlugin): - """Ensure current comp is saved""" - - order = pyblish.api.ValidatorOrder - label = "Validate Comp Saved" - families = ["render", "image"] - hosts = ["fusion"] - - def process(self, context): - - comp = context.data.get("currentComp") - assert comp, "Must have Comp object" - attrs = comp.GetAttrs() - - filename = attrs["COMPS_FileName"] - if not filename: - raise PublishValidationError("Comp is not saved.", - title=self.label) - - if not os.path.exists(filename): - raise PublishValidationError( - "Comp file does not exist: %s" % filename, title=self.label) - - if attrs["COMPB_Modified"]: - self.log.warning("Comp is modified. Save your comp to ensure your " - "changes propagate correctly.") diff --git a/server_addon/fusion/client/ayon_fusion/plugins/publish/validate_create_folder_checked.py b/server_addon/fusion/client/ayon_fusion/plugins/publish/validate_create_folder_checked.py deleted file mode 100644 index 1b910123f0..0000000000 --- a/server_addon/fusion/client/ayon_fusion/plugins/publish/validate_create_folder_checked.py +++ /dev/null @@ -1,44 +0,0 @@ -import pyblish.api - -from ayon_core.pipeline.publish import RepairAction -from ayon_core.pipeline import PublishValidationError - -from ayon_fusion.api.action import SelectInvalidAction - - -class ValidateCreateFolderChecked(pyblish.api.InstancePlugin): - """Valid if all savers have the input attribute CreateDir checked on - - This attribute ensures that the folders to which the saver will write - will be created. - """ - - order = pyblish.api.ValidatorOrder - label = "Validate Create Folder Checked" - families = ["render", "image"] - hosts = ["fusion"] - actions = [RepairAction, SelectInvalidAction] - - @classmethod - def get_invalid(cls, instance): - tool = instance.data["tool"] - create_dir = tool.GetInput("CreateDir") - if create_dir == 0.0: - cls.log.error( - "%s has Create Folder turned off" % instance[0].Name - ) - return [tool] - - def process(self, instance): - invalid = self.get_invalid(instance) - if invalid: - raise PublishValidationError( - "Found Saver with Create Folder During Render checked off", - title=self.label, - ) - - @classmethod - def repair(cls, instance): - invalid = cls.get_invalid(instance) - for tool in invalid: - tool.SetInput("CreateDir", 1.0) diff --git a/server_addon/fusion/client/ayon_fusion/plugins/publish/validate_expected_frames_existence.py b/server_addon/fusion/client/ayon_fusion/plugins/publish/validate_expected_frames_existence.py deleted file mode 100644 index 6dc9642581..0000000000 --- a/server_addon/fusion/client/ayon_fusion/plugins/publish/validate_expected_frames_existence.py +++ /dev/null @@ -1,66 +0,0 @@ -import os -import pyblish.api - -from ayon_core.pipeline.publish import RepairAction -from ayon_core.pipeline import PublishValidationError - -from ayon_fusion.api.action import SelectInvalidAction - - -class ValidateLocalFramesExistence(pyblish.api.InstancePlugin): - """Checks if files for savers that's set - to publish expected frames exists - """ - - order = pyblish.api.ValidatorOrder - label = "Validate Expected Frames Exists" - families = ["render.frames"] - hosts = ["fusion"] - actions = [RepairAction, SelectInvalidAction] - - @classmethod - def get_invalid(cls, instance, non_existing_frames=None): - if non_existing_frames is None: - non_existing_frames = [] - - tool = instance.data["tool"] - - expected_files = instance.data["expectedFiles"] - - for file in expected_files: - if not os.path.exists(file): - cls.log.error( - f"Missing file: {file}" - ) - non_existing_frames.append(file) - - if len(non_existing_frames) > 0: - cls.log.error(f"Some of {tool.Name}'s files does not exist") - return [tool] - - def process(self, instance): - non_existing_frames = [] - invalid = self.get_invalid(instance, non_existing_frames) - if invalid: - raise PublishValidationError( - "{} is set to publish existing frames but " - "some frames are missing. " - "The missing file(s) are:\n\n{}".format( - invalid[0].Name, - "\n\n".join(non_existing_frames), - ), - title=self.label, - ) - - @classmethod - def repair(cls, instance): - invalid = cls.get_invalid(instance) - if invalid: - tool = instance.data["tool"] - # Change render target to local to render locally - tool.SetData("openpype.creator_attributes.render_target", "local") - - cls.log.info( - f"Reload the publisher and {tool.Name} " - "will be set to render locally" - ) diff --git a/server_addon/fusion/client/ayon_fusion/plugins/publish/validate_filename_has_extension.py b/server_addon/fusion/client/ayon_fusion/plugins/publish/validate_filename_has_extension.py deleted file mode 100644 index 471c0ca31a..0000000000 --- a/server_addon/fusion/client/ayon_fusion/plugins/publish/validate_filename_has_extension.py +++ /dev/null @@ -1,41 +0,0 @@ -import os - -import pyblish.api -from ayon_core.pipeline import PublishValidationError - -from ayon_fusion.api.action import SelectInvalidAction - - -class ValidateFilenameHasExtension(pyblish.api.InstancePlugin): - """Ensure the Saver has an extension in the filename path - - This disallows files written as `filename` instead of `filename.frame.ext`. - Fusion does not always set an extension for your filename when - changing the file format of the saver. - - """ - - order = pyblish.api.ValidatorOrder - label = "Validate Filename Has Extension" - families = ["render", "image"] - hosts = ["fusion"] - actions = [SelectInvalidAction] - - def process(self, instance): - invalid = self.get_invalid(instance) - if invalid: - raise PublishValidationError("Found Saver without an extension", - title=self.label) - - @classmethod - def get_invalid(cls, instance): - - path = instance.data["expectedFiles"][0] - fname, ext = os.path.splitext(path) - - if not ext: - tool = instance.data["tool"] - cls.log.error("%s has no extension specified" % tool.Name) - return [tool] - - return [] diff --git a/server_addon/fusion/client/ayon_fusion/plugins/publish/validate_image_frame.py b/server_addon/fusion/client/ayon_fusion/plugins/publish/validate_image_frame.py deleted file mode 100644 index 70e5ed9279..0000000000 --- a/server_addon/fusion/client/ayon_fusion/plugins/publish/validate_image_frame.py +++ /dev/null @@ -1,27 +0,0 @@ -import pyblish.api - -from ayon_core.pipeline import PublishValidationError - - -class ValidateImageFrame(pyblish.api.InstancePlugin): - """Validates that `image` product type contains only single frame.""" - - order = pyblish.api.ValidatorOrder - label = "Validate Image Frame" - families = ["image"] - hosts = ["fusion"] - - def process(self, instance): - render_start = instance.data["frameStartHandle"] - render_end = instance.data["frameEndHandle"] - too_many_frames = (isinstance(instance.data["expectedFiles"], list) - and len(instance.data["expectedFiles"]) > 1) - - if render_end - render_start > 0 or too_many_frames: - desc = ("Trying to render multiple frames. 'image' product type " - "is meant for single frame. Please use 'render' creator.") - raise PublishValidationError( - title="Frame range outside of comp range", - message=desc, - description=desc - ) diff --git a/server_addon/fusion/client/ayon_fusion/plugins/publish/validate_instance_frame_range.py b/server_addon/fusion/client/ayon_fusion/plugins/publish/validate_instance_frame_range.py deleted file mode 100644 index 0f7ef1862d..0000000000 --- a/server_addon/fusion/client/ayon_fusion/plugins/publish/validate_instance_frame_range.py +++ /dev/null @@ -1,41 +0,0 @@ -import pyblish.api - -from ayon_core.pipeline import PublishValidationError - - -class ValidateInstanceFrameRange(pyblish.api.InstancePlugin): - """Validate instance frame range is within comp's global render range.""" - - order = pyblish.api.ValidatorOrder - label = "Validate Frame Range" - families = ["render", "image"] - hosts = ["fusion"] - - def process(self, instance): - - context = instance.context - global_start = context.data["compFrameStart"] - global_end = context.data["compFrameEnd"] - - render_start = instance.data["frameStartHandle"] - render_end = instance.data["frameEndHandle"] - - if render_start < global_start or render_end > global_end: - - message = ( - f"Instance {instance} render frame range " - f"({render_start}-{render_end}) is outside of the comp's " - f"global render range ({global_start}-{global_end}) and thus " - f"can't be rendered. " - ) - description = ( - f"{message}\n\n" - f"Either update the comp's global range or the instance's " - f"frame range to ensure the comp's frame range includes the " - f"to render frame range for the instance." - ) - raise PublishValidationError( - title="Frame range outside of comp range", - message=message, - description=description - ) diff --git a/server_addon/fusion/client/ayon_fusion/plugins/publish/validate_instance_in_context.py b/server_addon/fusion/client/ayon_fusion/plugins/publish/validate_instance_in_context.py deleted file mode 100644 index 7b8b70b2fb..0000000000 --- a/server_addon/fusion/client/ayon_fusion/plugins/publish/validate_instance_in_context.py +++ /dev/null @@ -1,80 +0,0 @@ -# -*- coding: utf-8 -*- -"""Validate if instance context is the same as publish context.""" - -import pyblish.api -from ayon_fusion.api.action import SelectToolAction -from ayon_core.pipeline.publish import ( - RepairAction, - ValidateContentsOrder, - PublishValidationError, - OptionalPyblishPluginMixin -) - - -class ValidateInstanceInContextFusion(pyblish.api.InstancePlugin, - OptionalPyblishPluginMixin): - """Validator to check if instance context matches context of publish. - - When working in per-shot style you always publish data in context of - current asset (shot). This validator checks if this is so. It is optional - so it can be disabled when needed. - """ - # Similar to maya and houdini-equivalent `ValidateInstanceInContext` - - order = ValidateContentsOrder - label = "Instance in same Context" - optional = True - hosts = ["fusion"] - actions = [SelectToolAction, RepairAction] - - def process(self, instance): - if not self.is_active(instance.data): - return - - instance_context = self.get_context(instance.data) - context = self.get_context(instance.context.data) - if instance_context != context: - context_label = "{} > {}".format(*context) - instance_label = "{} > {}".format(*instance_context) - - raise PublishValidationError( - message=( - "Instance '{}' publishes to different asset than current " - "context: {}. Current context: {}".format( - instance.name, instance_label, context_label - ) - ), - description=( - "## Publishing to a different asset\n" - "There are publish instances present which are publishing " - "into a different asset than your current context.\n\n" - "Usually this is not what you want but there can be cases " - "where you might want to publish into another asset or " - "shot. If that's the case you can disable the validation " - "on the instance to ignore it." - ) - ) - - @classmethod - def repair(cls, instance): - - create_context = instance.context.data["create_context"] - instance_id = instance.data.get("instance_id") - created_instance = create_context.get_instance_by_id( - instance_id - ) - if created_instance is None: - raise RuntimeError( - f"No CreatedInstances found with id '{instance_id} " - f"in {create_context.instances_by_id}" - ) - - context_asset, context_task = cls.get_context(instance.context.data) - created_instance["folderPath"] = context_asset - created_instance["task"] = context_task - create_context.save_changes() - - @staticmethod - def get_context(data): - """Return asset, task from publishing context data""" - return data["folderPath"], data["task"] diff --git a/server_addon/fusion/client/ayon_fusion/plugins/publish/validate_saver_has_input.py b/server_addon/fusion/client/ayon_fusion/plugins/publish/validate_saver_has_input.py deleted file mode 100644 index de2cd1d862..0000000000 --- a/server_addon/fusion/client/ayon_fusion/plugins/publish/validate_saver_has_input.py +++ /dev/null @@ -1,36 +0,0 @@ -import pyblish.api -from ayon_core.pipeline import PublishValidationError - -from ayon_fusion.api.action import SelectInvalidAction - - -class ValidateSaverHasInput(pyblish.api.InstancePlugin): - """Validate saver has incoming connection - - This ensures a Saver has at least an input connection. - - """ - - order = pyblish.api.ValidatorOrder - label = "Validate Saver Has Input" - families = ["render", "image"] - hosts = ["fusion"] - actions = [SelectInvalidAction] - - @classmethod - def get_invalid(cls, instance): - - saver = instance.data["tool"] - if not saver.Input.GetConnectedOutput(): - return [saver] - - return [] - - def process(self, instance): - invalid = self.get_invalid(instance) - if invalid: - saver_name = invalid[0].Name - raise PublishValidationError( - "Saver has no incoming connection: {} ({})".format(instance, - saver_name), - title=self.label) diff --git a/server_addon/fusion/client/ayon_fusion/plugins/publish/validate_saver_passthrough.py b/server_addon/fusion/client/ayon_fusion/plugins/publish/validate_saver_passthrough.py deleted file mode 100644 index caa17168bc..0000000000 --- a/server_addon/fusion/client/ayon_fusion/plugins/publish/validate_saver_passthrough.py +++ /dev/null @@ -1,49 +0,0 @@ -import pyblish.api -from ayon_core.pipeline import PublishValidationError - -from ayon_fusion.api.action import SelectInvalidAction - - -class ValidateSaverPassthrough(pyblish.api.ContextPlugin): - """Validate saver passthrough is similar to Pyblish publish state""" - - order = pyblish.api.ValidatorOrder - label = "Validate Saver Passthrough" - families = ["render", "image"] - hosts = ["fusion"] - actions = [SelectInvalidAction] - - def process(self, context): - - # Workaround for ContextPlugin always running, even if no instance - # is present with the family - instances = pyblish.api.instances_by_plugin(instances=list(context), - plugin=self) - if not instances: - self.log.debug("Ignoring plugin.. (bugfix)") - - invalid_instances = [] - for instance in instances: - invalid = self.is_invalid(instance) - if invalid: - invalid_instances.append(instance) - - if invalid_instances: - self.log.info("Reset pyblish to collect your current scene state, " - "that should fix error.") - raise PublishValidationError( - "Invalid instances: {0}".format(invalid_instances), - title=self.label) - - def is_invalid(self, instance): - - saver = instance.data["tool"] - attr = saver.GetAttrs() - active = not attr["TOOLB_PassThrough"] - - if active != instance.data.get("publish", True): - self.log.info("Saver has different passthrough state than " - "Pyblish: {} ({})".format(instance, saver.Name)) - return [saver] - - return [] diff --git a/server_addon/fusion/client/ayon_fusion/plugins/publish/validate_saver_resolution.py b/server_addon/fusion/client/ayon_fusion/plugins/publish/validate_saver_resolution.py deleted file mode 100644 index 15d96a9afc..0000000000 --- a/server_addon/fusion/client/ayon_fusion/plugins/publish/validate_saver_resolution.py +++ /dev/null @@ -1,116 +0,0 @@ -import pyblish.api -from ayon_core.pipeline import ( - PublishValidationError, - OptionalPyblishPluginMixin, -) - -from ayon_fusion.api.action import SelectInvalidAction -from ayon_fusion.api import comp_lock_and_undo_chunk - - -class ValidateSaverResolution( - pyblish.api.InstancePlugin, OptionalPyblishPluginMixin -): - """Validate that the saver input resolution matches the folder resolution""" - - order = pyblish.api.ValidatorOrder - label = "Validate Folder Resolution" - families = ["render", "image"] - hosts = ["fusion"] - optional = True - actions = [SelectInvalidAction] - - def process(self, instance): - if not self.is_active(instance.data): - return - - resolution = self.get_resolution(instance) - expected_resolution = self.get_expected_resolution(instance) - if resolution != expected_resolution: - raise PublishValidationError( - "The input's resolution does not match " - "the folder's resolution {}x{}.\n\n" - "The input's resolution is {}x{}.".format( - expected_resolution[0], expected_resolution[1], - resolution[0], resolution[1] - ) - ) - - @classmethod - def get_invalid(cls, instance): - saver = instance.data["tool"] - try: - resolution = cls.get_resolution(instance) - except PublishValidationError: - resolution = None - expected_resolution = cls.get_expected_resolution(instance) - if resolution != expected_resolution: - return [saver] - - @classmethod - def get_resolution(cls, instance): - saver = instance.data["tool"] - first_frame = instance.data["frameStartHandle"] - return cls.get_tool_resolution(saver, frame=first_frame) - - @classmethod - def get_expected_resolution(cls, instance): - attributes = instance.data["folderEntity"]["attrib"] - return attributes["resolutionWidth"], attributes["resolutionHeight"] - - @classmethod - def get_tool_resolution(cls, tool, frame): - """Return the 2D input resolution to a Fusion tool - - If the current tool hasn't been rendered its input resolution - hasn't been saved. To combat this, add an expression in - the comments field to read the resolution - - Args - tool (Fusion Tool): The tool to query input resolution - frame (int): The frame to query the resolution on. - - Returns: - tuple: width, height as 2-tuple of integers - - """ - comp = tool.Composition - - # False undo removes the undo-stack from the undo list - with comp_lock_and_undo_chunk(comp, "Read resolution", False): - # Save old comment - old_comment = "" - has_expression = False - - if tool["Comments"][frame] not in ["", None]: - if tool["Comments"].GetExpression() is not None: - has_expression = True - old_comment = tool["Comments"].GetExpression() - tool["Comments"].SetExpression(None) - else: - old_comment = tool["Comments"][frame] - tool["Comments"][frame] = "" - # Get input width - tool["Comments"].SetExpression("self.Input.OriginalWidth") - if tool["Comments"][frame] is None: - raise PublishValidationError( - "Cannot get resolution info for frame '{}'.\n\n " - "Please check that saver has connected input.".format( - frame - ) - ) - - width = int(tool["Comments"][frame]) - - # Get input height - tool["Comments"].SetExpression("self.Input.OriginalHeight") - height = int(tool["Comments"][frame]) - - # Reset old comment - tool["Comments"].SetExpression(None) - if has_expression: - tool["Comments"].SetExpression(old_comment) - else: - tool["Comments"][frame] = old_comment - - return width, height diff --git a/server_addon/fusion/client/ayon_fusion/plugins/publish/validate_unique_subsets.py b/server_addon/fusion/client/ayon_fusion/plugins/publish/validate_unique_subsets.py deleted file mode 100644 index dd7df54da5..0000000000 --- a/server_addon/fusion/client/ayon_fusion/plugins/publish/validate_unique_subsets.py +++ /dev/null @@ -1,62 +0,0 @@ -from collections import defaultdict - -import pyblish.api -from ayon_core.pipeline import PublishValidationError - -from ayon_fusion.api.action import SelectInvalidAction - - -class ValidateUniqueSubsets(pyblish.api.ContextPlugin): - """Ensure all instances have a unique product name""" - - order = pyblish.api.ValidatorOrder - label = "Validate Unique Products" - families = ["render", "image"] - hosts = ["fusion"] - actions = [SelectInvalidAction] - - @classmethod - def get_invalid(cls, context): - - # Collect instances per product per folder - instances_per_product_folder = defaultdict(lambda: defaultdict(list)) - for instance in context: - folder_path = instance.data["folderPath"] - product_name = instance.data["productName"] - instances_per_product_folder[folder_path][product_name].append( - instance - ) - - # Find which folder + subset combination has more than one instance - # Those are considered invalid because they'd integrate to the same - # destination. - invalid = [] - for folder_path, instances_per_product in ( - instances_per_product_folder.items() - ): - for product_name, instances in instances_per_product.items(): - if len(instances) > 1: - cls.log.warning( - ( - "{folder_path} > {product_name} used by more than " - "one instance: {instances}" - ).format( - folder_path=folder_path, - product_name=product_name, - instances=instances - ) - ) - invalid.extend(instances) - - # Return tools for the invalid instances so they can be selected - invalid = [instance.data["tool"] for instance in invalid] - - return invalid - - def process(self, context): - invalid = self.get_invalid(context) - if invalid: - raise PublishValidationError( - "Multiple instances are set to the same folder > product.", - title=self.label - ) diff --git a/server_addon/fusion/client/ayon_fusion/scripts/__init__.py b/server_addon/fusion/client/ayon_fusion/scripts/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/server_addon/fusion/client/ayon_fusion/scripts/duplicate_with_inputs.py b/server_addon/fusion/client/ayon_fusion/scripts/duplicate_with_inputs.py deleted file mode 100644 index 78edb1b3ba..0000000000 --- a/server_addon/fusion/client/ayon_fusion/scripts/duplicate_with_inputs.py +++ /dev/null @@ -1,45 +0,0 @@ -from ayon_fusion.api import ( - comp_lock_and_undo_chunk, - get_current_comp -) - - -def is_connected(input): - """Return whether an input has incoming connection""" - return input.GetAttrs()["INPB_Connected"] - - -def duplicate_with_input_connections(): - """Duplicate selected tools with incoming connections.""" - - comp = get_current_comp() - original_tools = comp.GetToolList(True).values() - if not original_tools: - return # nothing selected - - with comp_lock_and_undo_chunk( - comp, "Duplicate With Input Connections"): - - # Generate duplicates - comp.Copy() - comp.SetActiveTool() - comp.Paste() - duplicate_tools = comp.GetToolList(True).values() - - # Copy connections - for original, new in zip(original_tools, duplicate_tools): - - original_inputs = original.GetInputList().values() - new_inputs = new.GetInputList().values() - assert len(original_inputs) == len(new_inputs) - - for original_input, new_input in zip(original_inputs, new_inputs): - - if is_connected(original_input): - - if is_connected(new_input): - # Already connected if it is between the copied tools - continue - - new_input.ConnectTo(original_input.GetConnectedOutput()) - assert is_connected(new_input), "Must be connected now" diff --git a/server_addon/fusion/client/ayon_fusion/vendor/attr/__init__.py b/server_addon/fusion/client/ayon_fusion/vendor/attr/__init__.py deleted file mode 100644 index b1ce7fe248..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/attr/__init__.py +++ /dev/null @@ -1,78 +0,0 @@ -from __future__ import absolute_import, division, print_function - -import sys - -from functools import partial - -from . import converters, exceptions, filters, setters, validators -from ._cmp import cmp_using -from ._config import get_run_validators, set_run_validators -from ._funcs import asdict, assoc, astuple, evolve, has, resolve_types -from ._make import ( - NOTHING, - Attribute, - Factory, - attrib, - attrs, - fields, - fields_dict, - make_class, - validate, -) -from ._version_info import VersionInfo - - -__version__ = "21.2.0" -__version_info__ = VersionInfo._from_version_string(__version__) - -__title__ = "attrs" -__description__ = "Classes Without Boilerplate" -__url__ = "https://www.attrs.org/" -__uri__ = __url__ -__doc__ = __description__ + " <" + __uri__ + ">" - -__author__ = "Hynek Schlawack" -__email__ = "hs@ox.cx" - -__license__ = "MIT" -__copyright__ = "Copyright (c) 2015 Hynek Schlawack" - - -s = attributes = attrs -ib = attr = attrib -dataclass = partial(attrs, auto_attribs=True) # happy Easter ;) - -__all__ = [ - "Attribute", - "Factory", - "NOTHING", - "asdict", - "assoc", - "astuple", - "attr", - "attrib", - "attributes", - "attrs", - "cmp_using", - "converters", - "evolve", - "exceptions", - "fields", - "fields_dict", - "filters", - "get_run_validators", - "has", - "ib", - "make_class", - "resolve_types", - "s", - "set_run_validators", - "setters", - "validate", - "validators", -] - -if sys.version_info[:2] >= (3, 6): - from ._next_gen import define, field, frozen, mutable - - __all__.extend((define, field, frozen, mutable)) diff --git a/server_addon/fusion/client/ayon_fusion/vendor/attr/__init__.pyi b/server_addon/fusion/client/ayon_fusion/vendor/attr/__init__.pyi deleted file mode 100644 index 3503b073b4..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/attr/__init__.pyi +++ /dev/null @@ -1,475 +0,0 @@ -import sys - -from typing import ( - Any, - Callable, - Dict, - Generic, - List, - Mapping, - Optional, - Sequence, - Tuple, - Type, - TypeVar, - Union, - overload, -) - -# `import X as X` is required to make these public -from . import converters as converters -from . import exceptions as exceptions -from . import filters as filters -from . import setters as setters -from . import validators as validators -from ._version_info import VersionInfo - - -__version__: str -__version_info__: VersionInfo -__title__: str -__description__: str -__url__: str -__uri__: str -__author__: str -__email__: str -__license__: str -__copyright__: str - -_T = TypeVar("_T") -_C = TypeVar("_C", bound=type) - -_EqOrderType = Union[bool, Callable[[Any], Any]] -_ValidatorType = Callable[[Any, Attribute[_T], _T], Any] -_ConverterType = Callable[[Any], Any] -_FilterType = Callable[[Attribute[_T], _T], bool] -_ReprType = Callable[[Any], str] -_ReprArgType = Union[bool, _ReprType] -_OnSetAttrType = Callable[[Any, Attribute[Any], Any], Any] -_OnSetAttrArgType = Union[ - _OnSetAttrType, List[_OnSetAttrType], setters._NoOpType -] -_FieldTransformer = Callable[[type, List[Attribute[Any]]], List[Attribute[Any]]] -# FIXME: in reality, if multiple validators are passed they must be in a list -# or tuple, but those are invariant and so would prevent subtypes of -# _ValidatorType from working when passed in a list or tuple. -_ValidatorArgType = Union[_ValidatorType[_T], Sequence[_ValidatorType[_T]]] - -# _make -- - -NOTHING: object - -# NOTE: Factory lies about its return type to make this possible: -# `x: List[int] # = Factory(list)` -# Work around mypy issue #4554 in the common case by using an overload. -if sys.version_info >= (3, 8): - from typing import Literal - - @overload - def Factory(factory: Callable[[], _T]) -> _T: ... - @overload - def Factory( - factory: Callable[[Any], _T], - takes_self: Literal[True], - ) -> _T: ... - @overload - def Factory( - factory: Callable[[], _T], - takes_self: Literal[False], - ) -> _T: ... -else: - @overload - def Factory(factory: Callable[[], _T]) -> _T: ... - @overload - def Factory( - factory: Union[Callable[[Any], _T], Callable[[], _T]], - takes_self: bool = ..., - ) -> _T: ... - -# Static type inference support via __dataclass_transform__ implemented as per: -# https://github.com/microsoft/pyright/blob/1.1.135/specs/dataclass_transforms.md -# This annotation must be applied to all overloads of "define" and "attrs" -# -# NOTE: This is a typing construct and does not exist at runtime. Extensions -# wrapping attrs decorators should declare a separate __dataclass_transform__ -# signature in the extension module using the specification linked above to -# provide pyright support. -def __dataclass_transform__( - *, - eq_default: bool = True, - order_default: bool = False, - kw_only_default: bool = False, - field_descriptors: Tuple[Union[type, Callable[..., Any]], ...] = (()), -) -> Callable[[_T], _T]: ... - -class Attribute(Generic[_T]): - name: str - default: Optional[_T] - validator: Optional[_ValidatorType[_T]] - repr: _ReprArgType - cmp: _EqOrderType - eq: _EqOrderType - order: _EqOrderType - hash: Optional[bool] - init: bool - converter: Optional[_ConverterType] - metadata: Dict[Any, Any] - type: Optional[Type[_T]] - kw_only: bool - on_setattr: _OnSetAttrType - - def evolve(self, **changes: Any) -> "Attribute[Any]": ... - -# NOTE: We had several choices for the annotation to use for type arg: -# 1) Type[_T] -# - Pros: Handles simple cases correctly -# - Cons: Might produce less informative errors in the case of conflicting -# TypeVars e.g. `attr.ib(default='bad', type=int)` -# 2) Callable[..., _T] -# - Pros: Better error messages than #1 for conflicting TypeVars -# - Cons: Terrible error messages for validator checks. -# e.g. attr.ib(type=int, validator=validate_str) -# -> error: Cannot infer function type argument -# 3) type (and do all of the work in the mypy plugin) -# - Pros: Simple here, and we could customize the plugin with our own errors. -# - Cons: Would need to write mypy plugin code to handle all the cases. -# We chose option #1. - -# `attr` lies about its return type to make the following possible: -# attr() -> Any -# attr(8) -> int -# attr(validator=) -> Whatever the callable expects. -# This makes this type of assignments possible: -# x: int = attr(8) -# -# This form catches explicit None or no default but with no other arguments -# returns Any. -@overload -def attrib( - default: None = ..., - validator: None = ..., - repr: _ReprArgType = ..., - cmp: Optional[_EqOrderType] = ..., - hash: Optional[bool] = ..., - init: bool = ..., - metadata: Optional[Mapping[Any, Any]] = ..., - type: None = ..., - converter: None = ..., - factory: None = ..., - kw_only: bool = ..., - eq: Optional[_EqOrderType] = ..., - order: Optional[_EqOrderType] = ..., - on_setattr: Optional[_OnSetAttrArgType] = ..., -) -> Any: ... - -# This form catches an explicit None or no default and infers the type from the -# other arguments. -@overload -def attrib( - default: None = ..., - validator: Optional[_ValidatorArgType[_T]] = ..., - repr: _ReprArgType = ..., - cmp: Optional[_EqOrderType] = ..., - hash: Optional[bool] = ..., - init: bool = ..., - metadata: Optional[Mapping[Any, Any]] = ..., - type: Optional[Type[_T]] = ..., - converter: Optional[_ConverterType] = ..., - factory: Optional[Callable[[], _T]] = ..., - kw_only: bool = ..., - eq: Optional[_EqOrderType] = ..., - order: Optional[_EqOrderType] = ..., - on_setattr: Optional[_OnSetAttrArgType] = ..., -) -> _T: ... - -# This form catches an explicit default argument. -@overload -def attrib( - default: _T, - validator: Optional[_ValidatorArgType[_T]] = ..., - repr: _ReprArgType = ..., - cmp: Optional[_EqOrderType] = ..., - hash: Optional[bool] = ..., - init: bool = ..., - metadata: Optional[Mapping[Any, Any]] = ..., - type: Optional[Type[_T]] = ..., - converter: Optional[_ConverterType] = ..., - factory: Optional[Callable[[], _T]] = ..., - kw_only: bool = ..., - eq: Optional[_EqOrderType] = ..., - order: Optional[_EqOrderType] = ..., - on_setattr: Optional[_OnSetAttrArgType] = ..., -) -> _T: ... - -# This form covers type=non-Type: e.g. forward references (str), Any -@overload -def attrib( - default: Optional[_T] = ..., - validator: Optional[_ValidatorArgType[_T]] = ..., - repr: _ReprArgType = ..., - cmp: Optional[_EqOrderType] = ..., - hash: Optional[bool] = ..., - init: bool = ..., - metadata: Optional[Mapping[Any, Any]] = ..., - type: object = ..., - converter: Optional[_ConverterType] = ..., - factory: Optional[Callable[[], _T]] = ..., - kw_only: bool = ..., - eq: Optional[_EqOrderType] = ..., - order: Optional[_EqOrderType] = ..., - on_setattr: Optional[_OnSetAttrArgType] = ..., -) -> Any: ... -@overload -def field( - *, - default: None = ..., - validator: None = ..., - repr: _ReprArgType = ..., - hash: Optional[bool] = ..., - init: bool = ..., - metadata: Optional[Mapping[Any, Any]] = ..., - converter: None = ..., - factory: None = ..., - kw_only: bool = ..., - eq: Optional[bool] = ..., - order: Optional[bool] = ..., - on_setattr: Optional[_OnSetAttrArgType] = ..., -) -> Any: ... - -# This form catches an explicit None or no default and infers the type from the -# other arguments. -@overload -def field( - *, - default: None = ..., - validator: Optional[_ValidatorArgType[_T]] = ..., - repr: _ReprArgType = ..., - hash: Optional[bool] = ..., - init: bool = ..., - metadata: Optional[Mapping[Any, Any]] = ..., - converter: Optional[_ConverterType] = ..., - factory: Optional[Callable[[], _T]] = ..., - kw_only: bool = ..., - eq: Optional[_EqOrderType] = ..., - order: Optional[_EqOrderType] = ..., - on_setattr: Optional[_OnSetAttrArgType] = ..., -) -> _T: ... - -# This form catches an explicit default argument. -@overload -def field( - *, - default: _T, - validator: Optional[_ValidatorArgType[_T]] = ..., - repr: _ReprArgType = ..., - hash: Optional[bool] = ..., - init: bool = ..., - metadata: Optional[Mapping[Any, Any]] = ..., - converter: Optional[_ConverterType] = ..., - factory: Optional[Callable[[], _T]] = ..., - kw_only: bool = ..., - eq: Optional[_EqOrderType] = ..., - order: Optional[_EqOrderType] = ..., - on_setattr: Optional[_OnSetAttrArgType] = ..., -) -> _T: ... - -# This form covers type=non-Type: e.g. forward references (str), Any -@overload -def field( - *, - default: Optional[_T] = ..., - validator: Optional[_ValidatorArgType[_T]] = ..., - repr: _ReprArgType = ..., - hash: Optional[bool] = ..., - init: bool = ..., - metadata: Optional[Mapping[Any, Any]] = ..., - converter: Optional[_ConverterType] = ..., - factory: Optional[Callable[[], _T]] = ..., - kw_only: bool = ..., - eq: Optional[_EqOrderType] = ..., - order: Optional[_EqOrderType] = ..., - on_setattr: Optional[_OnSetAttrArgType] = ..., -) -> Any: ... -@overload -@__dataclass_transform__(order_default=True, field_descriptors=(attrib, field)) -def attrs( - maybe_cls: _C, - these: Optional[Dict[str, Any]] = ..., - repr_ns: Optional[str] = ..., - repr: bool = ..., - cmp: Optional[_EqOrderType] = ..., - hash: Optional[bool] = ..., - init: bool = ..., - slots: bool = ..., - frozen: bool = ..., - weakref_slot: bool = ..., - str: bool = ..., - auto_attribs: bool = ..., - kw_only: bool = ..., - cache_hash: bool = ..., - auto_exc: bool = ..., - eq: Optional[_EqOrderType] = ..., - order: Optional[_EqOrderType] = ..., - auto_detect: bool = ..., - collect_by_mro: bool = ..., - getstate_setstate: Optional[bool] = ..., - on_setattr: Optional[_OnSetAttrArgType] = ..., - field_transformer: Optional[_FieldTransformer] = ..., -) -> _C: ... -@overload -@__dataclass_transform__(order_default=True, field_descriptors=(attrib, field)) -def attrs( - maybe_cls: None = ..., - these: Optional[Dict[str, Any]] = ..., - repr_ns: Optional[str] = ..., - repr: bool = ..., - cmp: Optional[_EqOrderType] = ..., - hash: Optional[bool] = ..., - init: bool = ..., - slots: bool = ..., - frozen: bool = ..., - weakref_slot: bool = ..., - str: bool = ..., - auto_attribs: bool = ..., - kw_only: bool = ..., - cache_hash: bool = ..., - auto_exc: bool = ..., - eq: Optional[_EqOrderType] = ..., - order: Optional[_EqOrderType] = ..., - auto_detect: bool = ..., - collect_by_mro: bool = ..., - getstate_setstate: Optional[bool] = ..., - on_setattr: Optional[_OnSetAttrArgType] = ..., - field_transformer: Optional[_FieldTransformer] = ..., -) -> Callable[[_C], _C]: ... -@overload -@__dataclass_transform__(field_descriptors=(attrib, field)) -def define( - maybe_cls: _C, - *, - these: Optional[Dict[str, Any]] = ..., - repr: bool = ..., - hash: Optional[bool] = ..., - init: bool = ..., - slots: bool = ..., - frozen: bool = ..., - weakref_slot: bool = ..., - str: bool = ..., - auto_attribs: bool = ..., - kw_only: bool = ..., - cache_hash: bool = ..., - auto_exc: bool = ..., - eq: Optional[bool] = ..., - order: Optional[bool] = ..., - auto_detect: bool = ..., - getstate_setstate: Optional[bool] = ..., - on_setattr: Optional[_OnSetAttrArgType] = ..., - field_transformer: Optional[_FieldTransformer] = ..., -) -> _C: ... -@overload -@__dataclass_transform__(field_descriptors=(attrib, field)) -def define( - maybe_cls: None = ..., - *, - these: Optional[Dict[str, Any]] = ..., - repr: bool = ..., - hash: Optional[bool] = ..., - init: bool = ..., - slots: bool = ..., - frozen: bool = ..., - weakref_slot: bool = ..., - str: bool = ..., - auto_attribs: bool = ..., - kw_only: bool = ..., - cache_hash: bool = ..., - auto_exc: bool = ..., - eq: Optional[bool] = ..., - order: Optional[bool] = ..., - auto_detect: bool = ..., - getstate_setstate: Optional[bool] = ..., - on_setattr: Optional[_OnSetAttrArgType] = ..., - field_transformer: Optional[_FieldTransformer] = ..., -) -> Callable[[_C], _C]: ... - -mutable = define -frozen = define # they differ only in their defaults - -# TODO: add support for returning NamedTuple from the mypy plugin -class _Fields(Tuple[Attribute[Any], ...]): - def __getattr__(self, name: str) -> Attribute[Any]: ... - -def fields(cls: type) -> _Fields: ... -def fields_dict(cls: type) -> Dict[str, Attribute[Any]]: ... -def validate(inst: Any) -> None: ... -def resolve_types( - cls: _C, - globalns: Optional[Dict[str, Any]] = ..., - localns: Optional[Dict[str, Any]] = ..., - attribs: Optional[List[Attribute[Any]]] = ..., -) -> _C: ... - -# TODO: add support for returning a proper attrs class from the mypy plugin -# we use Any instead of _CountingAttr so that e.g. `make_class('Foo', -# [attr.ib()])` is valid -def make_class( - name: str, - attrs: Union[List[str], Tuple[str, ...], Dict[str, Any]], - bases: Tuple[type, ...] = ..., - repr_ns: Optional[str] = ..., - repr: bool = ..., - cmp: Optional[_EqOrderType] = ..., - hash: Optional[bool] = ..., - init: bool = ..., - slots: bool = ..., - frozen: bool = ..., - weakref_slot: bool = ..., - str: bool = ..., - auto_attribs: bool = ..., - kw_only: bool = ..., - cache_hash: bool = ..., - auto_exc: bool = ..., - eq: Optional[_EqOrderType] = ..., - order: Optional[_EqOrderType] = ..., - collect_by_mro: bool = ..., - on_setattr: Optional[_OnSetAttrArgType] = ..., - field_transformer: Optional[_FieldTransformer] = ..., -) -> type: ... - -# _funcs -- - -# TODO: add support for returning TypedDict from the mypy plugin -# FIXME: asdict/astuple do not honor their factory args. Waiting on one of -# these: -# https://github.com/python/mypy/issues/4236 -# https://github.com/python/typing/issues/253 -def asdict( - inst: Any, - recurse: bool = ..., - filter: Optional[_FilterType[Any]] = ..., - dict_factory: Type[Mapping[Any, Any]] = ..., - retain_collection_types: bool = ..., - value_serializer: Optional[Callable[[type, Attribute[Any], Any], Any]] = ..., -) -> Dict[str, Any]: ... - -# TODO: add support for returning NamedTuple from the mypy plugin -def astuple( - inst: Any, - recurse: bool = ..., - filter: Optional[_FilterType[Any]] = ..., - tuple_factory: Type[Sequence[Any]] = ..., - retain_collection_types: bool = ..., -) -> Tuple[Any, ...]: ... -def has(cls: type) -> bool: ... -def assoc(inst: _T, **changes: Any) -> _T: ... -def evolve(inst: _T, **changes: Any) -> _T: ... - -# _config -- - -def set_run_validators(run: bool) -> None: ... -def get_run_validators() -> bool: ... - -# aliases -- - -s = attributes = attrs -ib = attr = attrib -dataclass = attrs # Technically, partial(attrs, auto_attribs=True) ;) diff --git a/server_addon/fusion/client/ayon_fusion/vendor/attr/_cmp.py b/server_addon/fusion/client/ayon_fusion/vendor/attr/_cmp.py deleted file mode 100644 index b747b603f1..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/attr/_cmp.py +++ /dev/null @@ -1,152 +0,0 @@ -from __future__ import absolute_import, division, print_function - -import functools - -from ._compat import new_class -from ._make import _make_ne - - -_operation_names = {"eq": "==", "lt": "<", "le": "<=", "gt": ">", "ge": ">="} - - -def cmp_using( - eq=None, - lt=None, - le=None, - gt=None, - ge=None, - require_same_type=True, - class_name="Comparable", -): - """ - Create a class that can be passed into `attr.ib`'s ``eq``, ``order``, and - ``cmp`` arguments to customize field comparison. - - The resulting class will have a full set of ordering methods if - at least one of ``{lt, le, gt, ge}`` and ``eq`` are provided. - - :param Optional[callable] eq: `callable` used to evaluate equality - of two objects. - :param Optional[callable] lt: `callable` used to evaluate whether - one object is less than another object. - :param Optional[callable] le: `callable` used to evaluate whether - one object is less than or equal to another object. - :param Optional[callable] gt: `callable` used to evaluate whether - one object is greater than another object. - :param Optional[callable] ge: `callable` used to evaluate whether - one object is greater than or equal to another object. - - :param bool require_same_type: When `True`, equality and ordering methods - will return `NotImplemented` if objects are not of the same type. - - :param Optional[str] class_name: Name of class. Defaults to 'Comparable'. - - See `comparison` for more details. - - .. versionadded:: 21.1.0 - """ - - body = { - "__slots__": ["value"], - "__init__": _make_init(), - "_requirements": [], - "_is_comparable_to": _is_comparable_to, - } - - # Add operations. - num_order_functions = 0 - has_eq_function = False - - if eq is not None: - has_eq_function = True - body["__eq__"] = _make_operator("eq", eq) - body["__ne__"] = _make_ne() - - if lt is not None: - num_order_functions += 1 - body["__lt__"] = _make_operator("lt", lt) - - if le is not None: - num_order_functions += 1 - body["__le__"] = _make_operator("le", le) - - if gt is not None: - num_order_functions += 1 - body["__gt__"] = _make_operator("gt", gt) - - if ge is not None: - num_order_functions += 1 - body["__ge__"] = _make_operator("ge", ge) - - type_ = new_class(class_name, (object,), {}, lambda ns: ns.update(body)) - - # Add same type requirement. - if require_same_type: - type_._requirements.append(_check_same_type) - - # Add total ordering if at least one operation was defined. - if 0 < num_order_functions < 4: - if not has_eq_function: - # functools.total_ordering requires __eq__ to be defined, - # so raise early error here to keep a nice stack. - raise ValueError( - "eq must be define is order to complete ordering from " - "lt, le, gt, ge." - ) - type_ = functools.total_ordering(type_) - - return type_ - - -def _make_init(): - """ - Create __init__ method. - """ - - def __init__(self, value): - """ - Initialize object with *value*. - """ - self.value = value - - return __init__ - - -def _make_operator(name, func): - """ - Create operator method. - """ - - def method(self, other): - if not self._is_comparable_to(other): - return NotImplemented - - result = func(self.value, other.value) - if result is NotImplemented: - return NotImplemented - - return result - - method.__name__ = "__%s__" % (name,) - method.__doc__ = "Return a %s b. Computed by attrs." % ( - _operation_names[name], - ) - - return method - - -def _is_comparable_to(self, other): - """ - Check whether `other` is comparable to `self`. - """ - for func in self._requirements: - if not func(self, other): - return False - return True - - -def _check_same_type(self, other): - """ - Return True if *self* and *other* are of the same type, False otherwise. - """ - return other.value.__class__ is self.value.__class__ diff --git a/server_addon/fusion/client/ayon_fusion/vendor/attr/_cmp.pyi b/server_addon/fusion/client/ayon_fusion/vendor/attr/_cmp.pyi deleted file mode 100644 index 7093550f0f..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/attr/_cmp.pyi +++ /dev/null @@ -1,14 +0,0 @@ -from typing import Type - -from . import _CompareWithType - - -def cmp_using( - eq: Optional[_CompareWithType], - lt: Optional[_CompareWithType], - le: Optional[_CompareWithType], - gt: Optional[_CompareWithType], - ge: Optional[_CompareWithType], - require_same_type: bool, - class_name: str, -) -> Type: ... diff --git a/server_addon/fusion/client/ayon_fusion/vendor/attr/_compat.py b/server_addon/fusion/client/ayon_fusion/vendor/attr/_compat.py deleted file mode 100644 index 6939f338da..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/attr/_compat.py +++ /dev/null @@ -1,242 +0,0 @@ -from __future__ import absolute_import, division, print_function - -import platform -import sys -import types -import warnings - - -PY2 = sys.version_info[0] == 2 -PYPY = platform.python_implementation() == "PyPy" - - -if PYPY or sys.version_info[:2] >= (3, 6): - ordered_dict = dict -else: - from collections import OrderedDict - - ordered_dict = OrderedDict - - -if PY2: - from collections import Mapping, Sequence - - from UserDict import IterableUserDict - - # We 'bundle' isclass instead of using inspect as importing inspect is - # fairly expensive (order of 10-15 ms for a modern machine in 2016) - def isclass(klass): - return isinstance(klass, (type, types.ClassType)) - - def new_class(name, bases, kwds, exec_body): - """ - A minimal stub of types.new_class that we need for make_class. - """ - ns = {} - exec_body(ns) - - return type(name, bases, ns) - - # TYPE is used in exceptions, repr(int) is different on Python 2 and 3. - TYPE = "type" - - def iteritems(d): - return d.iteritems() - - # Python 2 is bereft of a read-only dict proxy, so we make one! - class ReadOnlyDict(IterableUserDict): - """ - Best-effort read-only dict wrapper. - """ - - def __setitem__(self, key, val): - # We gently pretend we're a Python 3 mappingproxy. - raise TypeError( - "'mappingproxy' object does not support item assignment" - ) - - def update(self, _): - # We gently pretend we're a Python 3 mappingproxy. - raise AttributeError( - "'mappingproxy' object has no attribute 'update'" - ) - - def __delitem__(self, _): - # We gently pretend we're a Python 3 mappingproxy. - raise TypeError( - "'mappingproxy' object does not support item deletion" - ) - - def clear(self): - # We gently pretend we're a Python 3 mappingproxy. - raise AttributeError( - "'mappingproxy' object has no attribute 'clear'" - ) - - def pop(self, key, default=None): - # We gently pretend we're a Python 3 mappingproxy. - raise AttributeError( - "'mappingproxy' object has no attribute 'pop'" - ) - - def popitem(self): - # We gently pretend we're a Python 3 mappingproxy. - raise AttributeError( - "'mappingproxy' object has no attribute 'popitem'" - ) - - def setdefault(self, key, default=None): - # We gently pretend we're a Python 3 mappingproxy. - raise AttributeError( - "'mappingproxy' object has no attribute 'setdefault'" - ) - - def __repr__(self): - # Override to be identical to the Python 3 version. - return "mappingproxy(" + repr(self.data) + ")" - - def metadata_proxy(d): - res = ReadOnlyDict() - res.data.update(d) # We blocked update, so we have to do it like this. - return res - - def just_warn(*args, **kw): # pragma: no cover - """ - We only warn on Python 3 because we are not aware of any concrete - consequences of not setting the cell on Python 2. - """ - - -else: # Python 3 and later. - from collections.abc import Mapping, Sequence # noqa - - def just_warn(*args, **kw): - """ - We only warn on Python 3 because we are not aware of any concrete - consequences of not setting the cell on Python 2. - """ - warnings.warn( - "Running interpreter doesn't sufficiently support code object " - "introspection. Some features like bare super() or accessing " - "__class__ will not work with slotted classes.", - RuntimeWarning, - stacklevel=2, - ) - - def isclass(klass): - return isinstance(klass, type) - - TYPE = "class" - - def iteritems(d): - return d.items() - - new_class = types.new_class - - def metadata_proxy(d): - return types.MappingProxyType(dict(d)) - - -def make_set_closure_cell(): - """Return a function of two arguments (cell, value) which sets - the value stored in the closure cell `cell` to `value`. - """ - # pypy makes this easy. (It also supports the logic below, but - # why not do the easy/fast thing?) - if PYPY: - - def set_closure_cell(cell, value): - cell.__setstate__((value,)) - - return set_closure_cell - - # Otherwise gotta do it the hard way. - - # Create a function that will set its first cellvar to `value`. - def set_first_cellvar_to(value): - x = value - return - - # This function will be eliminated as dead code, but - # not before its reference to `x` forces `x` to be - # represented as a closure cell rather than a local. - def force_x_to_be_a_cell(): # pragma: no cover - return x - - try: - # Extract the code object and make sure our assumptions about - # the closure behavior are correct. - if PY2: - co = set_first_cellvar_to.func_code - else: - co = set_first_cellvar_to.__code__ - if co.co_cellvars != ("x",) or co.co_freevars != (): - raise AssertionError # pragma: no cover - - # Convert this code object to a code object that sets the - # function's first _freevar_ (not cellvar) to the argument. - if sys.version_info >= (3, 8): - # CPython 3.8+ has an incompatible CodeType signature - # (added a posonlyargcount argument) but also added - # CodeType.replace() to do this without counting parameters. - set_first_freevar_code = co.replace( - co_cellvars=co.co_freevars, co_freevars=co.co_cellvars - ) - else: - args = [co.co_argcount] - if not PY2: - args.append(co.co_kwonlyargcount) - args.extend( - [ - co.co_nlocals, - co.co_stacksize, - co.co_flags, - co.co_code, - co.co_consts, - co.co_names, - co.co_varnames, - co.co_filename, - co.co_name, - co.co_firstlineno, - co.co_lnotab, - # These two arguments are reversed: - co.co_cellvars, - co.co_freevars, - ] - ) - set_first_freevar_code = types.CodeType(*args) - - def set_closure_cell(cell, value): - # Create a function using the set_first_freevar_code, - # whose first closure cell is `cell`. Calling it will - # change the value of that cell. - setter = types.FunctionType( - set_first_freevar_code, {}, "setter", (), (cell,) - ) - # And call it to set the cell. - setter(value) - - # Make sure it works on this interpreter: - def make_func_with_cell(): - x = None - - def func(): - return x # pragma: no cover - - return func - - if PY2: - cell = make_func_with_cell().func_closure[0] - else: - cell = make_func_with_cell().__closure__[0] - set_closure_cell(cell, 100) - if cell.cell_contents != 100: - raise AssertionError # pragma: no cover - - except Exception: - return just_warn - else: - return set_closure_cell - - -set_closure_cell = make_set_closure_cell() diff --git a/server_addon/fusion/client/ayon_fusion/vendor/attr/_config.py b/server_addon/fusion/client/ayon_fusion/vendor/attr/_config.py deleted file mode 100644 index 8ec920962d..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/attr/_config.py +++ /dev/null @@ -1,23 +0,0 @@ -from __future__ import absolute_import, division, print_function - - -__all__ = ["set_run_validators", "get_run_validators"] - -_run_validators = True - - -def set_run_validators(run): - """ - Set whether or not validators are run. By default, they are run. - """ - if not isinstance(run, bool): - raise TypeError("'run' must be bool.") - global _run_validators - _run_validators = run - - -def get_run_validators(): - """ - Return whether or not validators are run. - """ - return _run_validators diff --git a/server_addon/fusion/client/ayon_fusion/vendor/attr/_funcs.py b/server_addon/fusion/client/ayon_fusion/vendor/attr/_funcs.py deleted file mode 100644 index fda508c5c4..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/attr/_funcs.py +++ /dev/null @@ -1,395 +0,0 @@ -from __future__ import absolute_import, division, print_function - -import copy - -from ._compat import iteritems -from ._make import NOTHING, _obj_setattr, fields -from .exceptions import AttrsAttributeNotFoundError - - -def asdict( - inst, - recurse=True, - filter=None, - dict_factory=dict, - retain_collection_types=False, - value_serializer=None, -): - """ - Return the ``attrs`` attribute values of *inst* as a dict. - - Optionally recurse into other ``attrs``-decorated classes. - - :param inst: Instance of an ``attrs``-decorated class. - :param bool recurse: Recurse into classes that are also - ``attrs``-decorated. - :param callable filter: A callable whose return code determines whether an - attribute or element is included (``True``) or dropped (``False``). Is - called with the `attr.Attribute` as the first argument and the - value as the second argument. - :param callable dict_factory: A callable to produce dictionaries from. For - example, to produce ordered dictionaries instead of normal Python - dictionaries, pass in ``collections.OrderedDict``. - :param bool retain_collection_types: Do not convert to ``list`` when - encountering an attribute whose type is ``tuple`` or ``set``. Only - meaningful if ``recurse`` is ``True``. - :param Optional[callable] value_serializer: A hook that is called for every - attribute or dict key/value. It receives the current instance, field - and value and must return the (updated) value. The hook is run *after* - the optional *filter* has been applied. - - :rtype: return type of *dict_factory* - - :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` - class. - - .. versionadded:: 16.0.0 *dict_factory* - .. versionadded:: 16.1.0 *retain_collection_types* - .. versionadded:: 20.3.0 *value_serializer* - """ - attrs = fields(inst.__class__) - rv = dict_factory() - for a in attrs: - v = getattr(inst, a.name) - if filter is not None and not filter(a, v): - continue - - if value_serializer is not None: - v = value_serializer(inst, a, v) - - if recurse is True: - if has(v.__class__): - rv[a.name] = asdict( - v, - True, - filter, - dict_factory, - retain_collection_types, - value_serializer, - ) - elif isinstance(v, (tuple, list, set, frozenset)): - cf = v.__class__ if retain_collection_types is True else list - rv[a.name] = cf( - [ - _asdict_anything( - i, - filter, - dict_factory, - retain_collection_types, - value_serializer, - ) - for i in v - ] - ) - elif isinstance(v, dict): - df = dict_factory - rv[a.name] = df( - ( - _asdict_anything( - kk, - filter, - df, - retain_collection_types, - value_serializer, - ), - _asdict_anything( - vv, - filter, - df, - retain_collection_types, - value_serializer, - ), - ) - for kk, vv in iteritems(v) - ) - else: - rv[a.name] = v - else: - rv[a.name] = v - return rv - - -def _asdict_anything( - val, - filter, - dict_factory, - retain_collection_types, - value_serializer, -): - """ - ``asdict`` only works on attrs instances, this works on anything. - """ - if getattr(val.__class__, "__attrs_attrs__", None) is not None: - # Attrs class. - rv = asdict( - val, - True, - filter, - dict_factory, - retain_collection_types, - value_serializer, - ) - elif isinstance(val, (tuple, list, set, frozenset)): - cf = val.__class__ if retain_collection_types is True else list - rv = cf( - [ - _asdict_anything( - i, - filter, - dict_factory, - retain_collection_types, - value_serializer, - ) - for i in val - ] - ) - elif isinstance(val, dict): - df = dict_factory - rv = df( - ( - _asdict_anything( - kk, filter, df, retain_collection_types, value_serializer - ), - _asdict_anything( - vv, filter, df, retain_collection_types, value_serializer - ), - ) - for kk, vv in iteritems(val) - ) - else: - rv = val - if value_serializer is not None: - rv = value_serializer(None, None, rv) - - return rv - - -def astuple( - inst, - recurse=True, - filter=None, - tuple_factory=tuple, - retain_collection_types=False, -): - """ - Return the ``attrs`` attribute values of *inst* as a tuple. - - Optionally recurse into other ``attrs``-decorated classes. - - :param inst: Instance of an ``attrs``-decorated class. - :param bool recurse: Recurse into classes that are also - ``attrs``-decorated. - :param callable filter: A callable whose return code determines whether an - attribute or element is included (``True``) or dropped (``False``). Is - called with the `attr.Attribute` as the first argument and the - value as the second argument. - :param callable tuple_factory: A callable to produce tuples from. For - example, to produce lists instead of tuples. - :param bool retain_collection_types: Do not convert to ``list`` - or ``dict`` when encountering an attribute which type is - ``tuple``, ``dict`` or ``set``. Only meaningful if ``recurse`` is - ``True``. - - :rtype: return type of *tuple_factory* - - :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` - class. - - .. versionadded:: 16.2.0 - """ - attrs = fields(inst.__class__) - rv = [] - retain = retain_collection_types # Very long. :/ - for a in attrs: - v = getattr(inst, a.name) - if filter is not None and not filter(a, v): - continue - if recurse is True: - if has(v.__class__): - rv.append( - astuple( - v, - recurse=True, - filter=filter, - tuple_factory=tuple_factory, - retain_collection_types=retain, - ) - ) - elif isinstance(v, (tuple, list, set, frozenset)): - cf = v.__class__ if retain is True else list - rv.append( - cf( - [ - astuple( - j, - recurse=True, - filter=filter, - tuple_factory=tuple_factory, - retain_collection_types=retain, - ) - if has(j.__class__) - else j - for j in v - ] - ) - ) - elif isinstance(v, dict): - df = v.__class__ if retain is True else dict - rv.append( - df( - ( - astuple( - kk, - tuple_factory=tuple_factory, - retain_collection_types=retain, - ) - if has(kk.__class__) - else kk, - astuple( - vv, - tuple_factory=tuple_factory, - retain_collection_types=retain, - ) - if has(vv.__class__) - else vv, - ) - for kk, vv in iteritems(v) - ) - ) - else: - rv.append(v) - else: - rv.append(v) - - return rv if tuple_factory is list else tuple_factory(rv) - - -def has(cls): - """ - Check whether *cls* is a class with ``attrs`` attributes. - - :param type cls: Class to introspect. - :raise TypeError: If *cls* is not a class. - - :rtype: bool - """ - return getattr(cls, "__attrs_attrs__", None) is not None - - -def assoc(inst, **changes): - """ - Copy *inst* and apply *changes*. - - :param inst: Instance of a class with ``attrs`` attributes. - :param changes: Keyword changes in the new copy. - - :return: A copy of inst with *changes* incorporated. - - :raise attr.exceptions.AttrsAttributeNotFoundError: If *attr_name* couldn't - be found on *cls*. - :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` - class. - - .. deprecated:: 17.1.0 - Use `evolve` instead. - """ - import warnings - - warnings.warn( - "assoc is deprecated and will be removed after 2018/01.", - DeprecationWarning, - stacklevel=2, - ) - new = copy.copy(inst) - attrs = fields(inst.__class__) - for k, v in iteritems(changes): - a = getattr(attrs, k, NOTHING) - if a is NOTHING: - raise AttrsAttributeNotFoundError( - "{k} is not an attrs attribute on {cl}.".format( - k=k, cl=new.__class__ - ) - ) - _obj_setattr(new, k, v) - return new - - -def evolve(inst, **changes): - """ - Create a new instance, based on *inst* with *changes* applied. - - :param inst: Instance of a class with ``attrs`` attributes. - :param changes: Keyword changes in the new copy. - - :return: A copy of inst with *changes* incorporated. - - :raise TypeError: If *attr_name* couldn't be found in the class - ``__init__``. - :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` - class. - - .. versionadded:: 17.1.0 - """ - cls = inst.__class__ - attrs = fields(cls) - for a in attrs: - if not a.init: - continue - attr_name = a.name # To deal with private attributes. - init_name = attr_name if attr_name[0] != "_" else attr_name[1:] - if init_name not in changes: - changes[init_name] = getattr(inst, attr_name) - - return cls(**changes) - - -def resolve_types(cls, globalns=None, localns=None, attribs=None): - """ - Resolve any strings and forward annotations in type annotations. - - This is only required if you need concrete types in `Attribute`'s *type* - field. In other words, you don't need to resolve your types if you only - use them for static type checking. - - With no arguments, names will be looked up in the module in which the class - was created. If this is not what you want, e.g. if the name only exists - inside a method, you may pass *globalns* or *localns* to specify other - dictionaries in which to look up these names. See the docs of - `typing.get_type_hints` for more details. - - :param type cls: Class to resolve. - :param Optional[dict] globalns: Dictionary containing global variables. - :param Optional[dict] localns: Dictionary containing local variables. - :param Optional[list] attribs: List of attribs for the given class. - This is necessary when calling from inside a ``field_transformer`` - since *cls* is not an ``attrs`` class yet. - - :raise TypeError: If *cls* is not a class. - :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` - class and you didn't pass any attribs. - :raise NameError: If types cannot be resolved because of missing variables. - - :returns: *cls* so you can use this function also as a class decorator. - Please note that you have to apply it **after** `attr.s`. That means - the decorator has to come in the line **before** `attr.s`. - - .. versionadded:: 20.1.0 - .. versionadded:: 21.1.0 *attribs* - - """ - try: - # Since calling get_type_hints is expensive we cache whether we've - # done it already. - cls.__attrs_types_resolved__ - except AttributeError: - import typing - - hints = typing.get_type_hints(cls, globalns=globalns, localns=localns) - for field in fields(cls) if attribs is None else attribs: - if field.name in hints: - # Since fields have been frozen we must work around it. - _obj_setattr(field, "type", hints[field.name]) - cls.__attrs_types_resolved__ = True - - # Return the class so you can use it as a decorator too. - return cls diff --git a/server_addon/fusion/client/ayon_fusion/vendor/attr/_make.py b/server_addon/fusion/client/ayon_fusion/vendor/attr/_make.py deleted file mode 100644 index a1912b1233..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/attr/_make.py +++ /dev/null @@ -1,3052 +0,0 @@ -from __future__ import absolute_import, division, print_function - -import copy -import inspect -import linecache -import sys -import threading -import uuid -import warnings - -from operator import itemgetter - -from . import _config, setters -from ._compat import ( - PY2, - PYPY, - isclass, - iteritems, - metadata_proxy, - new_class, - ordered_dict, - set_closure_cell, -) -from .exceptions import ( - DefaultAlreadySetError, - FrozenInstanceError, - NotAnAttrsClassError, - PythonTooOldError, - UnannotatedAttributeError, -) - - -if not PY2: - import typing - - -# This is used at least twice, so cache it here. -_obj_setattr = object.__setattr__ -_init_converter_pat = "__attr_converter_%s" -_init_factory_pat = "__attr_factory_{}" -_tuple_property_pat = ( - " {attr_name} = _attrs_property(_attrs_itemgetter({index}))" -) -_classvar_prefixes = ( - "typing.ClassVar", - "t.ClassVar", - "ClassVar", - "typing_extensions.ClassVar", -) -# we don't use a double-underscore prefix because that triggers -# name mangling when trying to create a slot for the field -# (when slots=True) -_hash_cache_field = "_attrs_cached_hash" - -_empty_metadata_singleton = metadata_proxy({}) - -# Unique object for unequivocal getattr() defaults. -_sentinel = object() - - -class _Nothing(object): - """ - Sentinel class to indicate the lack of a value when ``None`` is ambiguous. - - ``_Nothing`` is a singleton. There is only ever one of it. - - .. versionchanged:: 21.1.0 ``bool(NOTHING)`` is now False. - """ - - _singleton = None - - def __new__(cls): - if _Nothing._singleton is None: - _Nothing._singleton = super(_Nothing, cls).__new__(cls) - return _Nothing._singleton - - def __repr__(self): - return "NOTHING" - - def __bool__(self): - return False - - def __len__(self): - return 0 # __bool__ for Python 2 - - -NOTHING = _Nothing() -""" -Sentinel to indicate the lack of a value when ``None`` is ambiguous. -""" - - -class _CacheHashWrapper(int): - """ - An integer subclass that pickles / copies as None - - This is used for non-slots classes with ``cache_hash=True``, to avoid - serializing a potentially (even likely) invalid hash value. Since ``None`` - is the default value for uncalculated hashes, whenever this is copied, - the copy's value for the hash should automatically reset. - - See GH #613 for more details. - """ - - if PY2: - # For some reason `type(None)` isn't callable in Python 2, but we don't - # actually need a constructor for None objects, we just need any - # available function that returns None. - def __reduce__(self, _none_constructor=getattr, _args=(0, "", None)): - return _none_constructor, _args - - else: - - def __reduce__(self, _none_constructor=type(None), _args=()): - return _none_constructor, _args - - -def attrib( - default=NOTHING, - validator=None, - repr=True, - cmp=None, - hash=None, - init=True, - metadata=None, - type=None, - converter=None, - factory=None, - kw_only=False, - eq=None, - order=None, - on_setattr=None, -): - """ - Create a new attribute on a class. - - .. warning:: - - Does *not* do anything unless the class is also decorated with - `attr.s`! - - :param default: A value that is used if an ``attrs``-generated ``__init__`` - is used and no value is passed while instantiating or the attribute is - excluded using ``init=False``. - - If the value is an instance of `Factory`, its callable will be - used to construct a new value (useful for mutable data types like lists - or dicts). - - If a default is not set (or set manually to `attr.NOTHING`), a value - *must* be supplied when instantiating; otherwise a `TypeError` - will be raised. - - The default can also be set using decorator notation as shown below. - - :type default: Any value - - :param callable factory: Syntactic sugar for - ``default=attr.Factory(factory)``. - - :param validator: `callable` that is called by ``attrs``-generated - ``__init__`` methods after the instance has been initialized. They - receive the initialized instance, the `Attribute`, and the - passed value. - - The return value is *not* inspected so the validator has to throw an - exception itself. - - If a `list` is passed, its items are treated as validators and must - all pass. - - Validators can be globally disabled and re-enabled using - `get_run_validators`. - - The validator can also be set using decorator notation as shown below. - - :type validator: `callable` or a `list` of `callable`\\ s. - - :param repr: Include this attribute in the generated ``__repr__`` - method. If ``True``, include the attribute; if ``False``, omit it. By - default, the built-in ``repr()`` function is used. To override how the - attribute value is formatted, pass a ``callable`` that takes a single - value and returns a string. Note that the resulting string is used - as-is, i.e. it will be used directly *instead* of calling ``repr()`` - (the default). - :type repr: a `bool` or a `callable` to use a custom function. - - :param eq: If ``True`` (default), include this attribute in the - generated ``__eq__`` and ``__ne__`` methods that check two instances - for equality. To override how the attribute value is compared, - pass a ``callable`` that takes a single value and returns the value - to be compared. - :type eq: a `bool` or a `callable`. - - :param order: If ``True`` (default), include this attributes in the - generated ``__lt__``, ``__le__``, ``__gt__`` and ``__ge__`` methods. - To override how the attribute value is ordered, - pass a ``callable`` that takes a single value and returns the value - to be ordered. - :type order: a `bool` or a `callable`. - - :param cmp: Setting *cmp* is equivalent to setting *eq* and *order* to the - same value. Must not be mixed with *eq* or *order*. - :type cmp: a `bool` or a `callable`. - - :param Optional[bool] hash: Include this attribute in the generated - ``__hash__`` method. If ``None`` (default), mirror *eq*'s value. This - is the correct behavior according the Python spec. Setting this value - to anything else than ``None`` is *discouraged*. - :param bool init: Include this attribute in the generated ``__init__`` - method. It is possible to set this to ``False`` and set a default - value. In that case this attributed is unconditionally initialized - with the specified default value or factory. - :param callable converter: `callable` that is called by - ``attrs``-generated ``__init__`` methods to convert attribute's value - to the desired format. It is given the passed-in value, and the - returned value will be used as the new value of the attribute. The - value is converted before being passed to the validator, if any. - :param metadata: An arbitrary mapping, to be used by third-party - components. See `extending_metadata`. - :param type: The type of the attribute. In Python 3.6 or greater, the - preferred method to specify the type is using a variable annotation - (see `PEP 526 `_). - This argument is provided for backward compatibility. - Regardless of the approach used, the type will be stored on - ``Attribute.type``. - - Please note that ``attrs`` doesn't do anything with this metadata by - itself. You can use it as part of your own code or for - `static type checking `. - :param kw_only: Make this attribute keyword-only (Python 3+) - in the generated ``__init__`` (if ``init`` is ``False``, this - parameter is ignored). - :param on_setattr: Allows to overwrite the *on_setattr* setting from - `attr.s`. If left `None`, the *on_setattr* value from `attr.s` is used. - Set to `attr.setters.NO_OP` to run **no** `setattr` hooks for this - attribute -- regardless of the setting in `attr.s`. - :type on_setattr: `callable`, or a list of callables, or `None`, or - `attr.setters.NO_OP` - - .. versionadded:: 15.2.0 *convert* - .. versionadded:: 16.3.0 *metadata* - .. versionchanged:: 17.1.0 *validator* can be a ``list`` now. - .. versionchanged:: 17.1.0 - *hash* is ``None`` and therefore mirrors *eq* by default. - .. versionadded:: 17.3.0 *type* - .. deprecated:: 17.4.0 *convert* - .. versionadded:: 17.4.0 *converter* as a replacement for the deprecated - *convert* to achieve consistency with other noun-based arguments. - .. versionadded:: 18.1.0 - ``factory=f`` is syntactic sugar for ``default=attr.Factory(f)``. - .. versionadded:: 18.2.0 *kw_only* - .. versionchanged:: 19.2.0 *convert* keyword argument removed. - .. versionchanged:: 19.2.0 *repr* also accepts a custom callable. - .. deprecated:: 19.2.0 *cmp* Removal on or after 2021-06-01. - .. versionadded:: 19.2.0 *eq* and *order* - .. versionadded:: 20.1.0 *on_setattr* - .. versionchanged:: 20.3.0 *kw_only* backported to Python 2 - .. versionchanged:: 21.1.0 - *eq*, *order*, and *cmp* also accept a custom callable - .. versionchanged:: 21.1.0 *cmp* undeprecated - """ - eq, eq_key, order, order_key = _determine_attrib_eq_order( - cmp, eq, order, True - ) - - if hash is not None and hash is not True and hash is not False: - raise TypeError( - "Invalid value for hash. Must be True, False, or None." - ) - - if factory is not None: - if default is not NOTHING: - raise ValueError( - "The `default` and `factory` arguments are mutually " - "exclusive." - ) - if not callable(factory): - raise ValueError("The `factory` argument must be a callable.") - default = Factory(factory) - - if metadata is None: - metadata = {} - - # Apply syntactic sugar by auto-wrapping. - if isinstance(on_setattr, (list, tuple)): - on_setattr = setters.pipe(*on_setattr) - - if validator and isinstance(validator, (list, tuple)): - validator = and_(*validator) - - if converter and isinstance(converter, (list, tuple)): - converter = pipe(*converter) - - return _CountingAttr( - default=default, - validator=validator, - repr=repr, - cmp=None, - hash=hash, - init=init, - converter=converter, - metadata=metadata, - type=type, - kw_only=kw_only, - eq=eq, - eq_key=eq_key, - order=order, - order_key=order_key, - on_setattr=on_setattr, - ) - - -def _compile_and_eval(script, globs, locs=None, filename=""): - """ - "Exec" the script with the given global (globs) and local (locs) variables. - """ - bytecode = compile(script, filename, "exec") - eval(bytecode, globs, locs) - - -def _make_method(name, script, filename, globs=None): - """ - Create the method with the script given and return the method object. - """ - locs = {} - if globs is None: - globs = {} - - _compile_and_eval(script, globs, locs, filename) - - # In order of debuggers like PDB being able to step through the code, - # we add a fake linecache entry. - linecache.cache[filename] = ( - len(script), - None, - script.splitlines(True), - filename, - ) - - return locs[name] - - -def _make_attr_tuple_class(cls_name, attr_names): - """ - Create a tuple subclass to hold `Attribute`s for an `attrs` class. - - The subclass is a bare tuple with properties for names. - - class MyClassAttributes(tuple): - __slots__ = () - x = property(itemgetter(0)) - """ - attr_class_name = "{}Attributes".format(cls_name) - attr_class_template = [ - "class {}(tuple):".format(attr_class_name), - " __slots__ = ()", - ] - if attr_names: - for i, attr_name in enumerate(attr_names): - attr_class_template.append( - _tuple_property_pat.format(index=i, attr_name=attr_name) - ) - else: - attr_class_template.append(" pass") - globs = {"_attrs_itemgetter": itemgetter, "_attrs_property": property} - _compile_and_eval("\n".join(attr_class_template), globs) - return globs[attr_class_name] - - -# Tuple class for extracted attributes from a class definition. -# `base_attrs` is a subset of `attrs`. -_Attributes = _make_attr_tuple_class( - "_Attributes", - [ - # all attributes to build dunder methods for - "attrs", - # attributes that have been inherited - "base_attrs", - # map inherited attributes to their originating classes - "base_attrs_map", - ], -) - - -def _is_class_var(annot): - """ - Check whether *annot* is a typing.ClassVar. - - The string comparison hack is used to avoid evaluating all string - annotations which would put attrs-based classes at a performance - disadvantage compared to plain old classes. - """ - annot = str(annot) - - # Annotation can be quoted. - if annot.startswith(("'", '"')) and annot.endswith(("'", '"')): - annot = annot[1:-1] - - return annot.startswith(_classvar_prefixes) - - -def _has_own_attribute(cls, attrib_name): - """ - Check whether *cls* defines *attrib_name* (and doesn't just inherit it). - - Requires Python 3. - """ - attr = getattr(cls, attrib_name, _sentinel) - if attr is _sentinel: - return False - - for base_cls in cls.__mro__[1:]: - a = getattr(base_cls, attrib_name, None) - if attr is a: - return False - - return True - - -def _get_annotations(cls): - """ - Get annotations for *cls*. - """ - if _has_own_attribute(cls, "__annotations__"): - return cls.__annotations__ - - return {} - - -def _counter_getter(e): - """ - Key function for sorting to avoid re-creating a lambda for every class. - """ - return e[1].counter - - -def _collect_base_attrs(cls, taken_attr_names): - """ - Collect attr.ibs from base classes of *cls*, except *taken_attr_names*. - """ - base_attrs = [] - base_attr_map = {} # A dictionary of base attrs to their classes. - - # Traverse the MRO and collect attributes. - for base_cls in reversed(cls.__mro__[1:-1]): - for a in getattr(base_cls, "__attrs_attrs__", []): - if a.inherited or a.name in taken_attr_names: - continue - - a = a.evolve(inherited=True) - base_attrs.append(a) - base_attr_map[a.name] = base_cls - - # For each name, only keep the freshest definition i.e. the furthest at the - # back. base_attr_map is fine because it gets overwritten with every new - # instance. - filtered = [] - seen = set() - for a in reversed(base_attrs): - if a.name in seen: - continue - filtered.insert(0, a) - seen.add(a.name) - - return filtered, base_attr_map - - -def _collect_base_attrs_broken(cls, taken_attr_names): - """ - Collect attr.ibs from base classes of *cls*, except *taken_attr_names*. - - N.B. *taken_attr_names* will be mutated. - - Adhere to the old incorrect behavior. - - Notably it collects from the front and considers inherited attributes which - leads to the buggy behavior reported in #428. - """ - base_attrs = [] - base_attr_map = {} # A dictionary of base attrs to their classes. - - # Traverse the MRO and collect attributes. - for base_cls in cls.__mro__[1:-1]: - for a in getattr(base_cls, "__attrs_attrs__", []): - if a.name in taken_attr_names: - continue - - a = a.evolve(inherited=True) - taken_attr_names.add(a.name) - base_attrs.append(a) - base_attr_map[a.name] = base_cls - - return base_attrs, base_attr_map - - -def _transform_attrs( - cls, these, auto_attribs, kw_only, collect_by_mro, field_transformer -): - """ - Transform all `_CountingAttr`s on a class into `Attribute`s. - - If *these* is passed, use that and don't look for them on the class. - - *collect_by_mro* is True, collect them in the correct MRO order, otherwise - use the old -- incorrect -- order. See #428. - - Return an `_Attributes`. - """ - cd = cls.__dict__ - anns = _get_annotations(cls) - - if these is not None: - ca_list = [(name, ca) for name, ca in iteritems(these)] - - if not isinstance(these, ordered_dict): - ca_list.sort(key=_counter_getter) - elif auto_attribs is True: - ca_names = { - name - for name, attr in cd.items() - if isinstance(attr, _CountingAttr) - } - ca_list = [] - annot_names = set() - for attr_name, type in anns.items(): - if _is_class_var(type): - continue - annot_names.add(attr_name) - a = cd.get(attr_name, NOTHING) - - if not isinstance(a, _CountingAttr): - if a is NOTHING: - a = attrib() - else: - a = attrib(default=a) - ca_list.append((attr_name, a)) - - unannotated = ca_names - annot_names - if len(unannotated) > 0: - raise UnannotatedAttributeError( - "The following `attr.ib`s lack a type annotation: " - + ", ".join( - sorted(unannotated, key=lambda n: cd.get(n).counter) - ) - + "." - ) - else: - ca_list = sorted( - ( - (name, attr) - for name, attr in cd.items() - if isinstance(attr, _CountingAttr) - ), - key=lambda e: e[1].counter, - ) - - own_attrs = [ - Attribute.from_counting_attr( - name=attr_name, ca=ca, type=anns.get(attr_name) - ) - for attr_name, ca in ca_list - ] - - if collect_by_mro: - base_attrs, base_attr_map = _collect_base_attrs( - cls, {a.name for a in own_attrs} - ) - else: - base_attrs, base_attr_map = _collect_base_attrs_broken( - cls, {a.name for a in own_attrs} - ) - - attr_names = [a.name for a in base_attrs + own_attrs] - - AttrsClass = _make_attr_tuple_class(cls.__name__, attr_names) - - if kw_only: - own_attrs = [a.evolve(kw_only=True) for a in own_attrs] - base_attrs = [a.evolve(kw_only=True) for a in base_attrs] - - attrs = AttrsClass(base_attrs + own_attrs) - - # Mandatory vs non-mandatory attr order only matters when they are part of - # the __init__ signature and when they aren't kw_only (which are moved to - # the end and can be mandatory or non-mandatory in any order, as they will - # be specified as keyword args anyway). Check the order of those attrs: - had_default = False - for a in (a for a in attrs if a.init is not False and a.kw_only is False): - if had_default is True and a.default is NOTHING: - raise ValueError( - "No mandatory attributes allowed after an attribute with a " - "default value or factory. Attribute in question: %r" % (a,) - ) - - if had_default is False and a.default is not NOTHING: - had_default = True - - if field_transformer is not None: - attrs = field_transformer(cls, attrs) - return _Attributes((attrs, base_attrs, base_attr_map)) - - -if PYPY: - - def _frozen_setattrs(self, name, value): - """ - Attached to frozen classes as __setattr__. - """ - if isinstance(self, BaseException) and name in ( - "__cause__", - "__context__", - ): - BaseException.__setattr__(self, name, value) - return - - raise FrozenInstanceError() - - -else: - - def _frozen_setattrs(self, name, value): - """ - Attached to frozen classes as __setattr__. - """ - raise FrozenInstanceError() - - -def _frozen_delattrs(self, name): - """ - Attached to frozen classes as __delattr__. - """ - raise FrozenInstanceError() - - -class _ClassBuilder(object): - """ - Iteratively build *one* class. - """ - - __slots__ = ( - "_attr_names", - "_attrs", - "_base_attr_map", - "_base_names", - "_cache_hash", - "_cls", - "_cls_dict", - "_delete_attribs", - "_frozen", - "_has_pre_init", - "_has_post_init", - "_is_exc", - "_on_setattr", - "_slots", - "_weakref_slot", - "_has_own_setattr", - "_has_custom_setattr", - ) - - def __init__( - self, - cls, - these, - slots, - frozen, - weakref_slot, - getstate_setstate, - auto_attribs, - kw_only, - cache_hash, - is_exc, - collect_by_mro, - on_setattr, - has_custom_setattr, - field_transformer, - ): - attrs, base_attrs, base_map = _transform_attrs( - cls, - these, - auto_attribs, - kw_only, - collect_by_mro, - field_transformer, - ) - - self._cls = cls - self._cls_dict = dict(cls.__dict__) if slots else {} - self._attrs = attrs - self._base_names = set(a.name for a in base_attrs) - self._base_attr_map = base_map - self._attr_names = tuple(a.name for a in attrs) - self._slots = slots - self._frozen = frozen - self._weakref_slot = weakref_slot - self._cache_hash = cache_hash - self._has_pre_init = bool(getattr(cls, "__attrs_pre_init__", False)) - self._has_post_init = bool(getattr(cls, "__attrs_post_init__", False)) - self._delete_attribs = not bool(these) - self._is_exc = is_exc - self._on_setattr = on_setattr - - self._has_custom_setattr = has_custom_setattr - self._has_own_setattr = False - - self._cls_dict["__attrs_attrs__"] = self._attrs - - if frozen: - self._cls_dict["__setattr__"] = _frozen_setattrs - self._cls_dict["__delattr__"] = _frozen_delattrs - - self._has_own_setattr = True - - if getstate_setstate: - ( - self._cls_dict["__getstate__"], - self._cls_dict["__setstate__"], - ) = self._make_getstate_setstate() - - def __repr__(self): - return "<_ClassBuilder(cls={cls})>".format(cls=self._cls.__name__) - - def build_class(self): - """ - Finalize class based on the accumulated configuration. - - Builder cannot be used after calling this method. - """ - if self._slots is True: - return self._create_slots_class() - else: - return self._patch_original_class() - - def _patch_original_class(self): - """ - Apply accumulated methods and return the class. - """ - cls = self._cls - base_names = self._base_names - - # Clean class of attribute definitions (`attr.ib()`s). - if self._delete_attribs: - for name in self._attr_names: - if ( - name not in base_names - and getattr(cls, name, _sentinel) is not _sentinel - ): - try: - delattr(cls, name) - except AttributeError: - # This can happen if a base class defines a class - # variable and we want to set an attribute with the - # same name by using only a type annotation. - pass - - # Attach our dunder methods. - for name, value in self._cls_dict.items(): - setattr(cls, name, value) - - # If we've inherited an attrs __setattr__ and don't write our own, - # reset it to object's. - if not self._has_own_setattr and getattr( - cls, "__attrs_own_setattr__", False - ): - cls.__attrs_own_setattr__ = False - - if not self._has_custom_setattr: - cls.__setattr__ = object.__setattr__ - - return cls - - def _create_slots_class(self): - """ - Build and return a new class with a `__slots__` attribute. - """ - cd = { - k: v - for k, v in iteritems(self._cls_dict) - if k not in tuple(self._attr_names) + ("__dict__", "__weakref__") - } - - # If our class doesn't have its own implementation of __setattr__ - # (either from the user or by us), check the bases, if one of them has - # an attrs-made __setattr__, that needs to be reset. We don't walk the - # MRO because we only care about our immediate base classes. - # XXX: This can be confused by subclassing a slotted attrs class with - # XXX: a non-attrs class and subclass the resulting class with an attrs - # XXX: class. See `test_slotted_confused` for details. For now that's - # XXX: OK with us. - if not self._has_own_setattr: - cd["__attrs_own_setattr__"] = False - - if not self._has_custom_setattr: - for base_cls in self._cls.__bases__: - if base_cls.__dict__.get("__attrs_own_setattr__", False): - cd["__setattr__"] = object.__setattr__ - break - - # Traverse the MRO to collect existing slots - # and check for an existing __weakref__. - existing_slots = dict() - weakref_inherited = False - for base_cls in self._cls.__mro__[1:-1]: - if base_cls.__dict__.get("__weakref__", None) is not None: - weakref_inherited = True - existing_slots.update( - { - name: getattr(base_cls, name) - for name in getattr(base_cls, "__slots__", []) - } - ) - - base_names = set(self._base_names) - - names = self._attr_names - if ( - self._weakref_slot - and "__weakref__" not in getattr(self._cls, "__slots__", ()) - and "__weakref__" not in names - and not weakref_inherited - ): - names += ("__weakref__",) - - # We only add the names of attributes that aren't inherited. - # Setting __slots__ to inherited attributes wastes memory. - slot_names = [name for name in names if name not in base_names] - # There are slots for attributes from current class - # that are defined in parent classes. - # As their descriptors may be overriden by a child class, - # we collect them here and update the class dict - reused_slots = { - slot: slot_descriptor - for slot, slot_descriptor in iteritems(existing_slots) - if slot in slot_names - } - slot_names = [name for name in slot_names if name not in reused_slots] - cd.update(reused_slots) - if self._cache_hash: - slot_names.append(_hash_cache_field) - cd["__slots__"] = tuple(slot_names) - - qualname = getattr(self._cls, "__qualname__", None) - if qualname is not None: - cd["__qualname__"] = qualname - - # Create new class based on old class and our methods. - cls = type(self._cls)(self._cls.__name__, self._cls.__bases__, cd) - - # The following is a fix for - # https://github.com/python-attrs/attrs/issues/102. On Python 3, - # if a method mentions `__class__` or uses the no-arg super(), the - # compiler will bake a reference to the class in the method itself - # as `method.__closure__`. Since we replace the class with a - # clone, we rewrite these references so it keeps working. - for item in cls.__dict__.values(): - if isinstance(item, (classmethod, staticmethod)): - # Class- and staticmethods hide their functions inside. - # These might need to be rewritten as well. - closure_cells = getattr(item.__func__, "__closure__", None) - elif isinstance(item, property): - # Workaround for property `super()` shortcut (PY3-only). - # There is no universal way for other descriptors. - closure_cells = getattr(item.fget, "__closure__", None) - else: - closure_cells = getattr(item, "__closure__", None) - - if not closure_cells: # Catch None or the empty list. - continue - for cell in closure_cells: - try: - match = cell.cell_contents is self._cls - except ValueError: # ValueError: Cell is empty - pass - else: - if match: - set_closure_cell(cell, cls) - - return cls - - def add_repr(self, ns): - self._cls_dict["__repr__"] = self._add_method_dunders( - _make_repr(self._attrs, ns=ns) - ) - return self - - def add_str(self): - repr = self._cls_dict.get("__repr__") - if repr is None: - raise ValueError( - "__str__ can only be generated if a __repr__ exists." - ) - - def __str__(self): - return self.__repr__() - - self._cls_dict["__str__"] = self._add_method_dunders(__str__) - return self - - def _make_getstate_setstate(self): - """ - Create custom __setstate__ and __getstate__ methods. - """ - # __weakref__ is not writable. - state_attr_names = tuple( - an for an in self._attr_names if an != "__weakref__" - ) - - def slots_getstate(self): - """ - Automatically created by attrs. - """ - return tuple(getattr(self, name) for name in state_attr_names) - - hash_caching_enabled = self._cache_hash - - def slots_setstate(self, state): - """ - Automatically created by attrs. - """ - __bound_setattr = _obj_setattr.__get__(self, Attribute) - for name, value in zip(state_attr_names, state): - __bound_setattr(name, value) - - # The hash code cache is not included when the object is - # serialized, but it still needs to be initialized to None to - # indicate that the first call to __hash__ should be a cache - # miss. - if hash_caching_enabled: - __bound_setattr(_hash_cache_field, None) - - return slots_getstate, slots_setstate - - def make_unhashable(self): - self._cls_dict["__hash__"] = None - return self - - def add_hash(self): - self._cls_dict["__hash__"] = self._add_method_dunders( - _make_hash( - self._cls, - self._attrs, - frozen=self._frozen, - cache_hash=self._cache_hash, - ) - ) - - return self - - def add_init(self): - self._cls_dict["__init__"] = self._add_method_dunders( - _make_init( - self._cls, - self._attrs, - self._has_pre_init, - self._has_post_init, - self._frozen, - self._slots, - self._cache_hash, - self._base_attr_map, - self._is_exc, - self._on_setattr is not None - and self._on_setattr is not setters.NO_OP, - attrs_init=False, - ) - ) - - return self - - def add_attrs_init(self): - self._cls_dict["__attrs_init__"] = self._add_method_dunders( - _make_init( - self._cls, - self._attrs, - self._has_pre_init, - self._has_post_init, - self._frozen, - self._slots, - self._cache_hash, - self._base_attr_map, - self._is_exc, - self._on_setattr is not None - and self._on_setattr is not setters.NO_OP, - attrs_init=True, - ) - ) - - return self - - def add_eq(self): - cd = self._cls_dict - - cd["__eq__"] = self._add_method_dunders( - _make_eq(self._cls, self._attrs) - ) - cd["__ne__"] = self._add_method_dunders(_make_ne()) - - return self - - def add_order(self): - cd = self._cls_dict - - cd["__lt__"], cd["__le__"], cd["__gt__"], cd["__ge__"] = ( - self._add_method_dunders(meth) - for meth in _make_order(self._cls, self._attrs) - ) - - return self - - def add_setattr(self): - if self._frozen: - return self - - sa_attrs = {} - for a in self._attrs: - on_setattr = a.on_setattr or self._on_setattr - if on_setattr and on_setattr is not setters.NO_OP: - sa_attrs[a.name] = a, on_setattr - - if not sa_attrs: - return self - - if self._has_custom_setattr: - # We need to write a __setattr__ but there already is one! - raise ValueError( - "Can't combine custom __setattr__ with on_setattr hooks." - ) - - # docstring comes from _add_method_dunders - def __setattr__(self, name, val): - try: - a, hook = sa_attrs[name] - except KeyError: - nval = val - else: - nval = hook(self, a, val) - - _obj_setattr(self, name, nval) - - self._cls_dict["__attrs_own_setattr__"] = True - self._cls_dict["__setattr__"] = self._add_method_dunders(__setattr__) - self._has_own_setattr = True - - return self - - def _add_method_dunders(self, method): - """ - Add __module__ and __qualname__ to a *method* if possible. - """ - try: - method.__module__ = self._cls.__module__ - except AttributeError: - pass - - try: - method.__qualname__ = ".".join( - (self._cls.__qualname__, method.__name__) - ) - except AttributeError: - pass - - try: - method.__doc__ = "Method generated by attrs for class %s." % ( - self._cls.__qualname__, - ) - except AttributeError: - pass - - return method - - -_CMP_DEPRECATION = ( - "The usage of `cmp` is deprecated and will be removed on or after " - "2021-06-01. Please use `eq` and `order` instead." -) - - -def _determine_attrs_eq_order(cmp, eq, order, default_eq): - """ - Validate the combination of *cmp*, *eq*, and *order*. Derive the effective - values of eq and order. If *eq* is None, set it to *default_eq*. - """ - if cmp is not None and any((eq is not None, order is not None)): - raise ValueError("Don't mix `cmp` with `eq' and `order`.") - - # cmp takes precedence due to bw-compatibility. - if cmp is not None: - return cmp, cmp - - # If left None, equality is set to the specified default and ordering - # mirrors equality. - if eq is None: - eq = default_eq - - if order is None: - order = eq - - if eq is False and order is True: - raise ValueError("`order` can only be True if `eq` is True too.") - - return eq, order - - -def _determine_attrib_eq_order(cmp, eq, order, default_eq): - """ - Validate the combination of *cmp*, *eq*, and *order*. Derive the effective - values of eq and order. If *eq* is None, set it to *default_eq*. - """ - if cmp is not None and any((eq is not None, order is not None)): - raise ValueError("Don't mix `cmp` with `eq' and `order`.") - - def decide_callable_or_boolean(value): - """ - Decide whether a key function is used. - """ - if callable(value): - value, key = True, value - else: - key = None - return value, key - - # cmp takes precedence due to bw-compatibility. - if cmp is not None: - cmp, cmp_key = decide_callable_or_boolean(cmp) - return cmp, cmp_key, cmp, cmp_key - - # If left None, equality is set to the specified default and ordering - # mirrors equality. - if eq is None: - eq, eq_key = default_eq, None - else: - eq, eq_key = decide_callable_or_boolean(eq) - - if order is None: - order, order_key = eq, eq_key - else: - order, order_key = decide_callable_or_boolean(order) - - if eq is False and order is True: - raise ValueError("`order` can only be True if `eq` is True too.") - - return eq, eq_key, order, order_key - - -def _determine_whether_to_implement( - cls, flag, auto_detect, dunders, default=True -): - """ - Check whether we should implement a set of methods for *cls*. - - *flag* is the argument passed into @attr.s like 'init', *auto_detect* the - same as passed into @attr.s and *dunders* is a tuple of attribute names - whose presence signal that the user has implemented it themselves. - - Return *default* if no reason for either for or against is found. - - auto_detect must be False on Python 2. - """ - if flag is True or flag is False: - return flag - - if flag is None and auto_detect is False: - return default - - # Logically, flag is None and auto_detect is True here. - for dunder in dunders: - if _has_own_attribute(cls, dunder): - return False - - return default - - -def attrs( - maybe_cls=None, - these=None, - repr_ns=None, - repr=None, - cmp=None, - hash=None, - init=None, - slots=False, - frozen=False, - weakref_slot=True, - str=False, - auto_attribs=False, - kw_only=False, - cache_hash=False, - auto_exc=False, - eq=None, - order=None, - auto_detect=False, - collect_by_mro=False, - getstate_setstate=None, - on_setattr=None, - field_transformer=None, -): - r""" - A class decorator that adds `dunder - `_\ -methods according to the - specified attributes using `attr.ib` or the *these* argument. - - :param these: A dictionary of name to `attr.ib` mappings. This is - useful to avoid the definition of your attributes within the class body - because you can't (e.g. if you want to add ``__repr__`` methods to - Django models) or don't want to. - - If *these* is not ``None``, ``attrs`` will *not* search the class body - for attributes and will *not* remove any attributes from it. - - If *these* is an ordered dict (`dict` on Python 3.6+, - `collections.OrderedDict` otherwise), the order is deduced from - the order of the attributes inside *these*. Otherwise the order - of the definition of the attributes is used. - - :type these: `dict` of `str` to `attr.ib` - - :param str repr_ns: When using nested classes, there's no way in Python 2 - to automatically detect that. Therefore it's possible to set the - namespace explicitly for a more meaningful ``repr`` output. - :param bool auto_detect: Instead of setting the *init*, *repr*, *eq*, - *order*, and *hash* arguments explicitly, assume they are set to - ``True`` **unless any** of the involved methods for one of the - arguments is implemented in the *current* class (i.e. it is *not* - inherited from some base class). - - So for example by implementing ``__eq__`` on a class yourself, - ``attrs`` will deduce ``eq=False`` and will create *neither* - ``__eq__`` *nor* ``__ne__`` (but Python classes come with a sensible - ``__ne__`` by default, so it *should* be enough to only implement - ``__eq__`` in most cases). - - .. warning:: - - If you prevent ``attrs`` from creating the ordering methods for you - (``order=False``, e.g. by implementing ``__le__``), it becomes - *your* responsibility to make sure its ordering is sound. The best - way is to use the `functools.total_ordering` decorator. - - - Passing ``True`` or ``False`` to *init*, *repr*, *eq*, *order*, - *cmp*, or *hash* overrides whatever *auto_detect* would determine. - - *auto_detect* requires Python 3. Setting it ``True`` on Python 2 raises - a `PythonTooOldError`. - - :param bool repr: Create a ``__repr__`` method with a human readable - representation of ``attrs`` attributes.. - :param bool str: Create a ``__str__`` method that is identical to - ``__repr__``. This is usually not necessary except for - `Exception`\ s. - :param Optional[bool] eq: If ``True`` or ``None`` (default), add ``__eq__`` - and ``__ne__`` methods that check two instances for equality. - - They compare the instances as if they were tuples of their ``attrs`` - attributes if and only if the types of both classes are *identical*! - :param Optional[bool] order: If ``True``, add ``__lt__``, ``__le__``, - ``__gt__``, and ``__ge__`` methods that behave like *eq* above and - allow instances to be ordered. If ``None`` (default) mirror value of - *eq*. - :param Optional[bool] cmp: Setting *cmp* is equivalent to setting *eq* - and *order* to the same value. Must not be mixed with *eq* or *order*. - :param Optional[bool] hash: If ``None`` (default), the ``__hash__`` method - is generated according how *eq* and *frozen* are set. - - 1. If *both* are True, ``attrs`` will generate a ``__hash__`` for you. - 2. If *eq* is True and *frozen* is False, ``__hash__`` will be set to - None, marking it unhashable (which it is). - 3. If *eq* is False, ``__hash__`` will be left untouched meaning the - ``__hash__`` method of the base class will be used (if base class is - ``object``, this means it will fall back to id-based hashing.). - - Although not recommended, you can decide for yourself and force - ``attrs`` to create one (e.g. if the class is immutable even though you - didn't freeze it programmatically) by passing ``True`` or not. Both of - these cases are rather special and should be used carefully. - - See our documentation on `hashing`, Python's documentation on - `object.__hash__`, and the `GitHub issue that led to the default \ - behavior `_ for more - details. - :param bool init: Create a ``__init__`` method that initializes the - ``attrs`` attributes. Leading underscores are stripped for the argument - name. If a ``__attrs_pre_init__`` method exists on the class, it will - be called before the class is initialized. If a ``__attrs_post_init__`` - method exists on the class, it will be called after the class is fully - initialized. - - If ``init`` is ``False``, an ``__attrs_init__`` method will be - injected instead. This allows you to define a custom ``__init__`` - method that can do pre-init work such as ``super().__init__()``, - and then call ``__attrs_init__()`` and ``__attrs_post_init__()``. - :param bool slots: Create a `slotted class ` that's more - memory-efficient. Slotted classes are generally superior to the default - dict classes, but have some gotchas you should know about, so we - encourage you to read the `glossary entry `. - :param bool frozen: Make instances immutable after initialization. If - someone attempts to modify a frozen instance, - `attr.exceptions.FrozenInstanceError` is raised. - - .. note:: - - 1. This is achieved by installing a custom ``__setattr__`` method - on your class, so you can't implement your own. - - 2. True immutability is impossible in Python. - - 3. This *does* have a minor a runtime performance `impact - ` when initializing new instances. In other words: - ``__init__`` is slightly slower with ``frozen=True``. - - 4. If a class is frozen, you cannot modify ``self`` in - ``__attrs_post_init__`` or a self-written ``__init__``. You can - circumvent that limitation by using - ``object.__setattr__(self, "attribute_name", value)``. - - 5. Subclasses of a frozen class are frozen too. - - :param bool weakref_slot: Make instances weak-referenceable. This has no - effect unless ``slots`` is also enabled. - :param bool auto_attribs: If ``True``, collect `PEP 526`_-annotated - attributes (Python 3.6 and later only) from the class body. - - In this case, you **must** annotate every field. If ``attrs`` - encounters a field that is set to an `attr.ib` but lacks a type - annotation, an `attr.exceptions.UnannotatedAttributeError` is - raised. Use ``field_name: typing.Any = attr.ib(...)`` if you don't - want to set a type. - - If you assign a value to those attributes (e.g. ``x: int = 42``), that - value becomes the default value like if it were passed using - ``attr.ib(default=42)``. Passing an instance of `Factory` also - works as expected in most cases (see warning below). - - Attributes annotated as `typing.ClassVar`, and attributes that are - neither annotated nor set to an `attr.ib` are **ignored**. - - .. warning:: - For features that use the attribute name to create decorators (e.g. - `validators `), you still *must* assign `attr.ib` to - them. Otherwise Python will either not find the name or try to use - the default value to call e.g. ``validator`` on it. - - These errors can be quite confusing and probably the most common bug - report on our bug tracker. - - .. _`PEP 526`: https://www.python.org/dev/peps/pep-0526/ - :param bool kw_only: Make all attributes keyword-only (Python 3+) - in the generated ``__init__`` (if ``init`` is ``False``, this - parameter is ignored). - :param bool cache_hash: Ensure that the object's hash code is computed - only once and stored on the object. If this is set to ``True``, - hashing must be either explicitly or implicitly enabled for this - class. If the hash code is cached, avoid any reassignments of - fields involved in hash code computation or mutations of the objects - those fields point to after object creation. If such changes occur, - the behavior of the object's hash code is undefined. - :param bool auto_exc: If the class subclasses `BaseException` - (which implicitly includes any subclass of any exception), the - following happens to behave like a well-behaved Python exceptions - class: - - - the values for *eq*, *order*, and *hash* are ignored and the - instances compare and hash by the instance's ids (N.B. ``attrs`` will - *not* remove existing implementations of ``__hash__`` or the equality - methods. It just won't add own ones.), - - all attributes that are either passed into ``__init__`` or have a - default value are additionally available as a tuple in the ``args`` - attribute, - - the value of *str* is ignored leaving ``__str__`` to base classes. - :param bool collect_by_mro: Setting this to `True` fixes the way ``attrs`` - collects attributes from base classes. The default behavior is - incorrect in certain cases of multiple inheritance. It should be on by - default but is kept off for backward-compatability. - - See issue `#428 `_ for - more details. - - :param Optional[bool] getstate_setstate: - .. note:: - This is usually only interesting for slotted classes and you should - probably just set *auto_detect* to `True`. - - If `True`, ``__getstate__`` and - ``__setstate__`` are generated and attached to the class. This is - necessary for slotted classes to be pickleable. If left `None`, it's - `True` by default for slotted classes and ``False`` for dict classes. - - If *auto_detect* is `True`, and *getstate_setstate* is left `None`, - and **either** ``__getstate__`` or ``__setstate__`` is detected directly - on the class (i.e. not inherited), it is set to `False` (this is usually - what you want). - - :param on_setattr: A callable that is run whenever the user attempts to set - an attribute (either by assignment like ``i.x = 42`` or by using - `setattr` like ``setattr(i, "x", 42)``). It receives the same arguments - as validators: the instance, the attribute that is being modified, and - the new value. - - If no exception is raised, the attribute is set to the return value of - the callable. - - If a list of callables is passed, they're automatically wrapped in an - `attr.setters.pipe`. - - :param Optional[callable] field_transformer: - A function that is called with the original class object and all - fields right before ``attrs`` finalizes the class. You can use - this, e.g., to automatically add converters or validators to - fields based on their types. See `transform-fields` for more details. - - .. versionadded:: 16.0.0 *slots* - .. versionadded:: 16.1.0 *frozen* - .. versionadded:: 16.3.0 *str* - .. versionadded:: 16.3.0 Support for ``__attrs_post_init__``. - .. versionchanged:: 17.1.0 - *hash* supports ``None`` as value which is also the default now. - .. versionadded:: 17.3.0 *auto_attribs* - .. versionchanged:: 18.1.0 - If *these* is passed, no attributes are deleted from the class body. - .. versionchanged:: 18.1.0 If *these* is ordered, the order is retained. - .. versionadded:: 18.2.0 *weakref_slot* - .. deprecated:: 18.2.0 - ``__lt__``, ``__le__``, ``__gt__``, and ``__ge__`` now raise a - `DeprecationWarning` if the classes compared are subclasses of - each other. ``__eq`` and ``__ne__`` never tried to compared subclasses - to each other. - .. versionchanged:: 19.2.0 - ``__lt__``, ``__le__``, ``__gt__``, and ``__ge__`` now do not consider - subclasses comparable anymore. - .. versionadded:: 18.2.0 *kw_only* - .. versionadded:: 18.2.0 *cache_hash* - .. versionadded:: 19.1.0 *auto_exc* - .. deprecated:: 19.2.0 *cmp* Removal on or after 2021-06-01. - .. versionadded:: 19.2.0 *eq* and *order* - .. versionadded:: 20.1.0 *auto_detect* - .. versionadded:: 20.1.0 *collect_by_mro* - .. versionadded:: 20.1.0 *getstate_setstate* - .. versionadded:: 20.1.0 *on_setattr* - .. versionadded:: 20.3.0 *field_transformer* - .. versionchanged:: 21.1.0 - ``init=False`` injects ``__attrs_init__`` - .. versionchanged:: 21.1.0 Support for ``__attrs_pre_init__`` - .. versionchanged:: 21.1.0 *cmp* undeprecated - """ - if auto_detect and PY2: - raise PythonTooOldError( - "auto_detect only works on Python 3 and later." - ) - - eq_, order_ = _determine_attrs_eq_order(cmp, eq, order, None) - hash_ = hash # work around the lack of nonlocal - - if isinstance(on_setattr, (list, tuple)): - on_setattr = setters.pipe(*on_setattr) - - def wrap(cls): - - if getattr(cls, "__class__", None) is None: - raise TypeError("attrs only works with new-style classes.") - - is_frozen = frozen or _has_frozen_base_class(cls) - is_exc = auto_exc is True and issubclass(cls, BaseException) - has_own_setattr = auto_detect and _has_own_attribute( - cls, "__setattr__" - ) - - if has_own_setattr and is_frozen: - raise ValueError("Can't freeze a class with a custom __setattr__.") - - builder = _ClassBuilder( - cls, - these, - slots, - is_frozen, - weakref_slot, - _determine_whether_to_implement( - cls, - getstate_setstate, - auto_detect, - ("__getstate__", "__setstate__"), - default=slots, - ), - auto_attribs, - kw_only, - cache_hash, - is_exc, - collect_by_mro, - on_setattr, - has_own_setattr, - field_transformer, - ) - if _determine_whether_to_implement( - cls, repr, auto_detect, ("__repr__",) - ): - builder.add_repr(repr_ns) - if str is True: - builder.add_str() - - eq = _determine_whether_to_implement( - cls, eq_, auto_detect, ("__eq__", "__ne__") - ) - if not is_exc and eq is True: - builder.add_eq() - if not is_exc and _determine_whether_to_implement( - cls, order_, auto_detect, ("__lt__", "__le__", "__gt__", "__ge__") - ): - builder.add_order() - - builder.add_setattr() - - if ( - hash_ is None - and auto_detect is True - and _has_own_attribute(cls, "__hash__") - ): - hash = False - else: - hash = hash_ - if hash is not True and hash is not False and hash is not None: - # Can't use `hash in` because 1 == True for example. - raise TypeError( - "Invalid value for hash. Must be True, False, or None." - ) - elif hash is False or (hash is None and eq is False) or is_exc: - # Don't do anything. Should fall back to __object__'s __hash__ - # which is by id. - if cache_hash: - raise TypeError( - "Invalid value for cache_hash. To use hash caching," - " hashing must be either explicitly or implicitly " - "enabled." - ) - elif hash is True or ( - hash is None and eq is True and is_frozen is True - ): - # Build a __hash__ if told so, or if it's safe. - builder.add_hash() - else: - # Raise TypeError on attempts to hash. - if cache_hash: - raise TypeError( - "Invalid value for cache_hash. To use hash caching," - " hashing must be either explicitly or implicitly " - "enabled." - ) - builder.make_unhashable() - - if _determine_whether_to_implement( - cls, init, auto_detect, ("__init__",) - ): - builder.add_init() - else: - builder.add_attrs_init() - if cache_hash: - raise TypeError( - "Invalid value for cache_hash. To use hash caching," - " init must be True." - ) - - return builder.build_class() - - # maybe_cls's type depends on the usage of the decorator. It's a class - # if it's used as `@attrs` but ``None`` if used as `@attrs()`. - if maybe_cls is None: - return wrap - else: - return wrap(maybe_cls) - - -_attrs = attrs -""" -Internal alias so we can use it in functions that take an argument called -*attrs*. -""" - - -if PY2: - - def _has_frozen_base_class(cls): - """ - Check whether *cls* has a frozen ancestor by looking at its - __setattr__. - """ - return ( - getattr(cls.__setattr__, "__module__", None) - == _frozen_setattrs.__module__ - and cls.__setattr__.__name__ == _frozen_setattrs.__name__ - ) - - -else: - - def _has_frozen_base_class(cls): - """ - Check whether *cls* has a frozen ancestor by looking at its - __setattr__. - """ - return cls.__setattr__ == _frozen_setattrs - - -def _generate_unique_filename(cls, func_name): - """ - Create a "filename" suitable for a function being generated. - """ - unique_id = uuid.uuid4() - extra = "" - count = 1 - - while True: - unique_filename = "".format( - func_name, - cls.__module__, - getattr(cls, "__qualname__", cls.__name__), - extra, - ) - # To handle concurrency we essentially "reserve" our spot in - # the linecache with a dummy line. The caller can then - # set this value correctly. - cache_line = (1, None, (str(unique_id),), unique_filename) - if ( - linecache.cache.setdefault(unique_filename, cache_line) - == cache_line - ): - return unique_filename - - # Looks like this spot is taken. Try again. - count += 1 - extra = "-{0}".format(count) - - -def _make_hash(cls, attrs, frozen, cache_hash): - attrs = tuple( - a for a in attrs if a.hash is True or (a.hash is None and a.eq is True) - ) - - tab = " " - - unique_filename = _generate_unique_filename(cls, "hash") - type_hash = hash(unique_filename) - - hash_def = "def __hash__(self" - hash_func = "hash((" - closing_braces = "))" - if not cache_hash: - hash_def += "):" - else: - if not PY2: - hash_def += ", *" - - hash_def += ( - ", _cache_wrapper=" - + "__import__('attr._make')._make._CacheHashWrapper):" - ) - hash_func = "_cache_wrapper(" + hash_func - closing_braces += ")" - - method_lines = [hash_def] - - def append_hash_computation_lines(prefix, indent): - """ - Generate the code for actually computing the hash code. - Below this will either be returned directly or used to compute - a value which is then cached, depending on the value of cache_hash - """ - - method_lines.extend( - [ - indent + prefix + hash_func, - indent + " %d," % (type_hash,), - ] - ) - - for a in attrs: - method_lines.append(indent + " self.%s," % a.name) - - method_lines.append(indent + " " + closing_braces) - - if cache_hash: - method_lines.append(tab + "if self.%s is None:" % _hash_cache_field) - if frozen: - append_hash_computation_lines( - "object.__setattr__(self, '%s', " % _hash_cache_field, tab * 2 - ) - method_lines.append(tab * 2 + ")") # close __setattr__ - else: - append_hash_computation_lines( - "self.%s = " % _hash_cache_field, tab * 2 - ) - method_lines.append(tab + "return self.%s" % _hash_cache_field) - else: - append_hash_computation_lines("return ", tab) - - script = "\n".join(method_lines) - return _make_method("__hash__", script, unique_filename) - - -def _add_hash(cls, attrs): - """ - Add a hash method to *cls*. - """ - cls.__hash__ = _make_hash(cls, attrs, frozen=False, cache_hash=False) - return cls - - -def _make_ne(): - """ - Create __ne__ method. - """ - - def __ne__(self, other): - """ - Check equality and either forward a NotImplemented or - return the result negated. - """ - result = self.__eq__(other) - if result is NotImplemented: - return NotImplemented - - return not result - - return __ne__ - - -def _make_eq(cls, attrs): - """ - Create __eq__ method for *cls* with *attrs*. - """ - attrs = [a for a in attrs if a.eq] - - unique_filename = _generate_unique_filename(cls, "eq") - lines = [ - "def __eq__(self, other):", - " if other.__class__ is not self.__class__:", - " return NotImplemented", - ] - - # We can't just do a big self.x = other.x and... clause due to - # irregularities like nan == nan is false but (nan,) == (nan,) is true. - globs = {} - if attrs: - lines.append(" return (") - others = [" ) == ("] - for a in attrs: - if a.eq_key: - cmp_name = "_%s_key" % (a.name,) - # Add the key function to the global namespace - # of the evaluated function. - globs[cmp_name] = a.eq_key - lines.append( - " %s(self.%s)," - % ( - cmp_name, - a.name, - ) - ) - others.append( - " %s(other.%s)," - % ( - cmp_name, - a.name, - ) - ) - else: - lines.append(" self.%s," % (a.name,)) - others.append(" other.%s," % (a.name,)) - - lines += others + [" )"] - else: - lines.append(" return True") - - script = "\n".join(lines) - - return _make_method("__eq__", script, unique_filename, globs) - - -def _make_order(cls, attrs): - """ - Create ordering methods for *cls* with *attrs*. - """ - attrs = [a for a in attrs if a.order] - - def attrs_to_tuple(obj): - """ - Save us some typing. - """ - return tuple( - key(value) if key else value - for value, key in ( - (getattr(obj, a.name), a.order_key) for a in attrs - ) - ) - - def __lt__(self, other): - """ - Automatically created by attrs. - """ - if other.__class__ is self.__class__: - return attrs_to_tuple(self) < attrs_to_tuple(other) - - return NotImplemented - - def __le__(self, other): - """ - Automatically created by attrs. - """ - if other.__class__ is self.__class__: - return attrs_to_tuple(self) <= attrs_to_tuple(other) - - return NotImplemented - - def __gt__(self, other): - """ - Automatically created by attrs. - """ - if other.__class__ is self.__class__: - return attrs_to_tuple(self) > attrs_to_tuple(other) - - return NotImplemented - - def __ge__(self, other): - """ - Automatically created by attrs. - """ - if other.__class__ is self.__class__: - return attrs_to_tuple(self) >= attrs_to_tuple(other) - - return NotImplemented - - return __lt__, __le__, __gt__, __ge__ - - -def _add_eq(cls, attrs=None): - """ - Add equality methods to *cls* with *attrs*. - """ - if attrs is None: - attrs = cls.__attrs_attrs__ - - cls.__eq__ = _make_eq(cls, attrs) - cls.__ne__ = _make_ne() - - return cls - - -_already_repring = threading.local() - - -def _make_repr(attrs, ns): - """ - Make a repr method that includes relevant *attrs*, adding *ns* to the full - name. - """ - - # Figure out which attributes to include, and which function to use to - # format them. The a.repr value can be either bool or a custom callable. - attr_names_with_reprs = tuple( - (a.name, repr if a.repr is True else a.repr) - for a in attrs - if a.repr is not False - ) - - def __repr__(self): - """ - Automatically created by attrs. - """ - try: - working_set = _already_repring.working_set - except AttributeError: - working_set = set() - _already_repring.working_set = working_set - - if id(self) in working_set: - return "..." - real_cls = self.__class__ - if ns is None: - qualname = getattr(real_cls, "__qualname__", None) - if qualname is not None: - class_name = qualname.rsplit(">.", 1)[-1] - else: - class_name = real_cls.__name__ - else: - class_name = ns + "." + real_cls.__name__ - - # Since 'self' remains on the stack (i.e.: strongly referenced) for the - # duration of this call, it's safe to depend on id(...) stability, and - # not need to track the instance and therefore worry about properties - # like weakref- or hash-ability. - working_set.add(id(self)) - try: - result = [class_name, "("] - first = True - for name, attr_repr in attr_names_with_reprs: - if first: - first = False - else: - result.append(", ") - result.extend( - (name, "=", attr_repr(getattr(self, name, NOTHING))) - ) - return "".join(result) + ")" - finally: - working_set.remove(id(self)) - - return __repr__ - - -def _add_repr(cls, ns=None, attrs=None): - """ - Add a repr method to *cls*. - """ - if attrs is None: - attrs = cls.__attrs_attrs__ - - cls.__repr__ = _make_repr(attrs, ns) - return cls - - -def fields(cls): - """ - Return the tuple of ``attrs`` attributes for a class. - - The tuple also allows accessing the fields by their names (see below for - examples). - - :param type cls: Class to introspect. - - :raise TypeError: If *cls* is not a class. - :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` - class. - - :rtype: tuple (with name accessors) of `attr.Attribute` - - .. versionchanged:: 16.2.0 Returned tuple allows accessing the fields - by name. - """ - if not isclass(cls): - raise TypeError("Passed object must be a class.") - attrs = getattr(cls, "__attrs_attrs__", None) - if attrs is None: - raise NotAnAttrsClassError( - "{cls!r} is not an attrs-decorated class.".format(cls=cls) - ) - return attrs - - -def fields_dict(cls): - """ - Return an ordered dictionary of ``attrs`` attributes for a class, whose - keys are the attribute names. - - :param type cls: Class to introspect. - - :raise TypeError: If *cls* is not a class. - :raise attr.exceptions.NotAnAttrsClassError: If *cls* is not an ``attrs`` - class. - - :rtype: an ordered dict where keys are attribute names and values are - `attr.Attribute`\\ s. This will be a `dict` if it's - naturally ordered like on Python 3.6+ or an - :class:`~collections.OrderedDict` otherwise. - - .. versionadded:: 18.1.0 - """ - if not isclass(cls): - raise TypeError("Passed object must be a class.") - attrs = getattr(cls, "__attrs_attrs__", None) - if attrs is None: - raise NotAnAttrsClassError( - "{cls!r} is not an attrs-decorated class.".format(cls=cls) - ) - return ordered_dict(((a.name, a) for a in attrs)) - - -def validate(inst): - """ - Validate all attributes on *inst* that have a validator. - - Leaves all exceptions through. - - :param inst: Instance of a class with ``attrs`` attributes. - """ - if _config._run_validators is False: - return - - for a in fields(inst.__class__): - v = a.validator - if v is not None: - v(inst, a, getattr(inst, a.name)) - - -def _is_slot_cls(cls): - return "__slots__" in cls.__dict__ - - -def _is_slot_attr(a_name, base_attr_map): - """ - Check if the attribute name comes from a slot class. - """ - return a_name in base_attr_map and _is_slot_cls(base_attr_map[a_name]) - - -def _make_init( - cls, - attrs, - pre_init, - post_init, - frozen, - slots, - cache_hash, - base_attr_map, - is_exc, - has_global_on_setattr, - attrs_init, -): - if frozen and has_global_on_setattr: - raise ValueError("Frozen classes can't use on_setattr.") - - needs_cached_setattr = cache_hash or frozen - filtered_attrs = [] - attr_dict = {} - for a in attrs: - if not a.init and a.default is NOTHING: - continue - - filtered_attrs.append(a) - attr_dict[a.name] = a - - if a.on_setattr is not None: - if frozen is True: - raise ValueError("Frozen classes can't use on_setattr.") - - needs_cached_setattr = True - elif ( - has_global_on_setattr and a.on_setattr is not setters.NO_OP - ) or _is_slot_attr(a.name, base_attr_map): - needs_cached_setattr = True - - unique_filename = _generate_unique_filename(cls, "init") - - script, globs, annotations = _attrs_to_init_script( - filtered_attrs, - frozen, - slots, - pre_init, - post_init, - cache_hash, - base_attr_map, - is_exc, - needs_cached_setattr, - has_global_on_setattr, - attrs_init, - ) - if cls.__module__ in sys.modules: - # This makes typing.get_type_hints(CLS.__init__) resolve string types. - globs.update(sys.modules[cls.__module__].__dict__) - - globs.update({"NOTHING": NOTHING, "attr_dict": attr_dict}) - - if needs_cached_setattr: - # Save the lookup overhead in __init__ if we need to circumvent - # setattr hooks. - globs["_cached_setattr"] = _obj_setattr - - init = _make_method( - "__attrs_init__" if attrs_init else "__init__", - script, - unique_filename, - globs, - ) - init.__annotations__ = annotations - - return init - - -def _setattr(attr_name, value_var, has_on_setattr): - """ - Use the cached object.setattr to set *attr_name* to *value_var*. - """ - return "_setattr('%s', %s)" % (attr_name, value_var) - - -def _setattr_with_converter(attr_name, value_var, has_on_setattr): - """ - Use the cached object.setattr to set *attr_name* to *value_var*, but run - its converter first. - """ - return "_setattr('%s', %s(%s))" % ( - attr_name, - _init_converter_pat % (attr_name,), - value_var, - ) - - -def _assign(attr_name, value, has_on_setattr): - """ - Unless *attr_name* has an on_setattr hook, use normal assignment. Otherwise - relegate to _setattr. - """ - if has_on_setattr: - return _setattr(attr_name, value, True) - - return "self.%s = %s" % (attr_name, value) - - -def _assign_with_converter(attr_name, value_var, has_on_setattr): - """ - Unless *attr_name* has an on_setattr hook, use normal assignment after - conversion. Otherwise relegate to _setattr_with_converter. - """ - if has_on_setattr: - return _setattr_with_converter(attr_name, value_var, True) - - return "self.%s = %s(%s)" % ( - attr_name, - _init_converter_pat % (attr_name,), - value_var, - ) - - -if PY2: - - def _unpack_kw_only_py2(attr_name, default=None): - """ - Unpack *attr_name* from _kw_only dict. - """ - if default is not None: - arg_default = ", %s" % default - else: - arg_default = "" - return "%s = _kw_only.pop('%s'%s)" % ( - attr_name, - attr_name, - arg_default, - ) - - def _unpack_kw_only_lines_py2(kw_only_args): - """ - Unpack all *kw_only_args* from _kw_only dict and handle errors. - - Given a list of strings "{attr_name}" and "{attr_name}={default}" - generates list of lines of code that pop attrs from _kw_only dict and - raise TypeError similar to builtin if required attr is missing or - extra key is passed. - - >>> print("\n".join(_unpack_kw_only_lines_py2(["a", "b=42"]))) - try: - a = _kw_only.pop('a') - b = _kw_only.pop('b', 42) - except KeyError as _key_error: - raise TypeError( - ... - if _kw_only: - raise TypeError( - ... - """ - lines = ["try:"] - lines.extend( - " " + _unpack_kw_only_py2(*arg.split("=")) - for arg in kw_only_args - ) - lines += """\ -except KeyError as _key_error: - raise TypeError( - '__init__() missing required keyword-only argument: %s' % _key_error - ) -if _kw_only: - raise TypeError( - '__init__() got an unexpected keyword argument %r' - % next(iter(_kw_only)) - ) -""".split( - "\n" - ) - return lines - - -def _attrs_to_init_script( - attrs, - frozen, - slots, - pre_init, - post_init, - cache_hash, - base_attr_map, - is_exc, - needs_cached_setattr, - has_global_on_setattr, - attrs_init, -): - """ - Return a script of an initializer for *attrs* and a dict of globals. - - The globals are expected by the generated script. - - If *frozen* is True, we cannot set the attributes directly so we use - a cached ``object.__setattr__``. - """ - lines = [] - if pre_init: - lines.append("self.__attrs_pre_init__()") - - if needs_cached_setattr: - lines.append( - # Circumvent the __setattr__ descriptor to save one lookup per - # assignment. - # Note _setattr will be used again below if cache_hash is True - "_setattr = _cached_setattr.__get__(self, self.__class__)" - ) - - if frozen is True: - if slots is True: - fmt_setter = _setattr - fmt_setter_with_converter = _setattr_with_converter - else: - # Dict frozen classes assign directly to __dict__. - # But only if the attribute doesn't come from an ancestor slot - # class. - # Note _inst_dict will be used again below if cache_hash is True - lines.append("_inst_dict = self.__dict__") - - def fmt_setter(attr_name, value_var, has_on_setattr): - if _is_slot_attr(attr_name, base_attr_map): - return _setattr(attr_name, value_var, has_on_setattr) - - return "_inst_dict['%s'] = %s" % (attr_name, value_var) - - def fmt_setter_with_converter( - attr_name, value_var, has_on_setattr - ): - if has_on_setattr or _is_slot_attr(attr_name, base_attr_map): - return _setattr_with_converter( - attr_name, value_var, has_on_setattr - ) - - return "_inst_dict['%s'] = %s(%s)" % ( - attr_name, - _init_converter_pat % (attr_name,), - value_var, - ) - - else: - # Not frozen. - fmt_setter = _assign - fmt_setter_with_converter = _assign_with_converter - - args = [] - kw_only_args = [] - attrs_to_validate = [] - - # This is a dictionary of names to validator and converter callables. - # Injecting this into __init__ globals lets us avoid lookups. - names_for_globals = {} - annotations = {"return": None} - - for a in attrs: - if a.validator: - attrs_to_validate.append(a) - - attr_name = a.name - has_on_setattr = a.on_setattr is not None or ( - a.on_setattr is not setters.NO_OP and has_global_on_setattr - ) - arg_name = a.name.lstrip("_") - - has_factory = isinstance(a.default, Factory) - if has_factory and a.default.takes_self: - maybe_self = "self" - else: - maybe_self = "" - - if a.init is False: - if has_factory: - init_factory_name = _init_factory_pat.format(a.name) - if a.converter is not None: - lines.append( - fmt_setter_with_converter( - attr_name, - init_factory_name + "(%s)" % (maybe_self,), - has_on_setattr, - ) - ) - conv_name = _init_converter_pat % (a.name,) - names_for_globals[conv_name] = a.converter - else: - lines.append( - fmt_setter( - attr_name, - init_factory_name + "(%s)" % (maybe_self,), - has_on_setattr, - ) - ) - names_for_globals[init_factory_name] = a.default.factory - else: - if a.converter is not None: - lines.append( - fmt_setter_with_converter( - attr_name, - "attr_dict['%s'].default" % (attr_name,), - has_on_setattr, - ) - ) - conv_name = _init_converter_pat % (a.name,) - names_for_globals[conv_name] = a.converter - else: - lines.append( - fmt_setter( - attr_name, - "attr_dict['%s'].default" % (attr_name,), - has_on_setattr, - ) - ) - elif a.default is not NOTHING and not has_factory: - arg = "%s=attr_dict['%s'].default" % (arg_name, attr_name) - if a.kw_only: - kw_only_args.append(arg) - else: - args.append(arg) - - if a.converter is not None: - lines.append( - fmt_setter_with_converter( - attr_name, arg_name, has_on_setattr - ) - ) - names_for_globals[ - _init_converter_pat % (a.name,) - ] = a.converter - else: - lines.append(fmt_setter(attr_name, arg_name, has_on_setattr)) - - elif has_factory: - arg = "%s=NOTHING" % (arg_name,) - if a.kw_only: - kw_only_args.append(arg) - else: - args.append(arg) - lines.append("if %s is not NOTHING:" % (arg_name,)) - - init_factory_name = _init_factory_pat.format(a.name) - if a.converter is not None: - lines.append( - " " - + fmt_setter_with_converter( - attr_name, arg_name, has_on_setattr - ) - ) - lines.append("else:") - lines.append( - " " - + fmt_setter_with_converter( - attr_name, - init_factory_name + "(" + maybe_self + ")", - has_on_setattr, - ) - ) - names_for_globals[ - _init_converter_pat % (a.name,) - ] = a.converter - else: - lines.append( - " " + fmt_setter(attr_name, arg_name, has_on_setattr) - ) - lines.append("else:") - lines.append( - " " - + fmt_setter( - attr_name, - init_factory_name + "(" + maybe_self + ")", - has_on_setattr, - ) - ) - names_for_globals[init_factory_name] = a.default.factory - else: - if a.kw_only: - kw_only_args.append(arg_name) - else: - args.append(arg_name) - - if a.converter is not None: - lines.append( - fmt_setter_with_converter( - attr_name, arg_name, has_on_setattr - ) - ) - names_for_globals[ - _init_converter_pat % (a.name,) - ] = a.converter - else: - lines.append(fmt_setter(attr_name, arg_name, has_on_setattr)) - - if a.init is True: - if a.type is not None and a.converter is None: - annotations[arg_name] = a.type - elif a.converter is not None and not PY2: - # Try to get the type from the converter. - sig = None - try: - sig = inspect.signature(a.converter) - except (ValueError, TypeError): # inspect failed - pass - if sig: - sig_params = list(sig.parameters.values()) - if ( - sig_params - and sig_params[0].annotation - is not inspect.Parameter.empty - ): - annotations[arg_name] = sig_params[0].annotation - - if attrs_to_validate: # we can skip this if there are no validators. - names_for_globals["_config"] = _config - lines.append("if _config._run_validators is True:") - for a in attrs_to_validate: - val_name = "__attr_validator_" + a.name - attr_name = "__attr_" + a.name - lines.append( - " %s(self, %s, self.%s)" % (val_name, attr_name, a.name) - ) - names_for_globals[val_name] = a.validator - names_for_globals[attr_name] = a - - if post_init: - lines.append("self.__attrs_post_init__()") - - # because this is set only after __attrs_post_init is called, a crash - # will result if post-init tries to access the hash code. This seemed - # preferable to setting this beforehand, in which case alteration to - # field values during post-init combined with post-init accessing the - # hash code would result in silent bugs. - if cache_hash: - if frozen: - if slots: - # if frozen and slots, then _setattr defined above - init_hash_cache = "_setattr('%s', %s)" - else: - # if frozen and not slots, then _inst_dict defined above - init_hash_cache = "_inst_dict['%s'] = %s" - else: - init_hash_cache = "self.%s = %s" - lines.append(init_hash_cache % (_hash_cache_field, "None")) - - # For exceptions we rely on BaseException.__init__ for proper - # initialization. - if is_exc: - vals = ",".join("self." + a.name for a in attrs if a.init) - - lines.append("BaseException.__init__(self, %s)" % (vals,)) - - args = ", ".join(args) - if kw_only_args: - if PY2: - lines = _unpack_kw_only_lines_py2(kw_only_args) + lines - - args += "%s**_kw_only" % (", " if args else "",) # leading comma - else: - args += "%s*, %s" % ( - ", " if args else "", # leading comma - ", ".join(kw_only_args), # kw_only args - ) - return ( - """\ -def {init_name}(self, {args}): - {lines} -""".format( - init_name=("__attrs_init__" if attrs_init else "__init__"), - args=args, - lines="\n ".join(lines) if lines else "pass", - ), - names_for_globals, - annotations, - ) - - -class Attribute(object): - """ - *Read-only* representation of an attribute. - - Instances of this class are frequently used for introspection purposes - like: - - - `fields` returns a tuple of them. - - Validators get them passed as the first argument. - - The *field transformer* hook receives a list of them. - - :attribute name: The name of the attribute. - :attribute inherited: Whether or not that attribute has been inherited from - a base class. - - Plus *all* arguments of `attr.ib` (except for ``factory`` - which is only syntactic sugar for ``default=Factory(...)``. - - .. versionadded:: 20.1.0 *inherited* - .. versionadded:: 20.1.0 *on_setattr* - .. versionchanged:: 20.2.0 *inherited* is not taken into account for - equality checks and hashing anymore. - .. versionadded:: 21.1.0 *eq_key* and *order_key* - - For the full version history of the fields, see `attr.ib`. - """ - - __slots__ = ( - "name", - "default", - "validator", - "repr", - "eq", - "eq_key", - "order", - "order_key", - "hash", - "init", - "metadata", - "type", - "converter", - "kw_only", - "inherited", - "on_setattr", - ) - - def __init__( - self, - name, - default, - validator, - repr, - cmp, # XXX: unused, remove along with other cmp code. - hash, - init, - inherited, - metadata=None, - type=None, - converter=None, - kw_only=False, - eq=None, - eq_key=None, - order=None, - order_key=None, - on_setattr=None, - ): - eq, eq_key, order, order_key = _determine_attrib_eq_order( - cmp, eq_key or eq, order_key or order, True - ) - - # Cache this descriptor here to speed things up later. - bound_setattr = _obj_setattr.__get__(self, Attribute) - - # Despite the big red warning, people *do* instantiate `Attribute` - # themselves. - bound_setattr("name", name) - bound_setattr("default", default) - bound_setattr("validator", validator) - bound_setattr("repr", repr) - bound_setattr("eq", eq) - bound_setattr("eq_key", eq_key) - bound_setattr("order", order) - bound_setattr("order_key", order_key) - bound_setattr("hash", hash) - bound_setattr("init", init) - bound_setattr("converter", converter) - bound_setattr( - "metadata", - ( - metadata_proxy(metadata) - if metadata - else _empty_metadata_singleton - ), - ) - bound_setattr("type", type) - bound_setattr("kw_only", kw_only) - bound_setattr("inherited", inherited) - bound_setattr("on_setattr", on_setattr) - - def __setattr__(self, name, value): - raise FrozenInstanceError() - - @classmethod - def from_counting_attr(cls, name, ca, type=None): - # type holds the annotated value. deal with conflicts: - if type is None: - type = ca.type - elif ca.type is not None: - raise ValueError( - "Type annotation and type argument cannot both be present" - ) - inst_dict = { - k: getattr(ca, k) - for k in Attribute.__slots__ - if k - not in ( - "name", - "validator", - "default", - "type", - "inherited", - ) # exclude methods and deprecated alias - } - return cls( - name=name, - validator=ca._validator, - default=ca._default, - type=type, - cmp=None, - inherited=False, - **inst_dict - ) - - @property - def cmp(self): - """ - Simulate the presence of a cmp attribute and warn. - """ - warnings.warn(_CMP_DEPRECATION, DeprecationWarning, stacklevel=2) - - return self.eq and self.order - - # Don't use attr.evolve since fields(Attribute) doesn't work - def evolve(self, **changes): - """ - Copy *self* and apply *changes*. - - This works similarly to `attr.evolve` but that function does not work - with ``Attribute``. - - It is mainly meant to be used for `transform-fields`. - - .. versionadded:: 20.3.0 - """ - new = copy.copy(self) - - new._setattrs(changes.items()) - - return new - - # Don't use _add_pickle since fields(Attribute) doesn't work - def __getstate__(self): - """ - Play nice with pickle. - """ - return tuple( - getattr(self, name) if name != "metadata" else dict(self.metadata) - for name in self.__slots__ - ) - - def __setstate__(self, state): - """ - Play nice with pickle. - """ - self._setattrs(zip(self.__slots__, state)) - - def _setattrs(self, name_values_pairs): - bound_setattr = _obj_setattr.__get__(self, Attribute) - for name, value in name_values_pairs: - if name != "metadata": - bound_setattr(name, value) - else: - bound_setattr( - name, - metadata_proxy(value) - if value - else _empty_metadata_singleton, - ) - - -_a = [ - Attribute( - name=name, - default=NOTHING, - validator=None, - repr=True, - cmp=None, - eq=True, - order=False, - hash=(name != "metadata"), - init=True, - inherited=False, - ) - for name in Attribute.__slots__ -] - -Attribute = _add_hash( - _add_eq( - _add_repr(Attribute, attrs=_a), - attrs=[a for a in _a if a.name != "inherited"], - ), - attrs=[a for a in _a if a.hash and a.name != "inherited"], -) - - -class _CountingAttr(object): - """ - Intermediate representation of attributes that uses a counter to preserve - the order in which the attributes have been defined. - - *Internal* data structure of the attrs library. Running into is most - likely the result of a bug like a forgotten `@attr.s` decorator. - """ - - __slots__ = ( - "counter", - "_default", - "repr", - "eq", - "eq_key", - "order", - "order_key", - "hash", - "init", - "metadata", - "_validator", - "converter", - "type", - "kw_only", - "on_setattr", - ) - __attrs_attrs__ = tuple( - Attribute( - name=name, - default=NOTHING, - validator=None, - repr=True, - cmp=None, - hash=True, - init=True, - kw_only=False, - eq=True, - eq_key=None, - order=False, - order_key=None, - inherited=False, - on_setattr=None, - ) - for name in ( - "counter", - "_default", - "repr", - "eq", - "order", - "hash", - "init", - "on_setattr", - ) - ) + ( - Attribute( - name="metadata", - default=None, - validator=None, - repr=True, - cmp=None, - hash=False, - init=True, - kw_only=False, - eq=True, - eq_key=None, - order=False, - order_key=None, - inherited=False, - on_setattr=None, - ), - ) - cls_counter = 0 - - def __init__( - self, - default, - validator, - repr, - cmp, - hash, - init, - converter, - metadata, - type, - kw_only, - eq, - eq_key, - order, - order_key, - on_setattr, - ): - _CountingAttr.cls_counter += 1 - self.counter = _CountingAttr.cls_counter - self._default = default - self._validator = validator - self.converter = converter - self.repr = repr - self.eq = eq - self.eq_key = eq_key - self.order = order - self.order_key = order_key - self.hash = hash - self.init = init - self.metadata = metadata - self.type = type - self.kw_only = kw_only - self.on_setattr = on_setattr - - def validator(self, meth): - """ - Decorator that adds *meth* to the list of validators. - - Returns *meth* unchanged. - - .. versionadded:: 17.1.0 - """ - if self._validator is None: - self._validator = meth - else: - self._validator = and_(self._validator, meth) - return meth - - def default(self, meth): - """ - Decorator that allows to set the default for an attribute. - - Returns *meth* unchanged. - - :raises DefaultAlreadySetError: If default has been set before. - - .. versionadded:: 17.1.0 - """ - if self._default is not NOTHING: - raise DefaultAlreadySetError() - - self._default = Factory(meth, takes_self=True) - - return meth - - -_CountingAttr = _add_eq(_add_repr(_CountingAttr)) - - -class Factory(object): - """ - Stores a factory callable. - - If passed as the default value to `attr.ib`, the factory is used to - generate a new value. - - :param callable factory: A callable that takes either none or exactly one - mandatory positional argument depending on *takes_self*. - :param bool takes_self: Pass the partially initialized instance that is - being initialized as a positional argument. - - .. versionadded:: 17.1.0 *takes_self* - """ - - __slots__ = ("factory", "takes_self") - - def __init__(self, factory, takes_self=False): - """ - `Factory` is part of the default machinery so if we want a default - value here, we have to implement it ourselves. - """ - self.factory = factory - self.takes_self = takes_self - - def __getstate__(self): - """ - Play nice with pickle. - """ - return tuple(getattr(self, name) for name in self.__slots__) - - def __setstate__(self, state): - """ - Play nice with pickle. - """ - for name, value in zip(self.__slots__, state): - setattr(self, name, value) - - -_f = [ - Attribute( - name=name, - default=NOTHING, - validator=None, - repr=True, - cmp=None, - eq=True, - order=False, - hash=True, - init=True, - inherited=False, - ) - for name in Factory.__slots__ -] - -Factory = _add_hash(_add_eq(_add_repr(Factory, attrs=_f), attrs=_f), attrs=_f) - - -def make_class(name, attrs, bases=(object,), **attributes_arguments): - """ - A quick way to create a new class called *name* with *attrs*. - - :param str name: The name for the new class. - - :param attrs: A list of names or a dictionary of mappings of names to - attributes. - - If *attrs* is a list or an ordered dict (`dict` on Python 3.6+, - `collections.OrderedDict` otherwise), the order is deduced from - the order of the names or attributes inside *attrs*. Otherwise the - order of the definition of the attributes is used. - :type attrs: `list` or `dict` - - :param tuple bases: Classes that the new class will subclass. - - :param attributes_arguments: Passed unmodified to `attr.s`. - - :return: A new class with *attrs*. - :rtype: type - - .. versionadded:: 17.1.0 *bases* - .. versionchanged:: 18.1.0 If *attrs* is ordered, the order is retained. - """ - if isinstance(attrs, dict): - cls_dict = attrs - elif isinstance(attrs, (list, tuple)): - cls_dict = dict((a, attrib()) for a in attrs) - else: - raise TypeError("attrs argument must be a dict or a list.") - - pre_init = cls_dict.pop("__attrs_pre_init__", None) - post_init = cls_dict.pop("__attrs_post_init__", None) - user_init = cls_dict.pop("__init__", None) - - body = {} - if pre_init is not None: - body["__attrs_pre_init__"] = pre_init - if post_init is not None: - body["__attrs_post_init__"] = post_init - if user_init is not None: - body["__init__"] = user_init - - type_ = new_class(name, bases, {}, lambda ns: ns.update(body)) - - # For pickling to work, the __module__ variable needs to be set to the - # frame where the class is created. Bypass this step in environments where - # sys._getframe is not defined (Jython for example) or sys._getframe is not - # defined for arguments greater than 0 (IronPython). - try: - type_.__module__ = sys._getframe(1).f_globals.get( - "__name__", "__main__" - ) - except (AttributeError, ValueError): - pass - - # We do it here for proper warnings with meaningful stacklevel. - cmp = attributes_arguments.pop("cmp", None) - ( - attributes_arguments["eq"], - attributes_arguments["order"], - ) = _determine_attrs_eq_order( - cmp, - attributes_arguments.get("eq"), - attributes_arguments.get("order"), - True, - ) - - return _attrs(these=cls_dict, **attributes_arguments)(type_) - - -# These are required by within this module so we define them here and merely -# import into .validators / .converters. - - -@attrs(slots=True, hash=True) -class _AndValidator(object): - """ - Compose many validators to a single one. - """ - - _validators = attrib() - - def __call__(self, inst, attr, value): - for v in self._validators: - v(inst, attr, value) - - -def and_(*validators): - """ - A validator that composes multiple validators into one. - - When called on a value, it runs all wrapped validators. - - :param callables validators: Arbitrary number of validators. - - .. versionadded:: 17.1.0 - """ - vals = [] - for validator in validators: - vals.extend( - validator._validators - if isinstance(validator, _AndValidator) - else [validator] - ) - - return _AndValidator(tuple(vals)) - - -def pipe(*converters): - """ - A converter that composes multiple converters into one. - - When called on a value, it runs all wrapped converters, returning the - *last* value. - - Type annotations will be inferred from the wrapped converters', if - they have any. - - :param callables converters: Arbitrary number of converters. - - .. versionadded:: 20.1.0 - """ - - def pipe_converter(val): - for converter in converters: - val = converter(val) - - return val - - if not PY2: - if not converters: - # If the converter list is empty, pipe_converter is the identity. - A = typing.TypeVar("A") - pipe_converter.__annotations__ = {"val": A, "return": A} - else: - # Get parameter type. - sig = None - try: - sig = inspect.signature(converters[0]) - except (ValueError, TypeError): # inspect failed - pass - if sig: - params = list(sig.parameters.values()) - if ( - params - and params[0].annotation is not inspect.Parameter.empty - ): - pipe_converter.__annotations__["val"] = params[ - 0 - ].annotation - # Get return type. - sig = None - try: - sig = inspect.signature(converters[-1]) - except (ValueError, TypeError): # inspect failed - pass - if sig and sig.return_annotation is not inspect.Signature().empty: - pipe_converter.__annotations__[ - "return" - ] = sig.return_annotation - - return pipe_converter diff --git a/server_addon/fusion/client/ayon_fusion/vendor/attr/_next_gen.py b/server_addon/fusion/client/ayon_fusion/vendor/attr/_next_gen.py deleted file mode 100644 index fab0af966a..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/attr/_next_gen.py +++ /dev/null @@ -1,158 +0,0 @@ -""" -These are Python 3.6+-only and keyword-only APIs that call `attr.s` and -`attr.ib` with different default values. -""" - -from functools import partial - -from attr.exceptions import UnannotatedAttributeError - -from . import setters -from ._make import NOTHING, _frozen_setattrs, attrib, attrs - - -def define( - maybe_cls=None, - *, - these=None, - repr=None, - hash=None, - init=None, - slots=True, - frozen=False, - weakref_slot=True, - str=False, - auto_attribs=None, - kw_only=False, - cache_hash=False, - auto_exc=True, - eq=None, - order=False, - auto_detect=True, - getstate_setstate=None, - on_setattr=None, - field_transformer=None, -): - r""" - The only behavioral differences are the handling of the *auto_attribs* - option: - - :param Optional[bool] auto_attribs: If set to `True` or `False`, it behaves - exactly like `attr.s`. If left `None`, `attr.s` will try to guess: - - 1. If any attributes are annotated and no unannotated `attr.ib`\ s - are found, it assumes *auto_attribs=True*. - 2. Otherwise it assumes *auto_attribs=False* and tries to collect - `attr.ib`\ s. - - and that mutable classes (``frozen=False``) validate on ``__setattr__``. - - .. versionadded:: 20.1.0 - """ - - def do_it(cls, auto_attribs): - return attrs( - maybe_cls=cls, - these=these, - repr=repr, - hash=hash, - init=init, - slots=slots, - frozen=frozen, - weakref_slot=weakref_slot, - str=str, - auto_attribs=auto_attribs, - kw_only=kw_only, - cache_hash=cache_hash, - auto_exc=auto_exc, - eq=eq, - order=order, - auto_detect=auto_detect, - collect_by_mro=True, - getstate_setstate=getstate_setstate, - on_setattr=on_setattr, - field_transformer=field_transformer, - ) - - def wrap(cls): - """ - Making this a wrapper ensures this code runs during class creation. - - We also ensure that frozen-ness of classes is inherited. - """ - nonlocal frozen, on_setattr - - had_on_setattr = on_setattr not in (None, setters.NO_OP) - - # By default, mutable classes validate on setattr. - if frozen is False and on_setattr is None: - on_setattr = setters.validate - - # However, if we subclass a frozen class, we inherit the immutability - # and disable on_setattr. - for base_cls in cls.__bases__: - if base_cls.__setattr__ is _frozen_setattrs: - if had_on_setattr: - raise ValueError( - "Frozen classes can't use on_setattr " - "(frozen-ness was inherited)." - ) - - on_setattr = setters.NO_OP - break - - if auto_attribs is not None: - return do_it(cls, auto_attribs) - - try: - return do_it(cls, True) - except UnannotatedAttributeError: - return do_it(cls, False) - - # maybe_cls's type depends on the usage of the decorator. It's a class - # if it's used as `@attrs` but ``None`` if used as `@attrs()`. - if maybe_cls is None: - return wrap - else: - return wrap(maybe_cls) - - -mutable = define -frozen = partial(define, frozen=True, on_setattr=None) - - -def field( - *, - default=NOTHING, - validator=None, - repr=True, - hash=None, - init=True, - metadata=None, - converter=None, - factory=None, - kw_only=False, - eq=None, - order=None, - on_setattr=None, -): - """ - Identical to `attr.ib`, except keyword-only and with some arguments - removed. - - .. versionadded:: 20.1.0 - """ - return attrib( - default=default, - validator=validator, - repr=repr, - hash=hash, - init=init, - metadata=metadata, - converter=converter, - factory=factory, - kw_only=kw_only, - eq=eq, - order=order, - on_setattr=on_setattr, - ) diff --git a/server_addon/fusion/client/ayon_fusion/vendor/attr/_version_info.py b/server_addon/fusion/client/ayon_fusion/vendor/attr/_version_info.py deleted file mode 100644 index 014e78a1b4..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/attr/_version_info.py +++ /dev/null @@ -1,85 +0,0 @@ -from __future__ import absolute_import, division, print_function - -from functools import total_ordering - -from ._funcs import astuple -from ._make import attrib, attrs - - -@total_ordering -@attrs(eq=False, order=False, slots=True, frozen=True) -class VersionInfo(object): - """ - A version object that can be compared to tuple of length 1--4: - - >>> attr.VersionInfo(19, 1, 0, "final") <= (19, 2) - True - >>> attr.VersionInfo(19, 1, 0, "final") < (19, 1, 1) - True - >>> vi = attr.VersionInfo(19, 2, 0, "final") - >>> vi < (19, 1, 1) - False - >>> vi < (19,) - False - >>> vi == (19, 2,) - True - >>> vi == (19, 2, 1) - False - - .. versionadded:: 19.2 - """ - - year = attrib(type=int) - minor = attrib(type=int) - micro = attrib(type=int) - releaselevel = attrib(type=str) - - @classmethod - def _from_version_string(cls, s): - """ - Parse *s* and return a _VersionInfo. - """ - v = s.split(".") - if len(v) == 3: - v.append("final") - - return cls( - year=int(v[0]), minor=int(v[1]), micro=int(v[2]), releaselevel=v[3] - ) - - def _ensure_tuple(self, other): - """ - Ensure *other* is a tuple of a valid length. - - Returns a possibly transformed *other* and ourselves as a tuple of - the same length as *other*. - """ - - if self.__class__ is other.__class__: - other = astuple(other) - - if not isinstance(other, tuple): - raise NotImplementedError - - if not (1 <= len(other) <= 4): - raise NotImplementedError - - return astuple(self)[: len(other)], other - - def __eq__(self, other): - try: - us, them = self._ensure_tuple(other) - except NotImplementedError: - return NotImplemented - - return us == them - - def __lt__(self, other): - try: - us, them = self._ensure_tuple(other) - except NotImplementedError: - return NotImplemented - - # Since alphabetically "dev0" < "final" < "post1" < "post2", we don't - # have to do anything special with releaselevel for now. - return us < them diff --git a/server_addon/fusion/client/ayon_fusion/vendor/attr/_version_info.pyi b/server_addon/fusion/client/ayon_fusion/vendor/attr/_version_info.pyi deleted file mode 100644 index 45ced08633..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/attr/_version_info.pyi +++ /dev/null @@ -1,9 +0,0 @@ -class VersionInfo: - @property - def year(self) -> int: ... - @property - def minor(self) -> int: ... - @property - def micro(self) -> int: ... - @property - def releaselevel(self) -> str: ... diff --git a/server_addon/fusion/client/ayon_fusion/vendor/attr/converters.py b/server_addon/fusion/client/ayon_fusion/vendor/attr/converters.py deleted file mode 100644 index 2777db6d0a..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/attr/converters.py +++ /dev/null @@ -1,111 +0,0 @@ -""" -Commonly useful converters. -""" - -from __future__ import absolute_import, division, print_function - -from ._compat import PY2 -from ._make import NOTHING, Factory, pipe - - -if not PY2: - import inspect - import typing - - -__all__ = [ - "pipe", - "optional", - "default_if_none", -] - - -def optional(converter): - """ - A converter that allows an attribute to be optional. An optional attribute - is one which can be set to ``None``. - - Type annotations will be inferred from the wrapped converter's, if it - has any. - - :param callable converter: the converter that is used for non-``None`` - values. - - .. versionadded:: 17.1.0 - """ - - def optional_converter(val): - if val is None: - return None - return converter(val) - - if not PY2: - sig = None - try: - sig = inspect.signature(converter) - except (ValueError, TypeError): # inspect failed - pass - if sig: - params = list(sig.parameters.values()) - if params and params[0].annotation is not inspect.Parameter.empty: - optional_converter.__annotations__["val"] = typing.Optional[ - params[0].annotation - ] - if sig.return_annotation is not inspect.Signature.empty: - optional_converter.__annotations__["return"] = typing.Optional[ - sig.return_annotation - ] - - return optional_converter - - -def default_if_none(default=NOTHING, factory=None): - """ - A converter that allows to replace ``None`` values by *default* or the - result of *factory*. - - :param default: Value to be used if ``None`` is passed. Passing an instance - of `attr.Factory` is supported, however the ``takes_self`` option - is *not*. - :param callable factory: A callable that takes no parameters whose result - is used if ``None`` is passed. - - :raises TypeError: If **neither** *default* or *factory* is passed. - :raises TypeError: If **both** *default* and *factory* are passed. - :raises ValueError: If an instance of `attr.Factory` is passed with - ``takes_self=True``. - - .. versionadded:: 18.2.0 - """ - if default is NOTHING and factory is None: - raise TypeError("Must pass either `default` or `factory`.") - - if default is not NOTHING and factory is not None: - raise TypeError( - "Must pass either `default` or `factory` but not both." - ) - - if factory is not None: - default = Factory(factory) - - if isinstance(default, Factory): - if default.takes_self: - raise ValueError( - "`takes_self` is not supported by default_if_none." - ) - - def default_if_none_converter(val): - if val is not None: - return val - - return default.factory() - - else: - - def default_if_none_converter(val): - if val is not None: - return val - - return default - - return default_if_none_converter diff --git a/server_addon/fusion/client/ayon_fusion/vendor/attr/converters.pyi b/server_addon/fusion/client/ayon_fusion/vendor/attr/converters.pyi deleted file mode 100644 index 84a57590b0..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/attr/converters.pyi +++ /dev/null @@ -1,13 +0,0 @@ -from typing import Callable, Optional, TypeVar, overload - -from . import _ConverterType - - -_T = TypeVar("_T") - -def pipe(*validators: _ConverterType) -> _ConverterType: ... -def optional(converter: _ConverterType) -> _ConverterType: ... -@overload -def default_if_none(default: _T) -> _ConverterType: ... -@overload -def default_if_none(*, factory: Callable[[], _T]) -> _ConverterType: ... diff --git a/server_addon/fusion/client/ayon_fusion/vendor/attr/exceptions.py b/server_addon/fusion/client/ayon_fusion/vendor/attr/exceptions.py deleted file mode 100644 index f6f9861bea..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/attr/exceptions.py +++ /dev/null @@ -1,92 +0,0 @@ -from __future__ import absolute_import, division, print_function - - -class FrozenError(AttributeError): - """ - A frozen/immutable instance or attribute have been attempted to be - modified. - - It mirrors the behavior of ``namedtuples`` by using the same error message - and subclassing `AttributeError`. - - .. versionadded:: 20.1.0 - """ - - msg = "can't set attribute" - args = [msg] - - -class FrozenInstanceError(FrozenError): - """ - A frozen instance has been attempted to be modified. - - .. versionadded:: 16.1.0 - """ - - -class FrozenAttributeError(FrozenError): - """ - A frozen attribute has been attempted to be modified. - - .. versionadded:: 20.1.0 - """ - - -class AttrsAttributeNotFoundError(ValueError): - """ - An ``attrs`` function couldn't find an attribute that the user asked for. - - .. versionadded:: 16.2.0 - """ - - -class NotAnAttrsClassError(ValueError): - """ - A non-``attrs`` class has been passed into an ``attrs`` function. - - .. versionadded:: 16.2.0 - """ - - -class DefaultAlreadySetError(RuntimeError): - """ - A default has been set using ``attr.ib()`` and is attempted to be reset - using the decorator. - - .. versionadded:: 17.1.0 - """ - - -class UnannotatedAttributeError(RuntimeError): - """ - A class with ``auto_attribs=True`` has an ``attr.ib()`` without a type - annotation. - - .. versionadded:: 17.3.0 - """ - - -class PythonTooOldError(RuntimeError): - """ - It was attempted to use an ``attrs`` feature that requires a newer Python - version. - - .. versionadded:: 18.2.0 - """ - - -class NotCallableError(TypeError): - """ - A ``attr.ib()`` requiring a callable has been set with a value - that is not callable. - - .. versionadded:: 19.2.0 - """ - - def __init__(self, msg, value): - super(TypeError, self).__init__(msg, value) - self.msg = msg - self.value = value - - def __str__(self): - return str(self.msg) diff --git a/server_addon/fusion/client/ayon_fusion/vendor/attr/exceptions.pyi b/server_addon/fusion/client/ayon_fusion/vendor/attr/exceptions.pyi deleted file mode 100644 index a800fb26bb..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/attr/exceptions.pyi +++ /dev/null @@ -1,18 +0,0 @@ -from typing import Any - - -class FrozenError(AttributeError): - msg: str = ... - -class FrozenInstanceError(FrozenError): ... -class FrozenAttributeError(FrozenError): ... -class AttrsAttributeNotFoundError(ValueError): ... -class NotAnAttrsClassError(ValueError): ... -class DefaultAlreadySetError(RuntimeError): ... -class UnannotatedAttributeError(RuntimeError): ... -class PythonTooOldError(RuntimeError): ... - -class NotCallableError(TypeError): - msg: str = ... - value: Any = ... - def __init__(self, msg: str, value: Any) -> None: ... diff --git a/server_addon/fusion/client/ayon_fusion/vendor/attr/filters.py b/server_addon/fusion/client/ayon_fusion/vendor/attr/filters.py deleted file mode 100644 index dc47e8fa38..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/attr/filters.py +++ /dev/null @@ -1,52 +0,0 @@ -""" -Commonly useful filters for `attr.asdict`. -""" - -from __future__ import absolute_import, division, print_function - -from ._compat import isclass -from ._make import Attribute - - -def _split_what(what): - """ - Returns a tuple of `frozenset`s of classes and attributes. - """ - return ( - frozenset(cls for cls in what if isclass(cls)), - frozenset(cls for cls in what if isinstance(cls, Attribute)), - ) - - -def include(*what): - """ - Whitelist *what*. - - :param what: What to whitelist. - :type what: `list` of `type` or `attr.Attribute`\\ s - - :rtype: `callable` - """ - cls, attrs = _split_what(what) - - def include_(attribute, value): - return value.__class__ in cls or attribute in attrs - - return include_ - - -def exclude(*what): - """ - Blacklist *what*. - - :param what: What to blacklist. - :type what: `list` of classes or `attr.Attribute`\\ s. - - :rtype: `callable` - """ - cls, attrs = _split_what(what) - - def exclude_(attribute, value): - return value.__class__ not in cls and attribute not in attrs - - return exclude_ diff --git a/server_addon/fusion/client/ayon_fusion/vendor/attr/filters.pyi b/server_addon/fusion/client/ayon_fusion/vendor/attr/filters.pyi deleted file mode 100644 index f7b63f1bb4..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/attr/filters.pyi +++ /dev/null @@ -1,7 +0,0 @@ -from typing import Any, Union - -from . import Attribute, _FilterType - - -def include(*what: Union[type, Attribute[Any]]) -> _FilterType[Any]: ... -def exclude(*what: Union[type, Attribute[Any]]) -> _FilterType[Any]: ... diff --git a/server_addon/fusion/client/ayon_fusion/vendor/attr/py.typed b/server_addon/fusion/client/ayon_fusion/vendor/attr/py.typed deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/server_addon/fusion/client/ayon_fusion/vendor/attr/setters.py b/server_addon/fusion/client/ayon_fusion/vendor/attr/setters.py deleted file mode 100644 index 240014b3c1..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/attr/setters.py +++ /dev/null @@ -1,77 +0,0 @@ -""" -Commonly used hooks for on_setattr. -""" - -from __future__ import absolute_import, division, print_function - -from . import _config -from .exceptions import FrozenAttributeError - - -def pipe(*setters): - """ - Run all *setters* and return the return value of the last one. - - .. versionadded:: 20.1.0 - """ - - def wrapped_pipe(instance, attrib, new_value): - rv = new_value - - for setter in setters: - rv = setter(instance, attrib, rv) - - return rv - - return wrapped_pipe - - -def frozen(_, __, ___): - """ - Prevent an attribute to be modified. - - .. versionadded:: 20.1.0 - """ - raise FrozenAttributeError() - - -def validate(instance, attrib, new_value): - """ - Run *attrib*'s validator on *new_value* if it has one. - - .. versionadded:: 20.1.0 - """ - if _config._run_validators is False: - return new_value - - v = attrib.validator - if not v: - return new_value - - v(instance, attrib, new_value) - - return new_value - - -def convert(instance, attrib, new_value): - """ - Run *attrib*'s converter -- if it has one -- on *new_value* and return the - result. - - .. versionadded:: 20.1.0 - """ - c = attrib.converter - if c: - return c(new_value) - - return new_value - - -NO_OP = object() -""" -Sentinel for disabling class-wide *on_setattr* hooks for certain attributes. - -Does not work in `pipe` or within lists. - -.. versionadded:: 20.1.0 -""" diff --git a/server_addon/fusion/client/ayon_fusion/vendor/attr/setters.pyi b/server_addon/fusion/client/ayon_fusion/vendor/attr/setters.pyi deleted file mode 100644 index a921e07deb..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/attr/setters.pyi +++ /dev/null @@ -1,20 +0,0 @@ -from typing import Any, NewType, NoReturn, TypeVar, cast - -from . import Attribute, _OnSetAttrType - - -_T = TypeVar("_T") - -def frozen( - instance: Any, attribute: Attribute[Any], new_value: Any -) -> NoReturn: ... -def pipe(*setters: _OnSetAttrType) -> _OnSetAttrType: ... -def validate(instance: Any, attribute: Attribute[_T], new_value: _T) -> _T: ... - -# convert is allowed to return Any, because they can be chained using pipe. -def convert( - instance: Any, attribute: Attribute[Any], new_value: Any -) -> Any: ... - -_NoOpType = NewType("_NoOpType", object) -NO_OP: _NoOpType diff --git a/server_addon/fusion/client/ayon_fusion/vendor/attr/validators.py b/server_addon/fusion/client/ayon_fusion/vendor/attr/validators.py deleted file mode 100644 index b9a73054e9..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/attr/validators.py +++ /dev/null @@ -1,379 +0,0 @@ -""" -Commonly useful validators. -""" - -from __future__ import absolute_import, division, print_function - -import re - -from ._make import _AndValidator, and_, attrib, attrs -from .exceptions import NotCallableError - - -__all__ = [ - "and_", - "deep_iterable", - "deep_mapping", - "in_", - "instance_of", - "is_callable", - "matches_re", - "optional", - "provides", -] - - -@attrs(repr=False, slots=True, hash=True) -class _InstanceOfValidator(object): - type = attrib() - - def __call__(self, inst, attr, value): - """ - We use a callable class to be able to change the ``__repr__``. - """ - if not isinstance(value, self.type): - raise TypeError( - "'{name}' must be {type!r} (got {value!r} that is a " - "{actual!r}).".format( - name=attr.name, - type=self.type, - actual=value.__class__, - value=value, - ), - attr, - self.type, - value, - ) - - def __repr__(self): - return "".format( - type=self.type - ) - - -def instance_of(type): - """ - A validator that raises a `TypeError` if the initializer is called - with a wrong type for this particular attribute (checks are performed using - `isinstance` therefore it's also valid to pass a tuple of types). - - :param type: The type to check for. - :type type: type or tuple of types - - :raises TypeError: With a human readable error message, the attribute - (of type `attr.Attribute`), the expected type, and the value it - got. - """ - return _InstanceOfValidator(type) - - -@attrs(repr=False, frozen=True, slots=True) -class _MatchesReValidator(object): - regex = attrib() - flags = attrib() - match_func = attrib() - - def __call__(self, inst, attr, value): - """ - We use a callable class to be able to change the ``__repr__``. - """ - if not self.match_func(value): - raise ValueError( - "'{name}' must match regex {regex!r}" - " ({value!r} doesn't)".format( - name=attr.name, regex=self.regex.pattern, value=value - ), - attr, - self.regex, - value, - ) - - def __repr__(self): - return "".format( - regex=self.regex - ) - - -def matches_re(regex, flags=0, func=None): - r""" - A validator that raises `ValueError` if the initializer is called - with a string that doesn't match *regex*. - - :param str regex: a regex string to match against - :param int flags: flags that will be passed to the underlying re function - (default 0) - :param callable func: which underlying `re` function to call (options - are `re.fullmatch`, `re.search`, `re.match`, default - is ``None`` which means either `re.fullmatch` or an emulation of - it on Python 2). For performance reasons, they won't be used directly - but on a pre-`re.compile`\ ed pattern. - - .. versionadded:: 19.2.0 - """ - fullmatch = getattr(re, "fullmatch", None) - valid_funcs = (fullmatch, None, re.search, re.match) - if func not in valid_funcs: - raise ValueError( - "'func' must be one of %s." - % ( - ", ".join( - sorted( - e and e.__name__ or "None" for e in set(valid_funcs) - ) - ), - ) - ) - - pattern = re.compile(regex, flags) - if func is re.match: - match_func = pattern.match - elif func is re.search: - match_func = pattern.search - else: - if fullmatch: - match_func = pattern.fullmatch - else: - pattern = re.compile(r"(?:{})\Z".format(regex), flags) - match_func = pattern.match - - return _MatchesReValidator(pattern, flags, match_func) - - -@attrs(repr=False, slots=True, hash=True) -class _ProvidesValidator(object): - interface = attrib() - - def __call__(self, inst, attr, value): - """ - We use a callable class to be able to change the ``__repr__``. - """ - if not self.interface.providedBy(value): - raise TypeError( - "'{name}' must provide {interface!r} which {value!r} " - "doesn't.".format( - name=attr.name, interface=self.interface, value=value - ), - attr, - self.interface, - value, - ) - - def __repr__(self): - return "".format( - interface=self.interface - ) - - -def provides(interface): - """ - A validator that raises a `TypeError` if the initializer is called - with an object that does not provide the requested *interface* (checks are - performed using ``interface.providedBy(value)`` (see `zope.interface - `_). - - :param interface: The interface to check for. - :type interface: ``zope.interface.Interface`` - - :raises TypeError: With a human readable error message, the attribute - (of type `attr.Attribute`), the expected interface, and the - value it got. - """ - return _ProvidesValidator(interface) - - -@attrs(repr=False, slots=True, hash=True) -class _OptionalValidator(object): - validator = attrib() - - def __call__(self, inst, attr, value): - if value is None: - return - - self.validator(inst, attr, value) - - def __repr__(self): - return "".format( - what=repr(self.validator) - ) - - -def optional(validator): - """ - A validator that makes an attribute optional. An optional attribute is one - which can be set to ``None`` in addition to satisfying the requirements of - the sub-validator. - - :param validator: A validator (or a list of validators) that is used for - non-``None`` values. - :type validator: callable or `list` of callables. - - .. versionadded:: 15.1.0 - .. versionchanged:: 17.1.0 *validator* can be a list of validators. - """ - if isinstance(validator, list): - return _OptionalValidator(_AndValidator(validator)) - return _OptionalValidator(validator) - - -@attrs(repr=False, slots=True, hash=True) -class _InValidator(object): - options = attrib() - - def __call__(self, inst, attr, value): - try: - in_options = value in self.options - except TypeError: # e.g. `1 in "abc"` - in_options = False - - if not in_options: - raise ValueError( - "'{name}' must be in {options!r} (got {value!r})".format( - name=attr.name, options=self.options, value=value - ) - ) - - def __repr__(self): - return "".format( - options=self.options - ) - - -def in_(options): - """ - A validator that raises a `ValueError` if the initializer is called - with a value that does not belong in the options provided. The check is - performed using ``value in options``. - - :param options: Allowed options. - :type options: list, tuple, `enum.Enum`, ... - - :raises ValueError: With a human readable error message, the attribute (of - type `attr.Attribute`), the expected options, and the value it - got. - - .. versionadded:: 17.1.0 - """ - return _InValidator(options) - - -@attrs(repr=False, slots=False, hash=True) -class _IsCallableValidator(object): - def __call__(self, inst, attr, value): - """ - We use a callable class to be able to change the ``__repr__``. - """ - if not callable(value): - message = ( - "'{name}' must be callable " - "(got {value!r} that is a {actual!r})." - ) - raise NotCallableError( - msg=message.format( - name=attr.name, value=value, actual=value.__class__ - ), - value=value, - ) - - def __repr__(self): - return "" - - -def is_callable(): - """ - A validator that raises a `attr.exceptions.NotCallableError` if the - initializer is called with a value for this particular attribute - that is not callable. - - .. versionadded:: 19.1.0 - - :raises `attr.exceptions.NotCallableError`: With a human readable error - message containing the attribute (`attr.Attribute`) name, - and the value it got. - """ - return _IsCallableValidator() - - -@attrs(repr=False, slots=True, hash=True) -class _DeepIterable(object): - member_validator = attrib(validator=is_callable()) - iterable_validator = attrib( - default=None, validator=optional(is_callable()) - ) - - def __call__(self, inst, attr, value): - """ - We use a callable class to be able to change the ``__repr__``. - """ - if self.iterable_validator is not None: - self.iterable_validator(inst, attr, value) - - for member in value: - self.member_validator(inst, attr, member) - - def __repr__(self): - iterable_identifier = ( - "" - if self.iterable_validator is None - else " {iterable!r}".format(iterable=self.iterable_validator) - ) - return ( - "" - ).format( - iterable_identifier=iterable_identifier, - member=self.member_validator, - ) - - -def deep_iterable(member_validator, iterable_validator=None): - """ - A validator that performs deep validation of an iterable. - - :param member_validator: Validator to apply to iterable members - :param iterable_validator: Validator to apply to iterable itself - (optional) - - .. versionadded:: 19.1.0 - - :raises TypeError: if any sub-validators fail - """ - return _DeepIterable(member_validator, iterable_validator) - - -@attrs(repr=False, slots=True, hash=True) -class _DeepMapping(object): - key_validator = attrib(validator=is_callable()) - value_validator = attrib(validator=is_callable()) - mapping_validator = attrib(default=None, validator=optional(is_callable())) - - def __call__(self, inst, attr, value): - """ - We use a callable class to be able to change the ``__repr__``. - """ - if self.mapping_validator is not None: - self.mapping_validator(inst, attr, value) - - for key in value: - self.key_validator(inst, attr, key) - self.value_validator(inst, attr, value[key]) - - def __repr__(self): - return ( - "" - ).format(key=self.key_validator, value=self.value_validator) - - -def deep_mapping(key_validator, value_validator, mapping_validator=None): - """ - A validator that performs deep validation of a dictionary. - - :param key_validator: Validator to apply to dictionary keys - :param value_validator: Validator to apply to dictionary values - :param mapping_validator: Validator to apply to top-level mapping - attribute (optional) - - .. versionadded:: 19.1.0 - - :raises TypeError: if any sub-validators fail - """ - return _DeepMapping(key_validator, value_validator, mapping_validator) diff --git a/server_addon/fusion/client/ayon_fusion/vendor/attr/validators.pyi b/server_addon/fusion/client/ayon_fusion/vendor/attr/validators.pyi deleted file mode 100644 index fe92aac421..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/attr/validators.pyi +++ /dev/null @@ -1,68 +0,0 @@ -from typing import ( - Any, - AnyStr, - Callable, - Container, - Iterable, - List, - Mapping, - Match, - Optional, - Tuple, - Type, - TypeVar, - Union, - overload, -) - -from . import _ValidatorType - - -_T = TypeVar("_T") -_T1 = TypeVar("_T1") -_T2 = TypeVar("_T2") -_T3 = TypeVar("_T3") -_I = TypeVar("_I", bound=Iterable) -_K = TypeVar("_K") -_V = TypeVar("_V") -_M = TypeVar("_M", bound=Mapping) - -# To be more precise on instance_of use some overloads. -# If there are more than 3 items in the tuple then we fall back to Any -@overload -def instance_of(type: Type[_T]) -> _ValidatorType[_T]: ... -@overload -def instance_of(type: Tuple[Type[_T]]) -> _ValidatorType[_T]: ... -@overload -def instance_of( - type: Tuple[Type[_T1], Type[_T2]] -) -> _ValidatorType[Union[_T1, _T2]]: ... -@overload -def instance_of( - type: Tuple[Type[_T1], Type[_T2], Type[_T3]] -) -> _ValidatorType[Union[_T1, _T2, _T3]]: ... -@overload -def instance_of(type: Tuple[type, ...]) -> _ValidatorType[Any]: ... -def provides(interface: Any) -> _ValidatorType[Any]: ... -def optional( - validator: Union[_ValidatorType[_T], List[_ValidatorType[_T]]] -) -> _ValidatorType[Optional[_T]]: ... -def in_(options: Container[_T]) -> _ValidatorType[_T]: ... -def and_(*validators: _ValidatorType[_T]) -> _ValidatorType[_T]: ... -def matches_re( - regex: AnyStr, - flags: int = ..., - func: Optional[ - Callable[[AnyStr, AnyStr, int], Optional[Match[AnyStr]]] - ] = ..., -) -> _ValidatorType[AnyStr]: ... -def deep_iterable( - member_validator: _ValidatorType[_T], - iterable_validator: Optional[_ValidatorType[_I]] = ..., -) -> _ValidatorType[_I]: ... -def deep_mapping( - key_validator: _ValidatorType[_K], - value_validator: _ValidatorType[_V], - mapping_validator: Optional[_ValidatorType[_M]] = ..., -) -> _ValidatorType[_M]: ... -def is_callable() -> _ValidatorType[_T]: ... diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/__init__.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/__init__.py deleted file mode 100644 index fe86b59d78..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/__init__.py +++ /dev/null @@ -1,85 +0,0 @@ -""" -Python HTTP library with thread-safe connection pooling, file post support, user friendly, and more -""" -from __future__ import absolute_import - -# Set default logging handler to avoid "No handler found" warnings. -import logging -import warnings -from logging import NullHandler - -from . import exceptions -from ._version import __version__ -from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool, connection_from_url -from .filepost import encode_multipart_formdata -from .poolmanager import PoolManager, ProxyManager, proxy_from_url -from .response import HTTPResponse -from .util.request import make_headers -from .util.retry import Retry -from .util.timeout import Timeout -from .util.url import get_host - -__author__ = "Andrey Petrov (andrey.petrov@shazow.net)" -__license__ = "MIT" -__version__ = __version__ - -__all__ = ( - "HTTPConnectionPool", - "HTTPSConnectionPool", - "PoolManager", - "ProxyManager", - "HTTPResponse", - "Retry", - "Timeout", - "add_stderr_logger", - "connection_from_url", - "disable_warnings", - "encode_multipart_formdata", - "get_host", - "make_headers", - "proxy_from_url", -) - -logging.getLogger(__name__).addHandler(NullHandler()) - - -def add_stderr_logger(level=logging.DEBUG): - """ - Helper for quickly adding a StreamHandler to the logger. Useful for - debugging. - - Returns the handler after adding it. - """ - # This method needs to be in this __init__.py to get the __name__ correct - # even if urllib3 is vendored within another package. - logger = logging.getLogger(__name__) - handler = logging.StreamHandler() - handler.setFormatter(logging.Formatter("%(asctime)s %(levelname)s %(message)s")) - logger.addHandler(handler) - logger.setLevel(level) - logger.debug("Added a stderr logging handler to logger: %s", __name__) - return handler - - -# ... Clean up. -del NullHandler - - -# All warning filters *must* be appended unless you're really certain that they -# shouldn't be: otherwise, it's very hard for users to use most Python -# mechanisms to silence them. -# SecurityWarning's always go off by default. -warnings.simplefilter("always", exceptions.SecurityWarning, append=True) -# SubjectAltNameWarning's should go off once per host -warnings.simplefilter("default", exceptions.SubjectAltNameWarning, append=True) -# InsecurePlatformWarning's don't vary between requests, so we keep it default. -warnings.simplefilter("default", exceptions.InsecurePlatformWarning, append=True) -# SNIMissingWarnings should go off only once. -warnings.simplefilter("default", exceptions.SNIMissingWarning, append=True) - - -def disable_warnings(category=exceptions.HTTPWarning): - """ - Helper for quickly disabling all urllib3 warnings. - """ - warnings.simplefilter("ignore", category) diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/_collections.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/_collections.py deleted file mode 100644 index da9857e986..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/_collections.py +++ /dev/null @@ -1,337 +0,0 @@ -from __future__ import absolute_import - -try: - from collections.abc import Mapping, MutableMapping -except ImportError: - from collections import Mapping, MutableMapping -try: - from threading import RLock -except ImportError: # Platform-specific: No threads available - - class RLock: - def __enter__(self): - pass - - def __exit__(self, exc_type, exc_value, traceback): - pass - - -from collections import OrderedDict - -from .exceptions import InvalidHeader -from .packages import six -from .packages.six import iterkeys, itervalues - -__all__ = ["RecentlyUsedContainer", "HTTPHeaderDict"] - - -_Null = object() - - -class RecentlyUsedContainer(MutableMapping): - """ - Provides a thread-safe dict-like container which maintains up to - ``maxsize`` keys while throwing away the least-recently-used keys beyond - ``maxsize``. - - :param maxsize: - Maximum number of recent elements to retain. - - :param dispose_func: - Every time an item is evicted from the container, - ``dispose_func(value)`` is called. Callback which will get called - """ - - ContainerCls = OrderedDict - - def __init__(self, maxsize=10, dispose_func=None): - self._maxsize = maxsize - self.dispose_func = dispose_func - - self._container = self.ContainerCls() - self.lock = RLock() - - def __getitem__(self, key): - # Re-insert the item, moving it to the end of the eviction line. - with self.lock: - item = self._container.pop(key) - self._container[key] = item - return item - - def __setitem__(self, key, value): - evicted_value = _Null - with self.lock: - # Possibly evict the existing value of 'key' - evicted_value = self._container.get(key, _Null) - self._container[key] = value - - # If we didn't evict an existing value, we might have to evict the - # least recently used item from the beginning of the container. - if len(self._container) > self._maxsize: - _key, evicted_value = self._container.popitem(last=False) - - if self.dispose_func and evicted_value is not _Null: - self.dispose_func(evicted_value) - - def __delitem__(self, key): - with self.lock: - value = self._container.pop(key) - - if self.dispose_func: - self.dispose_func(value) - - def __len__(self): - with self.lock: - return len(self._container) - - def __iter__(self): - raise NotImplementedError( - "Iteration over this class is unlikely to be threadsafe." - ) - - def clear(self): - with self.lock: - # Copy pointers to all values, then wipe the mapping - values = list(itervalues(self._container)) - self._container.clear() - - if self.dispose_func: - for value in values: - self.dispose_func(value) - - def keys(self): - with self.lock: - return list(iterkeys(self._container)) - - -class HTTPHeaderDict(MutableMapping): - """ - :param headers: - An iterable of field-value pairs. Must not contain multiple field names - when compared case-insensitively. - - :param kwargs: - Additional field-value pairs to pass in to ``dict.update``. - - A ``dict`` like container for storing HTTP Headers. - - Field names are stored and compared case-insensitively in compliance with - RFC 7230. Iteration provides the first case-sensitive key seen for each - case-insensitive pair. - - Using ``__setitem__`` syntax overwrites fields that compare equal - case-insensitively in order to maintain ``dict``'s api. For fields that - compare equal, instead create a new ``HTTPHeaderDict`` and use ``.add`` - in a loop. - - If multiple fields that are equal case-insensitively are passed to the - constructor or ``.update``, the behavior is undefined and some will be - lost. - - >>> headers = HTTPHeaderDict() - >>> headers.add('Set-Cookie', 'foo=bar') - >>> headers.add('set-cookie', 'baz=quxx') - >>> headers['content-length'] = '7' - >>> headers['SET-cookie'] - 'foo=bar, baz=quxx' - >>> headers['Content-Length'] - '7' - """ - - def __init__(self, headers=None, **kwargs): - super(HTTPHeaderDict, self).__init__() - self._container = OrderedDict() - if headers is not None: - if isinstance(headers, HTTPHeaderDict): - self._copy_from(headers) - else: - self.extend(headers) - if kwargs: - self.extend(kwargs) - - def __setitem__(self, key, val): - self._container[key.lower()] = [key, val] - return self._container[key.lower()] - - def __getitem__(self, key): - val = self._container[key.lower()] - return ", ".join(val[1:]) - - def __delitem__(self, key): - del self._container[key.lower()] - - def __contains__(self, key): - return key.lower() in self._container - - def __eq__(self, other): - if not isinstance(other, Mapping) and not hasattr(other, "keys"): - return False - if not isinstance(other, type(self)): - other = type(self)(other) - return dict((k.lower(), v) for k, v in self.itermerged()) == dict( - (k.lower(), v) for k, v in other.itermerged() - ) - - def __ne__(self, other): - return not self.__eq__(other) - - if six.PY2: # Python 2 - iterkeys = MutableMapping.iterkeys - itervalues = MutableMapping.itervalues - - __marker = object() - - def __len__(self): - return len(self._container) - - def __iter__(self): - # Only provide the originally cased names - for vals in self._container.values(): - yield vals[0] - - def pop(self, key, default=__marker): - """D.pop(k[,d]) -> v, remove specified key and return the corresponding value. - If key is not found, d is returned if given, otherwise KeyError is raised. - """ - # Using the MutableMapping function directly fails due to the private marker. - # Using ordinary dict.pop would expose the internal structures. - # So let's reinvent the wheel. - try: - value = self[key] - except KeyError: - if default is self.__marker: - raise - return default - else: - del self[key] - return value - - def discard(self, key): - try: - del self[key] - except KeyError: - pass - - def add(self, key, val): - """Adds a (name, value) pair, doesn't overwrite the value if it already - exists. - - >>> headers = HTTPHeaderDict(foo='bar') - >>> headers.add('Foo', 'baz') - >>> headers['foo'] - 'bar, baz' - """ - key_lower = key.lower() - new_vals = [key, val] - # Keep the common case aka no item present as fast as possible - vals = self._container.setdefault(key_lower, new_vals) - if new_vals is not vals: - vals.append(val) - - def extend(self, *args, **kwargs): - """Generic import function for any type of header-like object. - Adapted version of MutableMapping.update in order to insert items - with self.add instead of self.__setitem__ - """ - if len(args) > 1: - raise TypeError( - "extend() takes at most 1 positional " - "arguments ({0} given)".format(len(args)) - ) - other = args[0] if len(args) >= 1 else () - - if isinstance(other, HTTPHeaderDict): - for key, val in other.iteritems(): - self.add(key, val) - elif isinstance(other, Mapping): - for key in other: - self.add(key, other[key]) - elif hasattr(other, "keys"): - for key in other.keys(): - self.add(key, other[key]) - else: - for key, value in other: - self.add(key, value) - - for key, value in kwargs.items(): - self.add(key, value) - - def getlist(self, key, default=__marker): - """Returns a list of all the values for the named field. Returns an - empty list if the key doesn't exist.""" - try: - vals = self._container[key.lower()] - except KeyError: - if default is self.__marker: - return [] - return default - else: - return vals[1:] - - # Backwards compatibility for httplib - getheaders = getlist - getallmatchingheaders = getlist - iget = getlist - - # Backwards compatibility for http.cookiejar - get_all = getlist - - def __repr__(self): - return "%s(%s)" % (type(self).__name__, dict(self.itermerged())) - - def _copy_from(self, other): - for key in other: - val = other.getlist(key) - if isinstance(val, list): - # Don't need to convert tuples - val = list(val) - self._container[key.lower()] = [key] + val - - def copy(self): - clone = type(self)() - clone._copy_from(self) - return clone - - def iteritems(self): - """Iterate over all header lines, including duplicate ones.""" - for key in self: - vals = self._container[key.lower()] - for val in vals[1:]: - yield vals[0], val - - def itermerged(self): - """Iterate over all headers, merging duplicate ones together.""" - for key in self: - val = self._container[key.lower()] - yield val[0], ", ".join(val[1:]) - - def items(self): - return list(self.iteritems()) - - @classmethod - def from_httplib(cls, message): # Python 2 - """Read headers from a Python 2 httplib message object.""" - # python2.7 does not expose a proper API for exporting multiheaders - # efficiently. This function re-reads raw lines from the message - # object and extracts the multiheaders properly. - obs_fold_continued_leaders = (" ", "\t") - headers = [] - - for line in message.headers: - if line.startswith(obs_fold_continued_leaders): - if not headers: - # We received a header line that starts with OWS as described - # in RFC-7230 S3.2.4. This indicates a multiline header, but - # there exists no previous header to which we can attach it. - raise InvalidHeader( - "Header continuation with no previous header: %s" % line - ) - else: - key, value = headers[-1] - headers[-1] = (key, value + " " + line.strip()) - continue - - key, value = line.split(":", 1) - headers.append((key, value.strip())) - - return cls(headers) diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/_version.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/_version.py deleted file mode 100644 index e8ebee957f..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/_version.py +++ /dev/null @@ -1,2 +0,0 @@ -# This file is protected via CODEOWNERS -__version__ = "1.26.6" diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/connection.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/connection.py deleted file mode 100644 index 4c996659c8..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/connection.py +++ /dev/null @@ -1,539 +0,0 @@ -from __future__ import absolute_import - -import datetime -import logging -import os -import re -import socket -import warnings -from socket import error as SocketError -from socket import timeout as SocketTimeout - -from .packages import six -from .packages.six.moves.http_client import HTTPConnection as _HTTPConnection -from .packages.six.moves.http_client import HTTPException # noqa: F401 -from .util.proxy import create_proxy_ssl_context - -try: # Compiled with SSL? - import ssl - - BaseSSLError = ssl.SSLError -except (ImportError, AttributeError): # Platform-specific: No SSL. - ssl = None - - class BaseSSLError(BaseException): - pass - - -try: - # Python 3: not a no-op, we're adding this to the namespace so it can be imported. - ConnectionError = ConnectionError -except NameError: - # Python 2 - class ConnectionError(Exception): - pass - - -try: # Python 3: - # Not a no-op, we're adding this to the namespace so it can be imported. - BrokenPipeError = BrokenPipeError -except NameError: # Python 2: - - class BrokenPipeError(Exception): - pass - - -from ._collections import HTTPHeaderDict # noqa (historical, removed in v2) -from ._version import __version__ -from .exceptions import ( - ConnectTimeoutError, - NewConnectionError, - SubjectAltNameWarning, - SystemTimeWarning, -) -from .packages.ssl_match_hostname import CertificateError, match_hostname -from .util import SKIP_HEADER, SKIPPABLE_HEADERS, connection -from .util.ssl_ import ( - assert_fingerprint, - create_urllib3_context, - resolve_cert_reqs, - resolve_ssl_version, - ssl_wrap_socket, -) - -log = logging.getLogger(__name__) - -port_by_scheme = {"http": 80, "https": 443} - -# When it comes time to update this value as a part of regular maintenance -# (ie test_recent_date is failing) update it to ~6 months before the current date. -RECENT_DATE = datetime.date(2020, 7, 1) - -_CONTAINS_CONTROL_CHAR_RE = re.compile(r"[^-!#$%&'*+.^_`|~0-9a-zA-Z]") - - -class HTTPConnection(_HTTPConnection, object): - """ - Based on :class:`http.client.HTTPConnection` but provides an extra constructor - backwards-compatibility layer between older and newer Pythons. - - Additional keyword parameters are used to configure attributes of the connection. - Accepted parameters include: - - - ``strict``: See the documentation on :class:`urllib3.connectionpool.HTTPConnectionPool` - - ``source_address``: Set the source address for the current connection. - - ``socket_options``: Set specific options on the underlying socket. If not specified, then - defaults are loaded from ``HTTPConnection.default_socket_options`` which includes disabling - Nagle's algorithm (sets TCP_NODELAY to 1) unless the connection is behind a proxy. - - For example, if you wish to enable TCP Keep Alive in addition to the defaults, - you might pass: - - .. code-block:: python - - HTTPConnection.default_socket_options + [ - (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1), - ] - - Or you may want to disable the defaults by passing an empty list (e.g., ``[]``). - """ - - default_port = port_by_scheme["http"] - - #: Disable Nagle's algorithm by default. - #: ``[(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)]`` - default_socket_options = [(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)] - - #: Whether this connection verifies the host's certificate. - is_verified = False - - def __init__(self, *args, **kw): - if not six.PY2: - kw.pop("strict", None) - - # Pre-set source_address. - self.source_address = kw.get("source_address") - - #: The socket options provided by the user. If no options are - #: provided, we use the default options. - self.socket_options = kw.pop("socket_options", self.default_socket_options) - - # Proxy options provided by the user. - self.proxy = kw.pop("proxy", None) - self.proxy_config = kw.pop("proxy_config", None) - - _HTTPConnection.__init__(self, *args, **kw) - - @property - def host(self): - """ - Getter method to remove any trailing dots that indicate the hostname is an FQDN. - - In general, SSL certificates don't include the trailing dot indicating a - fully-qualified domain name, and thus, they don't validate properly when - checked against a domain name that includes the dot. In addition, some - servers may not expect to receive the trailing dot when provided. - - However, the hostname with trailing dot is critical to DNS resolution; doing a - lookup with the trailing dot will properly only resolve the appropriate FQDN, - whereas a lookup without a trailing dot will search the system's search domain - list. Thus, it's important to keep the original host around for use only in - those cases where it's appropriate (i.e., when doing DNS lookup to establish the - actual TCP connection across which we're going to send HTTP requests). - """ - return self._dns_host.rstrip(".") - - @host.setter - def host(self, value): - """ - Setter for the `host` property. - - We assume that only urllib3 uses the _dns_host attribute; httplib itself - only uses `host`, and it seems reasonable that other libraries follow suit. - """ - self._dns_host = value - - def _new_conn(self): - """Establish a socket connection and set nodelay settings on it. - - :return: New socket connection. - """ - extra_kw = {} - if self.source_address: - extra_kw["source_address"] = self.source_address - - if self.socket_options: - extra_kw["socket_options"] = self.socket_options - - try: - conn = connection.create_connection( - (self._dns_host, self.port), self.timeout, **extra_kw - ) - - except SocketTimeout: - raise ConnectTimeoutError( - self, - "Connection to %s timed out. (connect timeout=%s)" - % (self.host, self.timeout), - ) - - except SocketError as e: - raise NewConnectionError( - self, "Failed to establish a new connection: %s" % e - ) - - return conn - - def _is_using_tunnel(self): - # Google App Engine's httplib does not define _tunnel_host - return getattr(self, "_tunnel_host", None) - - def _prepare_conn(self, conn): - self.sock = conn - if self._is_using_tunnel(): - # TODO: Fix tunnel so it doesn't depend on self.sock state. - self._tunnel() - # Mark this connection as not reusable - self.auto_open = 0 - - def connect(self): - conn = self._new_conn() - self._prepare_conn(conn) - - def putrequest(self, method, url, *args, **kwargs): - """ """ - # Empty docstring because the indentation of CPython's implementation - # is broken but we don't want this method in our documentation. - match = _CONTAINS_CONTROL_CHAR_RE.search(method) - if match: - raise ValueError( - "Method cannot contain non-token characters %r (found at least %r)" - % (method, match.group()) - ) - - return _HTTPConnection.putrequest(self, method, url, *args, **kwargs) - - def putheader(self, header, *values): - """ """ - if not any(isinstance(v, str) and v == SKIP_HEADER for v in values): - _HTTPConnection.putheader(self, header, *values) - elif six.ensure_str(header.lower()) not in SKIPPABLE_HEADERS: - raise ValueError( - "urllib3.util.SKIP_HEADER only supports '%s'" - % ("', '".join(map(str.title, sorted(SKIPPABLE_HEADERS))),) - ) - - def request(self, method, url, body=None, headers=None): - if headers is None: - headers = {} - else: - # Avoid modifying the headers passed into .request() - headers = headers.copy() - if "user-agent" not in (six.ensure_str(k.lower()) for k in headers): - headers["User-Agent"] = _get_default_user_agent() - super(HTTPConnection, self).request(method, url, body=body, headers=headers) - - def request_chunked(self, method, url, body=None, headers=None): - """ - Alternative to the common request method, which sends the - body with chunked encoding and not as one block - """ - headers = headers or {} - header_keys = set([six.ensure_str(k.lower()) for k in headers]) - skip_accept_encoding = "accept-encoding" in header_keys - skip_host = "host" in header_keys - self.putrequest( - method, url, skip_accept_encoding=skip_accept_encoding, skip_host=skip_host - ) - if "user-agent" not in header_keys: - self.putheader("User-Agent", _get_default_user_agent()) - for header, value in headers.items(): - self.putheader(header, value) - if "transfer-encoding" not in header_keys: - self.putheader("Transfer-Encoding", "chunked") - self.endheaders() - - if body is not None: - stringish_types = six.string_types + (bytes,) - if isinstance(body, stringish_types): - body = (body,) - for chunk in body: - if not chunk: - continue - if not isinstance(chunk, bytes): - chunk = chunk.encode("utf8") - len_str = hex(len(chunk))[2:] - to_send = bytearray(len_str.encode()) - to_send += b"\r\n" - to_send += chunk - to_send += b"\r\n" - self.send(to_send) - - # After the if clause, to always have a closed body - self.send(b"0\r\n\r\n") - - -class HTTPSConnection(HTTPConnection): - """ - Many of the parameters to this constructor are passed to the underlying SSL - socket by means of :py:func:`urllib3.util.ssl_wrap_socket`. - """ - - default_port = port_by_scheme["https"] - - cert_reqs = None - ca_certs = None - ca_cert_dir = None - ca_cert_data = None - ssl_version = None - assert_fingerprint = None - tls_in_tls_required = False - - def __init__( - self, - host, - port=None, - key_file=None, - cert_file=None, - key_password=None, - strict=None, - timeout=socket._GLOBAL_DEFAULT_TIMEOUT, - ssl_context=None, - server_hostname=None, - **kw - ): - - HTTPConnection.__init__(self, host, port, strict=strict, timeout=timeout, **kw) - - self.key_file = key_file - self.cert_file = cert_file - self.key_password = key_password - self.ssl_context = ssl_context - self.server_hostname = server_hostname - - # Required property for Google AppEngine 1.9.0 which otherwise causes - # HTTPS requests to go out as HTTP. (See Issue #356) - self._protocol = "https" - - def set_cert( - self, - key_file=None, - cert_file=None, - cert_reqs=None, - key_password=None, - ca_certs=None, - assert_hostname=None, - assert_fingerprint=None, - ca_cert_dir=None, - ca_cert_data=None, - ): - """ - This method should only be called once, before the connection is used. - """ - # If cert_reqs is not provided we'll assume CERT_REQUIRED unless we also - # have an SSLContext object in which case we'll use its verify_mode. - if cert_reqs is None: - if self.ssl_context is not None: - cert_reqs = self.ssl_context.verify_mode - else: - cert_reqs = resolve_cert_reqs(None) - - self.key_file = key_file - self.cert_file = cert_file - self.cert_reqs = cert_reqs - self.key_password = key_password - self.assert_hostname = assert_hostname - self.assert_fingerprint = assert_fingerprint - self.ca_certs = ca_certs and os.path.expanduser(ca_certs) - self.ca_cert_dir = ca_cert_dir and os.path.expanduser(ca_cert_dir) - self.ca_cert_data = ca_cert_data - - def connect(self): - # Add certificate verification - conn = self._new_conn() - hostname = self.host - tls_in_tls = False - - if self._is_using_tunnel(): - if self.tls_in_tls_required: - conn = self._connect_tls_proxy(hostname, conn) - tls_in_tls = True - - self.sock = conn - - # Calls self._set_hostport(), so self.host is - # self._tunnel_host below. - self._tunnel() - # Mark this connection as not reusable - self.auto_open = 0 - - # Override the host with the one we're requesting data from. - hostname = self._tunnel_host - - server_hostname = hostname - if self.server_hostname is not None: - server_hostname = self.server_hostname - - is_time_off = datetime.date.today() < RECENT_DATE - if is_time_off: - warnings.warn( - ( - "System time is way off (before {0}). This will probably " - "lead to SSL verification errors" - ).format(RECENT_DATE), - SystemTimeWarning, - ) - - # Wrap socket using verification with the root certs in - # trusted_root_certs - default_ssl_context = False - if self.ssl_context is None: - default_ssl_context = True - self.ssl_context = create_urllib3_context( - ssl_version=resolve_ssl_version(self.ssl_version), - cert_reqs=resolve_cert_reqs(self.cert_reqs), - ) - - context = self.ssl_context - context.verify_mode = resolve_cert_reqs(self.cert_reqs) - - # Try to load OS default certs if none are given. - # Works well on Windows (requires Python3.4+) - if ( - not self.ca_certs - and not self.ca_cert_dir - and not self.ca_cert_data - and default_ssl_context - and hasattr(context, "load_default_certs") - ): - context.load_default_certs() - - self.sock = ssl_wrap_socket( - sock=conn, - keyfile=self.key_file, - certfile=self.cert_file, - key_password=self.key_password, - ca_certs=self.ca_certs, - ca_cert_dir=self.ca_cert_dir, - ca_cert_data=self.ca_cert_data, - server_hostname=server_hostname, - ssl_context=context, - tls_in_tls=tls_in_tls, - ) - - # If we're using all defaults and the connection - # is TLSv1 or TLSv1.1 we throw a DeprecationWarning - # for the host. - if ( - default_ssl_context - and self.ssl_version is None - and hasattr(self.sock, "version") - and self.sock.version() in {"TLSv1", "TLSv1.1"} - ): - warnings.warn( - "Negotiating TLSv1/TLSv1.1 by default is deprecated " - "and will be disabled in urllib3 v2.0.0. Connecting to " - "'%s' with '%s' can be enabled by explicitly opting-in " - "with 'ssl_version'" % (self.host, self.sock.version()), - DeprecationWarning, - ) - - if self.assert_fingerprint: - assert_fingerprint( - self.sock.getpeercert(binary_form=True), self.assert_fingerprint - ) - elif ( - context.verify_mode != ssl.CERT_NONE - and not getattr(context, "check_hostname", False) - and self.assert_hostname is not False - ): - # While urllib3 attempts to always turn off hostname matching from - # the TLS library, this cannot always be done. So we check whether - # the TLS Library still thinks it's matching hostnames. - cert = self.sock.getpeercert() - if not cert.get("subjectAltName", ()): - warnings.warn( - ( - "Certificate for {0} has no `subjectAltName`, falling back to check for a " - "`commonName` for now. This feature is being removed by major browsers and " - "deprecated by RFC 2818. (See https://github.com/urllib3/urllib3/issues/497 " - "for details.)".format(hostname) - ), - SubjectAltNameWarning, - ) - _match_hostname(cert, self.assert_hostname or server_hostname) - - self.is_verified = ( - context.verify_mode == ssl.CERT_REQUIRED - or self.assert_fingerprint is not None - ) - - def _connect_tls_proxy(self, hostname, conn): - """ - Establish a TLS connection to the proxy using the provided SSL context. - """ - proxy_config = self.proxy_config - ssl_context = proxy_config.ssl_context - if ssl_context: - # If the user provided a proxy context, we assume CA and client - # certificates have already been set - return ssl_wrap_socket( - sock=conn, - server_hostname=hostname, - ssl_context=ssl_context, - ) - - ssl_context = create_proxy_ssl_context( - self.ssl_version, - self.cert_reqs, - self.ca_certs, - self.ca_cert_dir, - self.ca_cert_data, - ) - # By default urllib3's SSLContext disables `check_hostname` and uses - # a custom check. For proxies we're good with relying on the default - # verification. - ssl_context.check_hostname = True - - # If no cert was provided, use only the default options for server - # certificate validation - return ssl_wrap_socket( - sock=conn, - ca_certs=self.ca_certs, - ca_cert_dir=self.ca_cert_dir, - ca_cert_data=self.ca_cert_data, - server_hostname=hostname, - ssl_context=ssl_context, - ) - - -def _match_hostname(cert, asserted_hostname): - try: - match_hostname(cert, asserted_hostname) - except CertificateError as e: - log.warning( - "Certificate did not match expected hostname: %s. Certificate: %s", - asserted_hostname, - cert, - ) - # Add cert to exception and reraise so client code can inspect - # the cert when catching the exception, if they want to - e._peer_cert = cert - raise - - -def _get_default_user_agent(): - return "python-urllib3/%s" % __version__ - - -class DummyConnection(object): - """Used to detect a failed ConnectionCls import.""" - - pass - - -if not ssl: - HTTPSConnection = DummyConnection # noqa: F811 - - -VerifiedHTTPSConnection = HTTPSConnection diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/connectionpool.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/connectionpool.py deleted file mode 100644 index 459bbe095b..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/connectionpool.py +++ /dev/null @@ -1,1067 +0,0 @@ -from __future__ import absolute_import - -import errno -import logging -import socket -import sys -import warnings -from socket import error as SocketError -from socket import timeout as SocketTimeout - -from .connection import ( - BaseSSLError, - BrokenPipeError, - DummyConnection, - HTTPConnection, - HTTPException, - HTTPSConnection, - VerifiedHTTPSConnection, - port_by_scheme, -) -from .exceptions import ( - ClosedPoolError, - EmptyPoolError, - HeaderParsingError, - HostChangedError, - InsecureRequestWarning, - LocationValueError, - MaxRetryError, - NewConnectionError, - ProtocolError, - ProxyError, - ReadTimeoutError, - SSLError, - TimeoutError, -) -from .packages import six -from .packages.six.moves import queue -from .packages.ssl_match_hostname import CertificateError -from .request import RequestMethods -from .response import HTTPResponse -from .util.connection import is_connection_dropped -from .util.proxy import connection_requires_http_tunnel -from .util.queue import LifoQueue -from .util.request import set_file_position -from .util.response import assert_header_parsing -from .util.retry import Retry -from .util.timeout import Timeout -from .util.url import Url, _encode_target -from .util.url import _normalize_host as normalize_host -from .util.url import get_host, parse_url - -xrange = six.moves.xrange - -log = logging.getLogger(__name__) - -_Default = object() - - -# Pool objects -class ConnectionPool(object): - """ - Base class for all connection pools, such as - :class:`.HTTPConnectionPool` and :class:`.HTTPSConnectionPool`. - - .. note:: - ConnectionPool.urlopen() does not normalize or percent-encode target URIs - which is useful if your target server doesn't support percent-encoded - target URIs. - """ - - scheme = None - QueueCls = LifoQueue - - def __init__(self, host, port=None): - if not host: - raise LocationValueError("No host specified.") - - self.host = _normalize_host(host, scheme=self.scheme) - self._proxy_host = host.lower() - self.port = port - - def __str__(self): - return "%s(host=%r, port=%r)" % (type(self).__name__, self.host, self.port) - - def __enter__(self): - return self - - def __exit__(self, exc_type, exc_val, exc_tb): - self.close() - # Return False to re-raise any potential exceptions - return False - - def close(self): - """ - Close all pooled connections and disable the pool. - """ - pass - - -# This is taken from http://hg.python.org/cpython/file/7aaba721ebc0/Lib/socket.py#l252 -_blocking_errnos = {errno.EAGAIN, errno.EWOULDBLOCK} - - -class HTTPConnectionPool(ConnectionPool, RequestMethods): - """ - Thread-safe connection pool for one host. - - :param host: - Host used for this HTTP Connection (e.g. "localhost"), passed into - :class:`http.client.HTTPConnection`. - - :param port: - Port used for this HTTP Connection (None is equivalent to 80), passed - into :class:`http.client.HTTPConnection`. - - :param strict: - Causes BadStatusLine to be raised if the status line can't be parsed - as a valid HTTP/1.0 or 1.1 status line, passed into - :class:`http.client.HTTPConnection`. - - .. note:: - Only works in Python 2. This parameter is ignored in Python 3. - - :param timeout: - Socket timeout in seconds for each individual connection. This can - be a float or integer, which sets the timeout for the HTTP request, - or an instance of :class:`urllib3.util.Timeout` which gives you more - fine-grained control over request timeouts. After the constructor has - been parsed, this is always a `urllib3.util.Timeout` object. - - :param maxsize: - Number of connections to save that can be reused. More than 1 is useful - in multithreaded situations. If ``block`` is set to False, more - connections will be created but they will not be saved once they've - been used. - - :param block: - If set to True, no more than ``maxsize`` connections will be used at - a time. When no free connections are available, the call will block - until a connection has been released. This is a useful side effect for - particular multithreaded situations where one does not want to use more - than maxsize connections per host to prevent flooding. - - :param headers: - Headers to include with all requests, unless other headers are given - explicitly. - - :param retries: - Retry configuration to use by default with requests in this pool. - - :param _proxy: - Parsed proxy URL, should not be used directly, instead, see - :class:`urllib3.ProxyManager` - - :param _proxy_headers: - A dictionary with proxy headers, should not be used directly, - instead, see :class:`urllib3.ProxyManager` - - :param \\**conn_kw: - Additional parameters are used to create fresh :class:`urllib3.connection.HTTPConnection`, - :class:`urllib3.connection.HTTPSConnection` instances. - """ - - scheme = "http" - ConnectionCls = HTTPConnection - ResponseCls = HTTPResponse - - def __init__( - self, - host, - port=None, - strict=False, - timeout=Timeout.DEFAULT_TIMEOUT, - maxsize=1, - block=False, - headers=None, - retries=None, - _proxy=None, - _proxy_headers=None, - _proxy_config=None, - **conn_kw - ): - ConnectionPool.__init__(self, host, port) - RequestMethods.__init__(self, headers) - - self.strict = strict - - if not isinstance(timeout, Timeout): - timeout = Timeout.from_float(timeout) - - if retries is None: - retries = Retry.DEFAULT - - self.timeout = timeout - self.retries = retries - - self.pool = self.QueueCls(maxsize) - self.block = block - - self.proxy = _proxy - self.proxy_headers = _proxy_headers or {} - self.proxy_config = _proxy_config - - # Fill the queue up so that doing get() on it will block properly - for _ in xrange(maxsize): - self.pool.put(None) - - # These are mostly for testing and debugging purposes. - self.num_connections = 0 - self.num_requests = 0 - self.conn_kw = conn_kw - - if self.proxy: - # Enable Nagle's algorithm for proxies, to avoid packet fragmentation. - # We cannot know if the user has added default socket options, so we cannot replace the - # list. - self.conn_kw.setdefault("socket_options", []) - - self.conn_kw["proxy"] = self.proxy - self.conn_kw["proxy_config"] = self.proxy_config - - def _new_conn(self): - """ - Return a fresh :class:`HTTPConnection`. - """ - self.num_connections += 1 - log.debug( - "Starting new HTTP connection (%d): %s:%s", - self.num_connections, - self.host, - self.port or "80", - ) - - conn = self.ConnectionCls( - host=self.host, - port=self.port, - timeout=self.timeout.connect_timeout, - strict=self.strict, - **self.conn_kw - ) - return conn - - def _get_conn(self, timeout=None): - """ - Get a connection. Will return a pooled connection if one is available. - - If no connections are available and :prop:`.block` is ``False``, then a - fresh connection is returned. - - :param timeout: - Seconds to wait before giving up and raising - :class:`urllib3.exceptions.EmptyPoolError` if the pool is empty and - :prop:`.block` is ``True``. - """ - conn = None - try: - conn = self.pool.get(block=self.block, timeout=timeout) - - except AttributeError: # self.pool is None - raise ClosedPoolError(self, "Pool is closed.") - - except queue.Empty: - if self.block: - raise EmptyPoolError( - self, - "Pool reached maximum size and no more connections are allowed.", - ) - pass # Oh well, we'll create a new connection then - - # If this is a persistent connection, check if it got disconnected - if conn and is_connection_dropped(conn): - log.debug("Resetting dropped connection: %s", self.host) - conn.close() - if getattr(conn, "auto_open", 1) == 0: - # This is a proxied connection that has been mutated by - # http.client._tunnel() and cannot be reused (since it would - # attempt to bypass the proxy) - conn = None - - return conn or self._new_conn() - - def _put_conn(self, conn): - """ - Put a connection back into the pool. - - :param conn: - Connection object for the current host and port as returned by - :meth:`._new_conn` or :meth:`._get_conn`. - - If the pool is already full, the connection is closed and discarded - because we exceeded maxsize. If connections are discarded frequently, - then maxsize should be increased. - - If the pool is closed, then the connection will be closed and discarded. - """ - try: - self.pool.put(conn, block=False) - return # Everything is dandy, done. - except AttributeError: - # self.pool is None. - pass - except queue.Full: - # This should never happen if self.block == True - log.warning("Connection pool is full, discarding connection: %s", self.host) - - # Connection never got put back into the pool, close it. - if conn: - conn.close() - - def _validate_conn(self, conn): - """ - Called right before a request is made, after the socket is created. - """ - pass - - def _prepare_proxy(self, conn): - # Nothing to do for HTTP connections. - pass - - def _get_timeout(self, timeout): - """Helper that always returns a :class:`urllib3.util.Timeout`""" - if timeout is _Default: - return self.timeout.clone() - - if isinstance(timeout, Timeout): - return timeout.clone() - else: - # User passed us an int/float. This is for backwards compatibility, - # can be removed later - return Timeout.from_float(timeout) - - def _raise_timeout(self, err, url, timeout_value): - """Is the error actually a timeout? Will raise a ReadTimeout or pass""" - - if isinstance(err, SocketTimeout): - raise ReadTimeoutError( - self, url, "Read timed out. (read timeout=%s)" % timeout_value - ) - - # See the above comment about EAGAIN in Python 3. In Python 2 we have - # to specifically catch it and throw the timeout error - if hasattr(err, "errno") and err.errno in _blocking_errnos: - raise ReadTimeoutError( - self, url, "Read timed out. (read timeout=%s)" % timeout_value - ) - - # Catch possible read timeouts thrown as SSL errors. If not the - # case, rethrow the original. We need to do this because of: - # http://bugs.python.org/issue10272 - if "timed out" in str(err) or "did not complete (read)" in str( - err - ): # Python < 2.7.4 - raise ReadTimeoutError( - self, url, "Read timed out. (read timeout=%s)" % timeout_value - ) - - def _make_request( - self, conn, method, url, timeout=_Default, chunked=False, **httplib_request_kw - ): - """ - Perform a request on a given urllib connection object taken from our - pool. - - :param conn: - a connection from one of our connection pools - - :param timeout: - Socket timeout in seconds for the request. This can be a - float or integer, which will set the same timeout value for - the socket connect and the socket read, or an instance of - :class:`urllib3.util.Timeout`, which gives you more fine-grained - control over your timeouts. - """ - self.num_requests += 1 - - timeout_obj = self._get_timeout(timeout) - timeout_obj.start_connect() - conn.timeout = timeout_obj.connect_timeout - - # Trigger any extra validation we need to do. - try: - self._validate_conn(conn) - except (SocketTimeout, BaseSSLError) as e: - # Py2 raises this as a BaseSSLError, Py3 raises it as socket timeout. - self._raise_timeout(err=e, url=url, timeout_value=conn.timeout) - raise - - # conn.request() calls http.client.*.request, not the method in - # urllib3.request. It also calls makefile (recv) on the socket. - try: - if chunked: - conn.request_chunked(method, url, **httplib_request_kw) - else: - conn.request(method, url, **httplib_request_kw) - - # We are swallowing BrokenPipeError (errno.EPIPE) since the server is - # legitimately able to close the connection after sending a valid response. - # With this behaviour, the received response is still readable. - except BrokenPipeError: - # Python 3 - pass - except IOError as e: - # Python 2 and macOS/Linux - # EPIPE and ESHUTDOWN are BrokenPipeError on Python 2, and EPROTOTYPE is needed on macOS - # https://erickt.github.io/blog/2014/11/19/adventures-in-debugging-a-potential-osx-kernel-bug/ - if e.errno not in { - errno.EPIPE, - errno.ESHUTDOWN, - errno.EPROTOTYPE, - }: - raise - - # Reset the timeout for the recv() on the socket - read_timeout = timeout_obj.read_timeout - - # App Engine doesn't have a sock attr - if getattr(conn, "sock", None): - # In Python 3 socket.py will catch EAGAIN and return None when you - # try and read into the file pointer created by http.client, which - # instead raises a BadStatusLine exception. Instead of catching - # the exception and assuming all BadStatusLine exceptions are read - # timeouts, check for a zero timeout before making the request. - if read_timeout == 0: - raise ReadTimeoutError( - self, url, "Read timed out. (read timeout=%s)" % read_timeout - ) - if read_timeout is Timeout.DEFAULT_TIMEOUT: - conn.sock.settimeout(socket.getdefaulttimeout()) - else: # None or a value - conn.sock.settimeout(read_timeout) - - # Receive the response from the server - try: - try: - # Python 2.7, use buffering of HTTP responses - httplib_response = conn.getresponse(buffering=True) - except TypeError: - # Python 3 - try: - httplib_response = conn.getresponse() - except BaseException as e: - # Remove the TypeError from the exception chain in - # Python 3 (including for exceptions like SystemExit). - # Otherwise it looks like a bug in the code. - six.raise_from(e, None) - except (SocketTimeout, BaseSSLError, SocketError) as e: - self._raise_timeout(err=e, url=url, timeout_value=read_timeout) - raise - - # AppEngine doesn't have a version attr. - http_version = getattr(conn, "_http_vsn_str", "HTTP/?") - log.debug( - '%s://%s:%s "%s %s %s" %s %s', - self.scheme, - self.host, - self.port, - method, - url, - http_version, - httplib_response.status, - httplib_response.length, - ) - - try: - assert_header_parsing(httplib_response.msg) - except (HeaderParsingError, TypeError) as hpe: # Platform-specific: Python 3 - log.warning( - "Failed to parse headers (url=%s): %s", - self._absolute_url(url), - hpe, - exc_info=True, - ) - - return httplib_response - - def _absolute_url(self, path): - return Url(scheme=self.scheme, host=self.host, port=self.port, path=path).url - - def close(self): - """ - Close all pooled connections and disable the pool. - """ - if self.pool is None: - return - # Disable access to the pool - old_pool, self.pool = self.pool, None - - try: - while True: - conn = old_pool.get(block=False) - if conn: - conn.close() - - except queue.Empty: - pass # Done. - - def is_same_host(self, url): - """ - Check if the given ``url`` is a member of the same host as this - connection pool. - """ - if url.startswith("/"): - return True - - # TODO: Add optional support for socket.gethostbyname checking. - scheme, host, port = get_host(url) - if host is not None: - host = _normalize_host(host, scheme=scheme) - - # Use explicit default port for comparison when none is given - if self.port and not port: - port = port_by_scheme.get(scheme) - elif not self.port and port == port_by_scheme.get(scheme): - port = None - - return (scheme, host, port) == (self.scheme, self.host, self.port) - - def urlopen( - self, - method, - url, - body=None, - headers=None, - retries=None, - redirect=True, - assert_same_host=True, - timeout=_Default, - pool_timeout=None, - release_conn=None, - chunked=False, - body_pos=None, - **response_kw - ): - """ - Get a connection from the pool and perform an HTTP request. This is the - lowest level call for making a request, so you'll need to specify all - the raw details. - - .. note:: - - More commonly, it's appropriate to use a convenience method provided - by :class:`.RequestMethods`, such as :meth:`request`. - - .. note:: - - `release_conn` will only behave as expected if - `preload_content=False` because we want to make - `preload_content=False` the default behaviour someday soon without - breaking backwards compatibility. - - :param method: - HTTP request method (such as GET, POST, PUT, etc.) - - :param url: - The URL to perform the request on. - - :param body: - Data to send in the request body, either :class:`str`, :class:`bytes`, - an iterable of :class:`str`/:class:`bytes`, or a file-like object. - - :param headers: - Dictionary of custom headers to send, such as User-Agent, - If-None-Match, etc. If None, pool headers are used. If provided, - these headers completely replace any pool-specific headers. - - :param retries: - Configure the number of retries to allow before raising a - :class:`~urllib3.exceptions.MaxRetryError` exception. - - Pass ``None`` to retry until you receive a response. Pass a - :class:`~urllib3.util.retry.Retry` object for fine-grained control - over different types of retries. - Pass an integer number to retry connection errors that many times, - but no other types of errors. Pass zero to never retry. - - If ``False``, then retries are disabled and any exception is raised - immediately. Also, instead of raising a MaxRetryError on redirects, - the redirect response will be returned. - - :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. - - :param redirect: - If True, automatically handle redirects (status codes 301, 302, - 303, 307, 308). Each redirect counts as a retry. Disabling retries - will disable redirect, too. - - :param assert_same_host: - If ``True``, will make sure that the host of the pool requests is - consistent else will raise HostChangedError. When ``False``, you can - use the pool on an HTTP proxy and request foreign hosts. - - :param timeout: - If specified, overrides the default timeout for this one - request. It may be a float (in seconds) or an instance of - :class:`urllib3.util.Timeout`. - - :param pool_timeout: - If set and the pool is set to block=True, then this method will - block for ``pool_timeout`` seconds and raise EmptyPoolError if no - connection is available within the time period. - - :param release_conn: - If False, then the urlopen call will not release the connection - back into the pool once a response is received (but will release if - you read the entire contents of the response such as when - `preload_content=True`). This is useful if you're not preloading - the response's content immediately. You will need to call - ``r.release_conn()`` on the response ``r`` to return the connection - back into the pool. If None, it takes the value of - ``response_kw.get('preload_content', True)``. - - :param chunked: - If True, urllib3 will send the body using chunked transfer - encoding. Otherwise, urllib3 will send the body using the standard - content-length form. Defaults to False. - - :param int body_pos: - Position to seek to in file-like body in the event of a retry or - redirect. Typically this won't need to be set because urllib3 will - auto-populate the value when needed. - - :param \\**response_kw: - Additional parameters are passed to - :meth:`urllib3.response.HTTPResponse.from_httplib` - """ - - parsed_url = parse_url(url) - destination_scheme = parsed_url.scheme - - if headers is None: - headers = self.headers - - if not isinstance(retries, Retry): - retries = Retry.from_int(retries, redirect=redirect, default=self.retries) - - if release_conn is None: - release_conn = response_kw.get("preload_content", True) - - # Check host - if assert_same_host and not self.is_same_host(url): - raise HostChangedError(self, url, retries) - - # Ensure that the URL we're connecting to is properly encoded - if url.startswith("/"): - url = six.ensure_str(_encode_target(url)) - else: - url = six.ensure_str(parsed_url.url) - - conn = None - - # Track whether `conn` needs to be released before - # returning/raising/recursing. Update this variable if necessary, and - # leave `release_conn` constant throughout the function. That way, if - # the function recurses, the original value of `release_conn` will be - # passed down into the recursive call, and its value will be respected. - # - # See issue #651 [1] for details. - # - # [1] - release_this_conn = release_conn - - http_tunnel_required = connection_requires_http_tunnel( - self.proxy, self.proxy_config, destination_scheme - ) - - # Merge the proxy headers. Only done when not using HTTP CONNECT. We - # have to copy the headers dict so we can safely change it without those - # changes being reflected in anyone else's copy. - if not http_tunnel_required: - headers = headers.copy() - headers.update(self.proxy_headers) - - # Must keep the exception bound to a separate variable or else Python 3 - # complains about UnboundLocalError. - err = None - - # Keep track of whether we cleanly exited the except block. This - # ensures we do proper cleanup in finally. - clean_exit = False - - # Rewind body position, if needed. Record current position - # for future rewinds in the event of a redirect/retry. - body_pos = set_file_position(body, body_pos) - - try: - # Request a connection from the queue. - timeout_obj = self._get_timeout(timeout) - conn = self._get_conn(timeout=pool_timeout) - - conn.timeout = timeout_obj.connect_timeout - - is_new_proxy_conn = self.proxy is not None and not getattr( - conn, "sock", None - ) - if is_new_proxy_conn and http_tunnel_required: - self._prepare_proxy(conn) - - # Make the request on the httplib connection object. - httplib_response = self._make_request( - conn, - method, - url, - timeout=timeout_obj, - body=body, - headers=headers, - chunked=chunked, - ) - - # If we're going to release the connection in ``finally:``, then - # the response doesn't need to know about the connection. Otherwise - # it will also try to release it and we'll have a double-release - # mess. - response_conn = conn if not release_conn else None - - # Pass method to Response for length checking - response_kw["request_method"] = method - - # Import httplib's response into our own wrapper object - response = self.ResponseCls.from_httplib( - httplib_response, - pool=self, - connection=response_conn, - retries=retries, - **response_kw - ) - - # Everything went great! - clean_exit = True - - except EmptyPoolError: - # Didn't get a connection from the pool, no need to clean up - clean_exit = True - release_this_conn = False - raise - - except ( - TimeoutError, - HTTPException, - SocketError, - ProtocolError, - BaseSSLError, - SSLError, - CertificateError, - ) as e: - # Discard the connection for these exceptions. It will be - # replaced during the next _get_conn() call. - clean_exit = False - if isinstance(e, (BaseSSLError, CertificateError)): - e = SSLError(e) - elif isinstance(e, (SocketError, NewConnectionError)) and self.proxy: - e = ProxyError("Cannot connect to proxy.", e) - elif isinstance(e, (SocketError, HTTPException)): - e = ProtocolError("Connection aborted.", e) - - retries = retries.increment( - method, url, error=e, _pool=self, _stacktrace=sys.exc_info()[2] - ) - retries.sleep() - - # Keep track of the error for the retry warning. - err = e - - finally: - if not clean_exit: - # We hit some kind of exception, handled or otherwise. We need - # to throw the connection away unless explicitly told not to. - # Close the connection, set the variable to None, and make sure - # we put the None back in the pool to avoid leaking it. - conn = conn and conn.close() - release_this_conn = True - - if release_this_conn: - # Put the connection back to be reused. If the connection is - # expired then it will be None, which will get replaced with a - # fresh connection during _get_conn. - self._put_conn(conn) - - if not conn: - # Try again - log.warning( - "Retrying (%r) after connection broken by '%r': %s", retries, err, url - ) - return self.urlopen( - method, - url, - body, - headers, - retries, - redirect, - assert_same_host, - timeout=timeout, - pool_timeout=pool_timeout, - release_conn=release_conn, - chunked=chunked, - body_pos=body_pos, - **response_kw - ) - - # Handle redirect? - redirect_location = redirect and response.get_redirect_location() - if redirect_location: - if response.status == 303: - method = "GET" - - try: - retries = retries.increment(method, url, response=response, _pool=self) - except MaxRetryError: - if retries.raise_on_redirect: - response.drain_conn() - raise - return response - - response.drain_conn() - retries.sleep_for_retry(response) - log.debug("Redirecting %s -> %s", url, redirect_location) - return self.urlopen( - method, - redirect_location, - body, - headers, - retries=retries, - redirect=redirect, - assert_same_host=assert_same_host, - timeout=timeout, - pool_timeout=pool_timeout, - release_conn=release_conn, - chunked=chunked, - body_pos=body_pos, - **response_kw - ) - - # Check if we should retry the HTTP response. - has_retry_after = bool(response.getheader("Retry-After")) - if retries.is_retry(method, response.status, has_retry_after): - try: - retries = retries.increment(method, url, response=response, _pool=self) - except MaxRetryError: - if retries.raise_on_status: - response.drain_conn() - raise - return response - - response.drain_conn() - retries.sleep(response) - log.debug("Retry: %s", url) - return self.urlopen( - method, - url, - body, - headers, - retries=retries, - redirect=redirect, - assert_same_host=assert_same_host, - timeout=timeout, - pool_timeout=pool_timeout, - release_conn=release_conn, - chunked=chunked, - body_pos=body_pos, - **response_kw - ) - - return response - - -class HTTPSConnectionPool(HTTPConnectionPool): - """ - Same as :class:`.HTTPConnectionPool`, but HTTPS. - - :class:`.HTTPSConnection` uses one of ``assert_fingerprint``, - ``assert_hostname`` and ``host`` in this order to verify connections. - If ``assert_hostname`` is False, no verification is done. - - The ``key_file``, ``cert_file``, ``cert_reqs``, ``ca_certs``, - ``ca_cert_dir``, ``ssl_version``, ``key_password`` are only used if :mod:`ssl` - is available and are fed into :meth:`urllib3.util.ssl_wrap_socket` to upgrade - the connection socket into an SSL socket. - """ - - scheme = "https" - ConnectionCls = HTTPSConnection - - def __init__( - self, - host, - port=None, - strict=False, - timeout=Timeout.DEFAULT_TIMEOUT, - maxsize=1, - block=False, - headers=None, - retries=None, - _proxy=None, - _proxy_headers=None, - key_file=None, - cert_file=None, - cert_reqs=None, - key_password=None, - ca_certs=None, - ssl_version=None, - assert_hostname=None, - assert_fingerprint=None, - ca_cert_dir=None, - **conn_kw - ): - - HTTPConnectionPool.__init__( - self, - host, - port, - strict, - timeout, - maxsize, - block, - headers, - retries, - _proxy, - _proxy_headers, - **conn_kw - ) - - self.key_file = key_file - self.cert_file = cert_file - self.cert_reqs = cert_reqs - self.key_password = key_password - self.ca_certs = ca_certs - self.ca_cert_dir = ca_cert_dir - self.ssl_version = ssl_version - self.assert_hostname = assert_hostname - self.assert_fingerprint = assert_fingerprint - - def _prepare_conn(self, conn): - """ - Prepare the ``connection`` for :meth:`urllib3.util.ssl_wrap_socket` - and establish the tunnel if proxy is used. - """ - - if isinstance(conn, VerifiedHTTPSConnection): - conn.set_cert( - key_file=self.key_file, - key_password=self.key_password, - cert_file=self.cert_file, - cert_reqs=self.cert_reqs, - ca_certs=self.ca_certs, - ca_cert_dir=self.ca_cert_dir, - assert_hostname=self.assert_hostname, - assert_fingerprint=self.assert_fingerprint, - ) - conn.ssl_version = self.ssl_version - return conn - - def _prepare_proxy(self, conn): - """ - Establishes a tunnel connection through HTTP CONNECT. - - Tunnel connection is established early because otherwise httplib would - improperly set Host: header to proxy's IP:port. - """ - - conn.set_tunnel(self._proxy_host, self.port, self.proxy_headers) - - if self.proxy.scheme == "https": - conn.tls_in_tls_required = True - - conn.connect() - - def _new_conn(self): - """ - Return a fresh :class:`http.client.HTTPSConnection`. - """ - self.num_connections += 1 - log.debug( - "Starting new HTTPS connection (%d): %s:%s", - self.num_connections, - self.host, - self.port or "443", - ) - - if not self.ConnectionCls or self.ConnectionCls is DummyConnection: - raise SSLError( - "Can't connect to HTTPS URL because the SSL module is not available." - ) - - actual_host = self.host - actual_port = self.port - if self.proxy is not None: - actual_host = self.proxy.host - actual_port = self.proxy.port - - conn = self.ConnectionCls( - host=actual_host, - port=actual_port, - timeout=self.timeout.connect_timeout, - strict=self.strict, - cert_file=self.cert_file, - key_file=self.key_file, - key_password=self.key_password, - **self.conn_kw - ) - - return self._prepare_conn(conn) - - def _validate_conn(self, conn): - """ - Called right before a request is made, after the socket is created. - """ - super(HTTPSConnectionPool, self)._validate_conn(conn) - - # Force connect early to allow us to validate the connection. - if not getattr(conn, "sock", None): # AppEngine might not have `.sock` - conn.connect() - - if not conn.is_verified: - warnings.warn( - ( - "Unverified HTTPS request is being made to host '%s'. " - "Adding certificate verification is strongly advised. See: " - "https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html" - "#ssl-warnings" % conn.host - ), - InsecureRequestWarning, - ) - - -def connection_from_url(url, **kw): - """ - Given a url, return an :class:`.ConnectionPool` instance of its host. - - This is a shortcut for not having to parse out the scheme, host, and port - of the url before creating an :class:`.ConnectionPool` instance. - - :param url: - Absolute URL string that must include the scheme. Port is optional. - - :param \\**kw: - Passes additional parameters to the constructor of the appropriate - :class:`.ConnectionPool`. Useful for specifying things like - timeout, maxsize, headers, etc. - - Example:: - - >>> conn = connection_from_url('http://google.com/') - >>> r = conn.request('GET', '/') - """ - scheme, host, port = get_host(url) - port = port or port_by_scheme.get(scheme, 80) - if scheme == "https": - return HTTPSConnectionPool(host, port=port, **kw) - else: - return HTTPConnectionPool(host, port=port, **kw) - - -def _normalize_host(host, scheme): - """ - Normalize hosts for comparisons and use with sockets. - """ - - host = normalize_host(host, scheme) - - # httplib doesn't like it when we include brackets in IPv6 addresses - # Specifically, if we include brackets but also pass the port then - # httplib crazily doubles up the square brackets on the Host header. - # Instead, we need to make sure we never pass ``None`` as the port. - # However, for backward compatibility reasons we can't actually - # *assert* that. See http://bugs.python.org/issue28539 - if host.startswith("[") and host.endswith("]"): - host = host[1:-1] - return host diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/contrib/__init__.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/contrib/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/contrib/_appengine_environ.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/contrib/_appengine_environ.py deleted file mode 100644 index 8765b907d7..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/contrib/_appengine_environ.py +++ /dev/null @@ -1,36 +0,0 @@ -""" -This module provides means to detect the App Engine environment. -""" - -import os - - -def is_appengine(): - return is_local_appengine() or is_prod_appengine() - - -def is_appengine_sandbox(): - """Reports if the app is running in the first generation sandbox. - - The second generation runtimes are technically still in a sandbox, but it - is much less restrictive, so generally you shouldn't need to check for it. - see https://cloud.google.com/appengine/docs/standard/runtimes - """ - return is_appengine() and os.environ["APPENGINE_RUNTIME"] == "python27" - - -def is_local_appengine(): - return "APPENGINE_RUNTIME" in os.environ and os.environ.get( - "SERVER_SOFTWARE", "" - ).startswith("Development/") - - -def is_prod_appengine(): - return "APPENGINE_RUNTIME" in os.environ and os.environ.get( - "SERVER_SOFTWARE", "" - ).startswith("Google App Engine/") - - -def is_prod_appengine_mvms(): - """Deprecated.""" - return False diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/contrib/_securetransport/__init__.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/contrib/_securetransport/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/contrib/_securetransport/bindings.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/contrib/_securetransport/bindings.py deleted file mode 100644 index 11524d400b..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/contrib/_securetransport/bindings.py +++ /dev/null @@ -1,519 +0,0 @@ -""" -This module uses ctypes to bind a whole bunch of functions and constants from -SecureTransport. The goal here is to provide the low-level API to -SecureTransport. These are essentially the C-level functions and constants, and -they're pretty gross to work with. - -This code is a bastardised version of the code found in Will Bond's oscrypto -library. An enormous debt is owed to him for blazing this trail for us. For -that reason, this code should be considered to be covered both by urllib3's -license and by oscrypto's: - - Copyright (c) 2015-2016 Will Bond - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -""" -from __future__ import absolute_import - -import platform -from ctypes import ( - CDLL, - CFUNCTYPE, - POINTER, - c_bool, - c_byte, - c_char_p, - c_int32, - c_long, - c_size_t, - c_uint32, - c_ulong, - c_void_p, -) -from ctypes.util import find_library - -from urllib3.packages.six import raise_from - -if platform.system() != "Darwin": - raise ImportError("Only macOS is supported") - -version = platform.mac_ver()[0] -version_info = tuple(map(int, version.split("."))) -if version_info < (10, 8): - raise OSError( - "Only OS X 10.8 and newer are supported, not %s.%s" - % (version_info[0], version_info[1]) - ) - - -def load_cdll(name, macos10_16_path): - """Loads a CDLL by name, falling back to known path on 10.16+""" - try: - # Big Sur is technically 11 but we use 10.16 due to the Big Sur - # beta being labeled as 10.16. - if version_info >= (10, 16): - path = macos10_16_path - else: - path = find_library(name) - if not path: - raise OSError # Caught and reraised as 'ImportError' - return CDLL(path, use_errno=True) - except OSError: - raise_from(ImportError("The library %s failed to load" % name), None) - - -Security = load_cdll( - "Security", "/System/Library/Frameworks/Security.framework/Security" -) -CoreFoundation = load_cdll( - "CoreFoundation", - "/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation", -) - - -Boolean = c_bool -CFIndex = c_long -CFStringEncoding = c_uint32 -CFData = c_void_p -CFString = c_void_p -CFArray = c_void_p -CFMutableArray = c_void_p -CFDictionary = c_void_p -CFError = c_void_p -CFType = c_void_p -CFTypeID = c_ulong - -CFTypeRef = POINTER(CFType) -CFAllocatorRef = c_void_p - -OSStatus = c_int32 - -CFDataRef = POINTER(CFData) -CFStringRef = POINTER(CFString) -CFArrayRef = POINTER(CFArray) -CFMutableArrayRef = POINTER(CFMutableArray) -CFDictionaryRef = POINTER(CFDictionary) -CFArrayCallBacks = c_void_p -CFDictionaryKeyCallBacks = c_void_p -CFDictionaryValueCallBacks = c_void_p - -SecCertificateRef = POINTER(c_void_p) -SecExternalFormat = c_uint32 -SecExternalItemType = c_uint32 -SecIdentityRef = POINTER(c_void_p) -SecItemImportExportFlags = c_uint32 -SecItemImportExportKeyParameters = c_void_p -SecKeychainRef = POINTER(c_void_p) -SSLProtocol = c_uint32 -SSLCipherSuite = c_uint32 -SSLContextRef = POINTER(c_void_p) -SecTrustRef = POINTER(c_void_p) -SSLConnectionRef = c_uint32 -SecTrustResultType = c_uint32 -SecTrustOptionFlags = c_uint32 -SSLProtocolSide = c_uint32 -SSLConnectionType = c_uint32 -SSLSessionOption = c_uint32 - - -try: - Security.SecItemImport.argtypes = [ - CFDataRef, - CFStringRef, - POINTER(SecExternalFormat), - POINTER(SecExternalItemType), - SecItemImportExportFlags, - POINTER(SecItemImportExportKeyParameters), - SecKeychainRef, - POINTER(CFArrayRef), - ] - Security.SecItemImport.restype = OSStatus - - Security.SecCertificateGetTypeID.argtypes = [] - Security.SecCertificateGetTypeID.restype = CFTypeID - - Security.SecIdentityGetTypeID.argtypes = [] - Security.SecIdentityGetTypeID.restype = CFTypeID - - Security.SecKeyGetTypeID.argtypes = [] - Security.SecKeyGetTypeID.restype = CFTypeID - - Security.SecCertificateCreateWithData.argtypes = [CFAllocatorRef, CFDataRef] - Security.SecCertificateCreateWithData.restype = SecCertificateRef - - Security.SecCertificateCopyData.argtypes = [SecCertificateRef] - Security.SecCertificateCopyData.restype = CFDataRef - - Security.SecCopyErrorMessageString.argtypes = [OSStatus, c_void_p] - Security.SecCopyErrorMessageString.restype = CFStringRef - - Security.SecIdentityCreateWithCertificate.argtypes = [ - CFTypeRef, - SecCertificateRef, - POINTER(SecIdentityRef), - ] - Security.SecIdentityCreateWithCertificate.restype = OSStatus - - Security.SecKeychainCreate.argtypes = [ - c_char_p, - c_uint32, - c_void_p, - Boolean, - c_void_p, - POINTER(SecKeychainRef), - ] - Security.SecKeychainCreate.restype = OSStatus - - Security.SecKeychainDelete.argtypes = [SecKeychainRef] - Security.SecKeychainDelete.restype = OSStatus - - Security.SecPKCS12Import.argtypes = [ - CFDataRef, - CFDictionaryRef, - POINTER(CFArrayRef), - ] - Security.SecPKCS12Import.restype = OSStatus - - SSLReadFunc = CFUNCTYPE(OSStatus, SSLConnectionRef, c_void_p, POINTER(c_size_t)) - SSLWriteFunc = CFUNCTYPE( - OSStatus, SSLConnectionRef, POINTER(c_byte), POINTER(c_size_t) - ) - - Security.SSLSetIOFuncs.argtypes = [SSLContextRef, SSLReadFunc, SSLWriteFunc] - Security.SSLSetIOFuncs.restype = OSStatus - - Security.SSLSetPeerID.argtypes = [SSLContextRef, c_char_p, c_size_t] - Security.SSLSetPeerID.restype = OSStatus - - Security.SSLSetCertificate.argtypes = [SSLContextRef, CFArrayRef] - Security.SSLSetCertificate.restype = OSStatus - - Security.SSLSetCertificateAuthorities.argtypes = [SSLContextRef, CFTypeRef, Boolean] - Security.SSLSetCertificateAuthorities.restype = OSStatus - - Security.SSLSetConnection.argtypes = [SSLContextRef, SSLConnectionRef] - Security.SSLSetConnection.restype = OSStatus - - Security.SSLSetPeerDomainName.argtypes = [SSLContextRef, c_char_p, c_size_t] - Security.SSLSetPeerDomainName.restype = OSStatus - - Security.SSLHandshake.argtypes = [SSLContextRef] - Security.SSLHandshake.restype = OSStatus - - Security.SSLRead.argtypes = [SSLContextRef, c_char_p, c_size_t, POINTER(c_size_t)] - Security.SSLRead.restype = OSStatus - - Security.SSLWrite.argtypes = [SSLContextRef, c_char_p, c_size_t, POINTER(c_size_t)] - Security.SSLWrite.restype = OSStatus - - Security.SSLClose.argtypes = [SSLContextRef] - Security.SSLClose.restype = OSStatus - - Security.SSLGetNumberSupportedCiphers.argtypes = [SSLContextRef, POINTER(c_size_t)] - Security.SSLGetNumberSupportedCiphers.restype = OSStatus - - Security.SSLGetSupportedCiphers.argtypes = [ - SSLContextRef, - POINTER(SSLCipherSuite), - POINTER(c_size_t), - ] - Security.SSLGetSupportedCiphers.restype = OSStatus - - Security.SSLSetEnabledCiphers.argtypes = [ - SSLContextRef, - POINTER(SSLCipherSuite), - c_size_t, - ] - Security.SSLSetEnabledCiphers.restype = OSStatus - - Security.SSLGetNumberEnabledCiphers.argtype = [SSLContextRef, POINTER(c_size_t)] - Security.SSLGetNumberEnabledCiphers.restype = OSStatus - - Security.SSLGetEnabledCiphers.argtypes = [ - SSLContextRef, - POINTER(SSLCipherSuite), - POINTER(c_size_t), - ] - Security.SSLGetEnabledCiphers.restype = OSStatus - - Security.SSLGetNegotiatedCipher.argtypes = [SSLContextRef, POINTER(SSLCipherSuite)] - Security.SSLGetNegotiatedCipher.restype = OSStatus - - Security.SSLGetNegotiatedProtocolVersion.argtypes = [ - SSLContextRef, - POINTER(SSLProtocol), - ] - Security.SSLGetNegotiatedProtocolVersion.restype = OSStatus - - Security.SSLCopyPeerTrust.argtypes = [SSLContextRef, POINTER(SecTrustRef)] - Security.SSLCopyPeerTrust.restype = OSStatus - - Security.SecTrustSetAnchorCertificates.argtypes = [SecTrustRef, CFArrayRef] - Security.SecTrustSetAnchorCertificates.restype = OSStatus - - Security.SecTrustSetAnchorCertificatesOnly.argstypes = [SecTrustRef, Boolean] - Security.SecTrustSetAnchorCertificatesOnly.restype = OSStatus - - Security.SecTrustEvaluate.argtypes = [SecTrustRef, POINTER(SecTrustResultType)] - Security.SecTrustEvaluate.restype = OSStatus - - Security.SecTrustGetCertificateCount.argtypes = [SecTrustRef] - Security.SecTrustGetCertificateCount.restype = CFIndex - - Security.SecTrustGetCertificateAtIndex.argtypes = [SecTrustRef, CFIndex] - Security.SecTrustGetCertificateAtIndex.restype = SecCertificateRef - - Security.SSLCreateContext.argtypes = [ - CFAllocatorRef, - SSLProtocolSide, - SSLConnectionType, - ] - Security.SSLCreateContext.restype = SSLContextRef - - Security.SSLSetSessionOption.argtypes = [SSLContextRef, SSLSessionOption, Boolean] - Security.SSLSetSessionOption.restype = OSStatus - - Security.SSLSetProtocolVersionMin.argtypes = [SSLContextRef, SSLProtocol] - Security.SSLSetProtocolVersionMin.restype = OSStatus - - Security.SSLSetProtocolVersionMax.argtypes = [SSLContextRef, SSLProtocol] - Security.SSLSetProtocolVersionMax.restype = OSStatus - - try: - Security.SSLSetALPNProtocols.argtypes = [SSLContextRef, CFArrayRef] - Security.SSLSetALPNProtocols.restype = OSStatus - except AttributeError: - # Supported only in 10.12+ - pass - - Security.SecCopyErrorMessageString.argtypes = [OSStatus, c_void_p] - Security.SecCopyErrorMessageString.restype = CFStringRef - - Security.SSLReadFunc = SSLReadFunc - Security.SSLWriteFunc = SSLWriteFunc - Security.SSLContextRef = SSLContextRef - Security.SSLProtocol = SSLProtocol - Security.SSLCipherSuite = SSLCipherSuite - Security.SecIdentityRef = SecIdentityRef - Security.SecKeychainRef = SecKeychainRef - Security.SecTrustRef = SecTrustRef - Security.SecTrustResultType = SecTrustResultType - Security.SecExternalFormat = SecExternalFormat - Security.OSStatus = OSStatus - - Security.kSecImportExportPassphrase = CFStringRef.in_dll( - Security, "kSecImportExportPassphrase" - ) - Security.kSecImportItemIdentity = CFStringRef.in_dll( - Security, "kSecImportItemIdentity" - ) - - # CoreFoundation time! - CoreFoundation.CFRetain.argtypes = [CFTypeRef] - CoreFoundation.CFRetain.restype = CFTypeRef - - CoreFoundation.CFRelease.argtypes = [CFTypeRef] - CoreFoundation.CFRelease.restype = None - - CoreFoundation.CFGetTypeID.argtypes = [CFTypeRef] - CoreFoundation.CFGetTypeID.restype = CFTypeID - - CoreFoundation.CFStringCreateWithCString.argtypes = [ - CFAllocatorRef, - c_char_p, - CFStringEncoding, - ] - CoreFoundation.CFStringCreateWithCString.restype = CFStringRef - - CoreFoundation.CFStringGetCStringPtr.argtypes = [CFStringRef, CFStringEncoding] - CoreFoundation.CFStringGetCStringPtr.restype = c_char_p - - CoreFoundation.CFStringGetCString.argtypes = [ - CFStringRef, - c_char_p, - CFIndex, - CFStringEncoding, - ] - CoreFoundation.CFStringGetCString.restype = c_bool - - CoreFoundation.CFDataCreate.argtypes = [CFAllocatorRef, c_char_p, CFIndex] - CoreFoundation.CFDataCreate.restype = CFDataRef - - CoreFoundation.CFDataGetLength.argtypes = [CFDataRef] - CoreFoundation.CFDataGetLength.restype = CFIndex - - CoreFoundation.CFDataGetBytePtr.argtypes = [CFDataRef] - CoreFoundation.CFDataGetBytePtr.restype = c_void_p - - CoreFoundation.CFDictionaryCreate.argtypes = [ - CFAllocatorRef, - POINTER(CFTypeRef), - POINTER(CFTypeRef), - CFIndex, - CFDictionaryKeyCallBacks, - CFDictionaryValueCallBacks, - ] - CoreFoundation.CFDictionaryCreate.restype = CFDictionaryRef - - CoreFoundation.CFDictionaryGetValue.argtypes = [CFDictionaryRef, CFTypeRef] - CoreFoundation.CFDictionaryGetValue.restype = CFTypeRef - - CoreFoundation.CFArrayCreate.argtypes = [ - CFAllocatorRef, - POINTER(CFTypeRef), - CFIndex, - CFArrayCallBacks, - ] - CoreFoundation.CFArrayCreate.restype = CFArrayRef - - CoreFoundation.CFArrayCreateMutable.argtypes = [ - CFAllocatorRef, - CFIndex, - CFArrayCallBacks, - ] - CoreFoundation.CFArrayCreateMutable.restype = CFMutableArrayRef - - CoreFoundation.CFArrayAppendValue.argtypes = [CFMutableArrayRef, c_void_p] - CoreFoundation.CFArrayAppendValue.restype = None - - CoreFoundation.CFArrayGetCount.argtypes = [CFArrayRef] - CoreFoundation.CFArrayGetCount.restype = CFIndex - - CoreFoundation.CFArrayGetValueAtIndex.argtypes = [CFArrayRef, CFIndex] - CoreFoundation.CFArrayGetValueAtIndex.restype = c_void_p - - CoreFoundation.kCFAllocatorDefault = CFAllocatorRef.in_dll( - CoreFoundation, "kCFAllocatorDefault" - ) - CoreFoundation.kCFTypeArrayCallBacks = c_void_p.in_dll( - CoreFoundation, "kCFTypeArrayCallBacks" - ) - CoreFoundation.kCFTypeDictionaryKeyCallBacks = c_void_p.in_dll( - CoreFoundation, "kCFTypeDictionaryKeyCallBacks" - ) - CoreFoundation.kCFTypeDictionaryValueCallBacks = c_void_p.in_dll( - CoreFoundation, "kCFTypeDictionaryValueCallBacks" - ) - - CoreFoundation.CFTypeRef = CFTypeRef - CoreFoundation.CFArrayRef = CFArrayRef - CoreFoundation.CFStringRef = CFStringRef - CoreFoundation.CFDictionaryRef = CFDictionaryRef - -except (AttributeError): - raise ImportError("Error initializing ctypes") - - -class CFConst(object): - """ - A class object that acts as essentially a namespace for CoreFoundation - constants. - """ - - kCFStringEncodingUTF8 = CFStringEncoding(0x08000100) - - -class SecurityConst(object): - """ - A class object that acts as essentially a namespace for Security constants. - """ - - kSSLSessionOptionBreakOnServerAuth = 0 - - kSSLProtocol2 = 1 - kSSLProtocol3 = 2 - kTLSProtocol1 = 4 - kTLSProtocol11 = 7 - kTLSProtocol12 = 8 - # SecureTransport does not support TLS 1.3 even if there's a constant for it - kTLSProtocol13 = 10 - kTLSProtocolMaxSupported = 999 - - kSSLClientSide = 1 - kSSLStreamType = 0 - - kSecFormatPEMSequence = 10 - - kSecTrustResultInvalid = 0 - kSecTrustResultProceed = 1 - # This gap is present on purpose: this was kSecTrustResultConfirm, which - # is deprecated. - kSecTrustResultDeny = 3 - kSecTrustResultUnspecified = 4 - kSecTrustResultRecoverableTrustFailure = 5 - kSecTrustResultFatalTrustFailure = 6 - kSecTrustResultOtherError = 7 - - errSSLProtocol = -9800 - errSSLWouldBlock = -9803 - errSSLClosedGraceful = -9805 - errSSLClosedNoNotify = -9816 - errSSLClosedAbort = -9806 - - errSSLXCertChainInvalid = -9807 - errSSLCrypto = -9809 - errSSLInternal = -9810 - errSSLCertExpired = -9814 - errSSLCertNotYetValid = -9815 - errSSLUnknownRootCert = -9812 - errSSLNoRootCert = -9813 - errSSLHostNameMismatch = -9843 - errSSLPeerHandshakeFail = -9824 - errSSLPeerUserCancelled = -9839 - errSSLWeakPeerEphemeralDHKey = -9850 - errSSLServerAuthCompleted = -9841 - errSSLRecordOverflow = -9847 - - errSecVerifyFailed = -67808 - errSecNoTrustSettings = -25263 - errSecItemNotFound = -25300 - errSecInvalidTrustSettings = -25262 - - # Cipher suites. We only pick the ones our default cipher string allows. - # Source: https://developer.apple.com/documentation/security/1550981-ssl_cipher_suite_values - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02C - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xC030 - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA9 - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA8 - TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = 0x009F - TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E - TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC024 - TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 = 0xC028 - TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xC00A - TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014 - TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x006B - TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039 - TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC023 - TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xC027 - TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0xC009 - TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013 - TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x0067 - TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033 - TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009D - TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C - TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x003D - TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x003C - TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035 - TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F - TLS_AES_128_GCM_SHA256 = 0x1301 - TLS_AES_256_GCM_SHA384 = 0x1302 - TLS_AES_128_CCM_8_SHA256 = 0x1305 - TLS_AES_128_CCM_SHA256 = 0x1304 diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/contrib/_securetransport/low_level.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/contrib/_securetransport/low_level.py deleted file mode 100644 index ed8120190c..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/contrib/_securetransport/low_level.py +++ /dev/null @@ -1,396 +0,0 @@ -""" -Low-level helpers for the SecureTransport bindings. - -These are Python functions that are not directly related to the high-level APIs -but are necessary to get them to work. They include a whole bunch of low-level -CoreFoundation messing about and memory management. The concerns in this module -are almost entirely about trying to avoid memory leaks and providing -appropriate and useful assistance to the higher-level code. -""" -import base64 -import ctypes -import itertools -import os -import re -import ssl -import struct -import tempfile - -from .bindings import CFConst, CoreFoundation, Security - -# This regular expression is used to grab PEM data out of a PEM bundle. -_PEM_CERTS_RE = re.compile( - b"-----BEGIN CERTIFICATE-----\n(.*?)\n-----END CERTIFICATE-----", re.DOTALL -) - - -def _cf_data_from_bytes(bytestring): - """ - Given a bytestring, create a CFData object from it. This CFData object must - be CFReleased by the caller. - """ - return CoreFoundation.CFDataCreate( - CoreFoundation.kCFAllocatorDefault, bytestring, len(bytestring) - ) - - -def _cf_dictionary_from_tuples(tuples): - """ - Given a list of Python tuples, create an associated CFDictionary. - """ - dictionary_size = len(tuples) - - # We need to get the dictionary keys and values out in the same order. - keys = (t[0] for t in tuples) - values = (t[1] for t in tuples) - cf_keys = (CoreFoundation.CFTypeRef * dictionary_size)(*keys) - cf_values = (CoreFoundation.CFTypeRef * dictionary_size)(*values) - - return CoreFoundation.CFDictionaryCreate( - CoreFoundation.kCFAllocatorDefault, - cf_keys, - cf_values, - dictionary_size, - CoreFoundation.kCFTypeDictionaryKeyCallBacks, - CoreFoundation.kCFTypeDictionaryValueCallBacks, - ) - - -def _cfstr(py_bstr): - """ - Given a Python binary data, create a CFString. - The string must be CFReleased by the caller. - """ - c_str = ctypes.c_char_p(py_bstr) - cf_str = CoreFoundation.CFStringCreateWithCString( - CoreFoundation.kCFAllocatorDefault, - c_str, - CFConst.kCFStringEncodingUTF8, - ) - return cf_str - - -def _create_cfstring_array(lst): - """ - Given a list of Python binary data, create an associated CFMutableArray. - The array must be CFReleased by the caller. - - Raises an ssl.SSLError on failure. - """ - cf_arr = None - try: - cf_arr = CoreFoundation.CFArrayCreateMutable( - CoreFoundation.kCFAllocatorDefault, - 0, - ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks), - ) - if not cf_arr: - raise MemoryError("Unable to allocate memory!") - for item in lst: - cf_str = _cfstr(item) - if not cf_str: - raise MemoryError("Unable to allocate memory!") - try: - CoreFoundation.CFArrayAppendValue(cf_arr, cf_str) - finally: - CoreFoundation.CFRelease(cf_str) - except BaseException as e: - if cf_arr: - CoreFoundation.CFRelease(cf_arr) - raise ssl.SSLError("Unable to allocate array: %s" % (e,)) - return cf_arr - - -def _cf_string_to_unicode(value): - """ - Creates a Unicode string from a CFString object. Used entirely for error - reporting. - - Yes, it annoys me quite a lot that this function is this complex. - """ - value_as_void_p = ctypes.cast(value, ctypes.POINTER(ctypes.c_void_p)) - - string = CoreFoundation.CFStringGetCStringPtr( - value_as_void_p, CFConst.kCFStringEncodingUTF8 - ) - if string is None: - buffer = ctypes.create_string_buffer(1024) - result = CoreFoundation.CFStringGetCString( - value_as_void_p, buffer, 1024, CFConst.kCFStringEncodingUTF8 - ) - if not result: - raise OSError("Error copying C string from CFStringRef") - string = buffer.value - if string is not None: - string = string.decode("utf-8") - return string - - -def _assert_no_error(error, exception_class=None): - """ - Checks the return code and throws an exception if there is an error to - report - """ - if error == 0: - return - - cf_error_string = Security.SecCopyErrorMessageString(error, None) - output = _cf_string_to_unicode(cf_error_string) - CoreFoundation.CFRelease(cf_error_string) - - if output is None or output == u"": - output = u"OSStatus %s" % error - - if exception_class is None: - exception_class = ssl.SSLError - - raise exception_class(output) - - -def _cert_array_from_pem(pem_bundle): - """ - Given a bundle of certs in PEM format, turns them into a CFArray of certs - that can be used to validate a cert chain. - """ - # Normalize the PEM bundle's line endings. - pem_bundle = pem_bundle.replace(b"\r\n", b"\n") - - der_certs = [ - base64.b64decode(match.group(1)) for match in _PEM_CERTS_RE.finditer(pem_bundle) - ] - if not der_certs: - raise ssl.SSLError("No root certificates specified") - - cert_array = CoreFoundation.CFArrayCreateMutable( - CoreFoundation.kCFAllocatorDefault, - 0, - ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks), - ) - if not cert_array: - raise ssl.SSLError("Unable to allocate memory!") - - try: - for der_bytes in der_certs: - certdata = _cf_data_from_bytes(der_bytes) - if not certdata: - raise ssl.SSLError("Unable to allocate memory!") - cert = Security.SecCertificateCreateWithData( - CoreFoundation.kCFAllocatorDefault, certdata - ) - CoreFoundation.CFRelease(certdata) - if not cert: - raise ssl.SSLError("Unable to build cert object!") - - CoreFoundation.CFArrayAppendValue(cert_array, cert) - CoreFoundation.CFRelease(cert) - except Exception: - # We need to free the array before the exception bubbles further. - # We only want to do that if an error occurs: otherwise, the caller - # should free. - CoreFoundation.CFRelease(cert_array) - - return cert_array - - -def _is_cert(item): - """ - Returns True if a given CFTypeRef is a certificate. - """ - expected = Security.SecCertificateGetTypeID() - return CoreFoundation.CFGetTypeID(item) == expected - - -def _is_identity(item): - """ - Returns True if a given CFTypeRef is an identity. - """ - expected = Security.SecIdentityGetTypeID() - return CoreFoundation.CFGetTypeID(item) == expected - - -def _temporary_keychain(): - """ - This function creates a temporary Mac keychain that we can use to work with - credentials. This keychain uses a one-time password and a temporary file to - store the data. We expect to have one keychain per socket. The returned - SecKeychainRef must be freed by the caller, including calling - SecKeychainDelete. - - Returns a tuple of the SecKeychainRef and the path to the temporary - directory that contains it. - """ - # Unfortunately, SecKeychainCreate requires a path to a keychain. This - # means we cannot use mkstemp to use a generic temporary file. Instead, - # we're going to create a temporary directory and a filename to use there. - # This filename will be 8 random bytes expanded into base64. We also need - # some random bytes to password-protect the keychain we're creating, so we - # ask for 40 random bytes. - random_bytes = os.urandom(40) - filename = base64.b16encode(random_bytes[:8]).decode("utf-8") - password = base64.b16encode(random_bytes[8:]) # Must be valid UTF-8 - tempdirectory = tempfile.mkdtemp() - - keychain_path = os.path.join(tempdirectory, filename).encode("utf-8") - - # We now want to create the keychain itself. - keychain = Security.SecKeychainRef() - status = Security.SecKeychainCreate( - keychain_path, len(password), password, False, None, ctypes.byref(keychain) - ) - _assert_no_error(status) - - # Having created the keychain, we want to pass it off to the caller. - return keychain, tempdirectory - - -def _load_items_from_file(keychain, path): - """ - Given a single file, loads all the trust objects from it into arrays and - the keychain. - Returns a tuple of lists: the first list is a list of identities, the - second a list of certs. - """ - certificates = [] - identities = [] - result_array = None - - with open(path, "rb") as f: - raw_filedata = f.read() - - try: - filedata = CoreFoundation.CFDataCreate( - CoreFoundation.kCFAllocatorDefault, raw_filedata, len(raw_filedata) - ) - result_array = CoreFoundation.CFArrayRef() - result = Security.SecItemImport( - filedata, # cert data - None, # Filename, leaving it out for now - None, # What the type of the file is, we don't care - None, # what's in the file, we don't care - 0, # import flags - None, # key params, can include passphrase in the future - keychain, # The keychain to insert into - ctypes.byref(result_array), # Results - ) - _assert_no_error(result) - - # A CFArray is not very useful to us as an intermediary - # representation, so we are going to extract the objects we want - # and then free the array. We don't need to keep hold of keys: the - # keychain already has them! - result_count = CoreFoundation.CFArrayGetCount(result_array) - for index in range(result_count): - item = CoreFoundation.CFArrayGetValueAtIndex(result_array, index) - item = ctypes.cast(item, CoreFoundation.CFTypeRef) - - if _is_cert(item): - CoreFoundation.CFRetain(item) - certificates.append(item) - elif _is_identity(item): - CoreFoundation.CFRetain(item) - identities.append(item) - finally: - if result_array: - CoreFoundation.CFRelease(result_array) - - CoreFoundation.CFRelease(filedata) - - return (identities, certificates) - - -def _load_client_cert_chain(keychain, *paths): - """ - Load certificates and maybe keys from a number of files. Has the end goal - of returning a CFArray containing one SecIdentityRef, and then zero or more - SecCertificateRef objects, suitable for use as a client certificate trust - chain. - """ - # Ok, the strategy. - # - # This relies on knowing that macOS will not give you a SecIdentityRef - # unless you have imported a key into a keychain. This is a somewhat - # artificial limitation of macOS (for example, it doesn't necessarily - # affect iOS), but there is nothing inside Security.framework that lets you - # get a SecIdentityRef without having a key in a keychain. - # - # So the policy here is we take all the files and iterate them in order. - # Each one will use SecItemImport to have one or more objects loaded from - # it. We will also point at a keychain that macOS can use to work with the - # private key. - # - # Once we have all the objects, we'll check what we actually have. If we - # already have a SecIdentityRef in hand, fab: we'll use that. Otherwise, - # we'll take the first certificate (which we assume to be our leaf) and - # ask the keychain to give us a SecIdentityRef with that cert's associated - # key. - # - # We'll then return a CFArray containing the trust chain: one - # SecIdentityRef and then zero-or-more SecCertificateRef objects. The - # responsibility for freeing this CFArray will be with the caller. This - # CFArray must remain alive for the entire connection, so in practice it - # will be stored with a single SSLSocket, along with the reference to the - # keychain. - certificates = [] - identities = [] - - # Filter out bad paths. - paths = (path for path in paths if path) - - try: - for file_path in paths: - new_identities, new_certs = _load_items_from_file(keychain, file_path) - identities.extend(new_identities) - certificates.extend(new_certs) - - # Ok, we have everything. The question is: do we have an identity? If - # not, we want to grab one from the first cert we have. - if not identities: - new_identity = Security.SecIdentityRef() - status = Security.SecIdentityCreateWithCertificate( - keychain, certificates[0], ctypes.byref(new_identity) - ) - _assert_no_error(status) - identities.append(new_identity) - - # We now want to release the original certificate, as we no longer - # need it. - CoreFoundation.CFRelease(certificates.pop(0)) - - # We now need to build a new CFArray that holds the trust chain. - trust_chain = CoreFoundation.CFArrayCreateMutable( - CoreFoundation.kCFAllocatorDefault, - 0, - ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks), - ) - for item in itertools.chain(identities, certificates): - # ArrayAppendValue does a CFRetain on the item. That's fine, - # because the finally block will release our other refs to them. - CoreFoundation.CFArrayAppendValue(trust_chain, item) - - return trust_chain - finally: - for obj in itertools.chain(identities, certificates): - CoreFoundation.CFRelease(obj) - - -TLS_PROTOCOL_VERSIONS = { - "SSLv2": (0, 2), - "SSLv3": (3, 0), - "TLSv1": (3, 1), - "TLSv1.1": (3, 2), - "TLSv1.2": (3, 3), -} - - -def _build_tls_unknown_ca_alert(version): - """ - Builds a TLS alert record for an unknown CA. - """ - ver_maj, ver_min = TLS_PROTOCOL_VERSIONS[version] - severity_fatal = 0x02 - description_unknown_ca = 0x30 - msg = struct.pack(">BB", severity_fatal, description_unknown_ca) - msg_len = len(msg) - record_type_alert = 0x15 - record = struct.pack(">BBBH", record_type_alert, ver_maj, ver_min, msg_len) + msg - return record diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/contrib/appengine.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/contrib/appengine.py deleted file mode 100644 index f91bdd6e77..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/contrib/appengine.py +++ /dev/null @@ -1,314 +0,0 @@ -""" -This module provides a pool manager that uses Google App Engine's -`URLFetch Service `_. - -Example usage:: - - from urllib3 import PoolManager - from urllib3.contrib.appengine import AppEngineManager, is_appengine_sandbox - - if is_appengine_sandbox(): - # AppEngineManager uses AppEngine's URLFetch API behind the scenes - http = AppEngineManager() - else: - # PoolManager uses a socket-level API behind the scenes - http = PoolManager() - - r = http.request('GET', 'https://google.com/') - -There are `limitations `_ to the URLFetch service and it may not be -the best choice for your application. There are three options for using -urllib3 on Google App Engine: - -1. You can use :class:`AppEngineManager` with URLFetch. URLFetch is - cost-effective in many circumstances as long as your usage is within the - limitations. -2. You can use a normal :class:`~urllib3.PoolManager` by enabling sockets. - Sockets also have `limitations and restrictions - `_ and have a lower free quota than URLFetch. - To use sockets, be sure to specify the following in your ``app.yaml``:: - - env_variables: - GAE_USE_SOCKETS_HTTPLIB : 'true' - -3. If you are using `App Engine Flexible -`_, you can use the standard -:class:`PoolManager` without any configuration or special environment variables. -""" - -from __future__ import absolute_import - -import io -import logging -import warnings - -from ..exceptions import ( - HTTPError, - HTTPWarning, - MaxRetryError, - ProtocolError, - SSLError, - TimeoutError, -) -from ..packages.six.moves.urllib.parse import urljoin -from ..request import RequestMethods -from ..response import HTTPResponse -from ..util.retry import Retry -from ..util.timeout import Timeout -from . import _appengine_environ - -try: - from google.appengine.api import urlfetch -except ImportError: - urlfetch = None - - -log = logging.getLogger(__name__) - - -class AppEnginePlatformWarning(HTTPWarning): - pass - - -class AppEnginePlatformError(HTTPError): - pass - - -class AppEngineManager(RequestMethods): - """ - Connection manager for Google App Engine sandbox applications. - - This manager uses the URLFetch service directly instead of using the - emulated httplib, and is subject to URLFetch limitations as described in - the App Engine documentation `here - `_. - - Notably it will raise an :class:`AppEnginePlatformError` if: - * URLFetch is not available. - * If you attempt to use this on App Engine Flexible, as full socket - support is available. - * If a request size is more than 10 megabytes. - * If a response size is more than 32 megabytes. - * If you use an unsupported request method such as OPTIONS. - - Beyond those cases, it will raise normal urllib3 errors. - """ - - def __init__( - self, - headers=None, - retries=None, - validate_certificate=True, - urlfetch_retries=True, - ): - if not urlfetch: - raise AppEnginePlatformError( - "URLFetch is not available in this environment." - ) - - warnings.warn( - "urllib3 is using URLFetch on Google App Engine sandbox instead " - "of sockets. To use sockets directly instead of URLFetch see " - "https://urllib3.readthedocs.io/en/1.26.x/reference/urllib3.contrib.html.", - AppEnginePlatformWarning, - ) - - RequestMethods.__init__(self, headers) - self.validate_certificate = validate_certificate - self.urlfetch_retries = urlfetch_retries - - self.retries = retries or Retry.DEFAULT - - def __enter__(self): - return self - - def __exit__(self, exc_type, exc_val, exc_tb): - # Return False to re-raise any potential exceptions - return False - - def urlopen( - self, - method, - url, - body=None, - headers=None, - retries=None, - redirect=True, - timeout=Timeout.DEFAULT_TIMEOUT, - **response_kw - ): - - retries = self._get_retries(retries, redirect) - - try: - follow_redirects = redirect and retries.redirect != 0 and retries.total - response = urlfetch.fetch( - url, - payload=body, - method=method, - headers=headers or {}, - allow_truncated=False, - follow_redirects=self.urlfetch_retries and follow_redirects, - deadline=self._get_absolute_timeout(timeout), - validate_certificate=self.validate_certificate, - ) - except urlfetch.DeadlineExceededError as e: - raise TimeoutError(self, e) - - except urlfetch.InvalidURLError as e: - if "too large" in str(e): - raise AppEnginePlatformError( - "URLFetch request too large, URLFetch only " - "supports requests up to 10mb in size.", - e, - ) - raise ProtocolError(e) - - except urlfetch.DownloadError as e: - if "Too many redirects" in str(e): - raise MaxRetryError(self, url, reason=e) - raise ProtocolError(e) - - except urlfetch.ResponseTooLargeError as e: - raise AppEnginePlatformError( - "URLFetch response too large, URLFetch only supports" - "responses up to 32mb in size.", - e, - ) - - except urlfetch.SSLCertificateError as e: - raise SSLError(e) - - except urlfetch.InvalidMethodError as e: - raise AppEnginePlatformError( - "URLFetch does not support method: %s" % method, e - ) - - http_response = self._urlfetch_response_to_http_response( - response, retries=retries, **response_kw - ) - - # Handle redirect? - redirect_location = redirect and http_response.get_redirect_location() - if redirect_location: - # Check for redirect response - if self.urlfetch_retries and retries.raise_on_redirect: - raise MaxRetryError(self, url, "too many redirects") - else: - if http_response.status == 303: - method = "GET" - - try: - retries = retries.increment( - method, url, response=http_response, _pool=self - ) - except MaxRetryError: - if retries.raise_on_redirect: - raise MaxRetryError(self, url, "too many redirects") - return http_response - - retries.sleep_for_retry(http_response) - log.debug("Redirecting %s -> %s", url, redirect_location) - redirect_url = urljoin(url, redirect_location) - return self.urlopen( - method, - redirect_url, - body, - headers, - retries=retries, - redirect=redirect, - timeout=timeout, - **response_kw - ) - - # Check if we should retry the HTTP response. - has_retry_after = bool(http_response.getheader("Retry-After")) - if retries.is_retry(method, http_response.status, has_retry_after): - retries = retries.increment(method, url, response=http_response, _pool=self) - log.debug("Retry: %s", url) - retries.sleep(http_response) - return self.urlopen( - method, - url, - body=body, - headers=headers, - retries=retries, - redirect=redirect, - timeout=timeout, - **response_kw - ) - - return http_response - - def _urlfetch_response_to_http_response(self, urlfetch_resp, **response_kw): - - if is_prod_appengine(): - # Production GAE handles deflate encoding automatically, but does - # not remove the encoding header. - content_encoding = urlfetch_resp.headers.get("content-encoding") - - if content_encoding == "deflate": - del urlfetch_resp.headers["content-encoding"] - - transfer_encoding = urlfetch_resp.headers.get("transfer-encoding") - # We have a full response's content, - # so let's make sure we don't report ourselves as chunked data. - if transfer_encoding == "chunked": - encodings = transfer_encoding.split(",") - encodings.remove("chunked") - urlfetch_resp.headers["transfer-encoding"] = ",".join(encodings) - - original_response = HTTPResponse( - # In order for decoding to work, we must present the content as - # a file-like object. - body=io.BytesIO(urlfetch_resp.content), - msg=urlfetch_resp.header_msg, - headers=urlfetch_resp.headers, - status=urlfetch_resp.status_code, - **response_kw - ) - - return HTTPResponse( - body=io.BytesIO(urlfetch_resp.content), - headers=urlfetch_resp.headers, - status=urlfetch_resp.status_code, - original_response=original_response, - **response_kw - ) - - def _get_absolute_timeout(self, timeout): - if timeout is Timeout.DEFAULT_TIMEOUT: - return None # Defer to URLFetch's default. - if isinstance(timeout, Timeout): - if timeout._read is not None or timeout._connect is not None: - warnings.warn( - "URLFetch does not support granular timeout settings, " - "reverting to total or default URLFetch timeout.", - AppEnginePlatformWarning, - ) - return timeout.total - return timeout - - def _get_retries(self, retries, redirect): - if not isinstance(retries, Retry): - retries = Retry.from_int(retries, redirect=redirect, default=self.retries) - - if retries.connect or retries.read or retries.redirect: - warnings.warn( - "URLFetch only supports total retries and does not " - "recognize connect, read, or redirect retry parameters.", - AppEnginePlatformWarning, - ) - - return retries - - -# Alias methods from _appengine_environ to maintain public API interface. - -is_appengine = _appengine_environ.is_appengine -is_appengine_sandbox = _appengine_environ.is_appengine_sandbox -is_local_appengine = _appengine_environ.is_local_appengine -is_prod_appengine = _appengine_environ.is_prod_appengine -is_prod_appengine_mvms = _appengine_environ.is_prod_appengine_mvms diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/contrib/ntlmpool.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/contrib/ntlmpool.py deleted file mode 100644 index 41a8fd174c..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/contrib/ntlmpool.py +++ /dev/null @@ -1,130 +0,0 @@ -""" -NTLM authenticating pool, contributed by erikcederstran - -Issue #10, see: http://code.google.com/p/urllib3/issues/detail?id=10 -""" -from __future__ import absolute_import - -import warnings -from logging import getLogger - -from ntlm import ntlm - -from .. import HTTPSConnectionPool -from ..packages.six.moves.http_client import HTTPSConnection - -warnings.warn( - "The 'urllib3.contrib.ntlmpool' module is deprecated and will be removed " - "in urllib3 v2.0 release, urllib3 is not able to support it properly due " - "to reasons listed in issue: https://github.com/urllib3/urllib3/issues/2282. " - "If you are a user of this module please comment in the mentioned issue.", - DeprecationWarning, -) - -log = getLogger(__name__) - - -class NTLMConnectionPool(HTTPSConnectionPool): - """ - Implements an NTLM authentication version of an urllib3 connection pool - """ - - scheme = "https" - - def __init__(self, user, pw, authurl, *args, **kwargs): - """ - authurl is a random URL on the server that is protected by NTLM. - user is the Windows user, probably in the DOMAIN\\username format. - pw is the password for the user. - """ - super(NTLMConnectionPool, self).__init__(*args, **kwargs) - self.authurl = authurl - self.rawuser = user - user_parts = user.split("\\", 1) - self.domain = user_parts[0].upper() - self.user = user_parts[1] - self.pw = pw - - def _new_conn(self): - # Performs the NTLM handshake that secures the connection. The socket - # must be kept open while requests are performed. - self.num_connections += 1 - log.debug( - "Starting NTLM HTTPS connection no. %d: https://%s%s", - self.num_connections, - self.host, - self.authurl, - ) - - headers = {"Connection": "Keep-Alive"} - req_header = "Authorization" - resp_header = "www-authenticate" - - conn = HTTPSConnection(host=self.host, port=self.port) - - # Send negotiation message - headers[req_header] = "NTLM %s" % ntlm.create_NTLM_NEGOTIATE_MESSAGE( - self.rawuser - ) - log.debug("Request headers: %s", headers) - conn.request("GET", self.authurl, None, headers) - res = conn.getresponse() - reshdr = dict(res.getheaders()) - log.debug("Response status: %s %s", res.status, res.reason) - log.debug("Response headers: %s", reshdr) - log.debug("Response data: %s [...]", res.read(100)) - - # Remove the reference to the socket, so that it can not be closed by - # the response object (we want to keep the socket open) - res.fp = None - - # Server should respond with a challenge message - auth_header_values = reshdr[resp_header].split(", ") - auth_header_value = None - for s in auth_header_values: - if s[:5] == "NTLM ": - auth_header_value = s[5:] - if auth_header_value is None: - raise Exception( - "Unexpected %s response header: %s" % (resp_header, reshdr[resp_header]) - ) - - # Send authentication message - ServerChallenge, NegotiateFlags = ntlm.parse_NTLM_CHALLENGE_MESSAGE( - auth_header_value - ) - auth_msg = ntlm.create_NTLM_AUTHENTICATE_MESSAGE( - ServerChallenge, self.user, self.domain, self.pw, NegotiateFlags - ) - headers[req_header] = "NTLM %s" % auth_msg - log.debug("Request headers: %s", headers) - conn.request("GET", self.authurl, None, headers) - res = conn.getresponse() - log.debug("Response status: %s %s", res.status, res.reason) - log.debug("Response headers: %s", dict(res.getheaders())) - log.debug("Response data: %s [...]", res.read()[:100]) - if res.status != 200: - if res.status == 401: - raise Exception("Server rejected request: wrong username or password") - raise Exception("Wrong server response: %s %s" % (res.status, res.reason)) - - res.fp = None - log.debug("Connection established") - return conn - - def urlopen( - self, - method, - url, - body=None, - headers=None, - retries=3, - redirect=True, - assert_same_host=True, - ): - if headers is None: - headers = {} - headers["Connection"] = "Keep-Alive" - return super(NTLMConnectionPool, self).urlopen( - method, url, body, headers, retries, redirect, assert_same_host - ) diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/contrib/pyopenssl.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/contrib/pyopenssl.py deleted file mode 100644 index def83afdb2..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/contrib/pyopenssl.py +++ /dev/null @@ -1,511 +0,0 @@ -""" -TLS with SNI_-support for Python 2. Follow these instructions if you would -like to verify TLS certificates in Python 2. Note, the default libraries do -*not* do certificate checking; you need to do additional work to validate -certificates yourself. - -This needs the following packages installed: - -* `pyOpenSSL`_ (tested with 16.0.0) -* `cryptography`_ (minimum 1.3.4, from pyopenssl) -* `idna`_ (minimum 2.0, from cryptography) - -However, pyopenssl depends on cryptography, which depends on idna, so while we -use all three directly here we end up having relatively few packages required. - -You can install them with the following command: - -.. code-block:: bash - - $ python -m pip install pyopenssl cryptography idna - -To activate certificate checking, call -:func:`~urllib3.contrib.pyopenssl.inject_into_urllib3` from your Python code -before you begin making HTTP requests. This can be done in a ``sitecustomize`` -module, or at any other time before your application begins using ``urllib3``, -like this: - -.. code-block:: python - - try: - import urllib3.contrib.pyopenssl - urllib3.contrib.pyopenssl.inject_into_urllib3() - except ImportError: - pass - -Now you can use :mod:`urllib3` as you normally would, and it will support SNI -when the required modules are installed. - -Activating this module also has the positive side effect of disabling SSL/TLS -compression in Python 2 (see `CRIME attack`_). - -.. _sni: https://en.wikipedia.org/wiki/Server_Name_Indication -.. _crime attack: https://en.wikipedia.org/wiki/CRIME_(security_exploit) -.. _pyopenssl: https://www.pyopenssl.org -.. _cryptography: https://cryptography.io -.. _idna: https://github.com/kjd/idna -""" -from __future__ import absolute_import - -import OpenSSL.SSL -from cryptography import x509 -from cryptography.hazmat.backends.openssl import backend as openssl_backend -from cryptography.hazmat.backends.openssl.x509 import _Certificate - -try: - from cryptography.x509 import UnsupportedExtension -except ImportError: - # UnsupportedExtension is gone in cryptography >= 2.1.0 - class UnsupportedExtension(Exception): - pass - - -from io import BytesIO -from socket import error as SocketError -from socket import timeout - -try: # Platform-specific: Python 2 - from socket import _fileobject -except ImportError: # Platform-specific: Python 3 - _fileobject = None - from ..packages.backports.makefile import backport_makefile - -import logging -import ssl -import sys - -from .. import util -from ..packages import six -from ..util.ssl_ import PROTOCOL_TLS_CLIENT - -__all__ = ["inject_into_urllib3", "extract_from_urllib3"] - -# SNI always works. -HAS_SNI = True - -# Map from urllib3 to PyOpenSSL compatible parameter-values. -_openssl_versions = { - util.PROTOCOL_TLS: OpenSSL.SSL.SSLv23_METHOD, - PROTOCOL_TLS_CLIENT: OpenSSL.SSL.SSLv23_METHOD, - ssl.PROTOCOL_TLSv1: OpenSSL.SSL.TLSv1_METHOD, -} - -if hasattr(ssl, "PROTOCOL_SSLv3") and hasattr(OpenSSL.SSL, "SSLv3_METHOD"): - _openssl_versions[ssl.PROTOCOL_SSLv3] = OpenSSL.SSL.SSLv3_METHOD - -if hasattr(ssl, "PROTOCOL_TLSv1_1") and hasattr(OpenSSL.SSL, "TLSv1_1_METHOD"): - _openssl_versions[ssl.PROTOCOL_TLSv1_1] = OpenSSL.SSL.TLSv1_1_METHOD - -if hasattr(ssl, "PROTOCOL_TLSv1_2") and hasattr(OpenSSL.SSL, "TLSv1_2_METHOD"): - _openssl_versions[ssl.PROTOCOL_TLSv1_2] = OpenSSL.SSL.TLSv1_2_METHOD - - -_stdlib_to_openssl_verify = { - ssl.CERT_NONE: OpenSSL.SSL.VERIFY_NONE, - ssl.CERT_OPTIONAL: OpenSSL.SSL.VERIFY_PEER, - ssl.CERT_REQUIRED: OpenSSL.SSL.VERIFY_PEER - + OpenSSL.SSL.VERIFY_FAIL_IF_NO_PEER_CERT, -} -_openssl_to_stdlib_verify = dict((v, k) for k, v in _stdlib_to_openssl_verify.items()) - -# OpenSSL will only write 16K at a time -SSL_WRITE_BLOCKSIZE = 16384 - -orig_util_HAS_SNI = util.HAS_SNI -orig_util_SSLContext = util.ssl_.SSLContext - - -log = logging.getLogger(__name__) - - -def inject_into_urllib3(): - "Monkey-patch urllib3 with PyOpenSSL-backed SSL-support." - - _validate_dependencies_met() - - util.SSLContext = PyOpenSSLContext - util.ssl_.SSLContext = PyOpenSSLContext - util.HAS_SNI = HAS_SNI - util.ssl_.HAS_SNI = HAS_SNI - util.IS_PYOPENSSL = True - util.ssl_.IS_PYOPENSSL = True - - -def extract_from_urllib3(): - "Undo monkey-patching by :func:`inject_into_urllib3`." - - util.SSLContext = orig_util_SSLContext - util.ssl_.SSLContext = orig_util_SSLContext - util.HAS_SNI = orig_util_HAS_SNI - util.ssl_.HAS_SNI = orig_util_HAS_SNI - util.IS_PYOPENSSL = False - util.ssl_.IS_PYOPENSSL = False - - -def _validate_dependencies_met(): - """ - Verifies that PyOpenSSL's package-level dependencies have been met. - Throws `ImportError` if they are not met. - """ - # Method added in `cryptography==1.1`; not available in older versions - from cryptography.x509.extensions import Extensions - - if getattr(Extensions, "get_extension_for_class", None) is None: - raise ImportError( - "'cryptography' module missing required functionality. " - "Try upgrading to v1.3.4 or newer." - ) - - # pyOpenSSL 0.14 and above use cryptography for OpenSSL bindings. The _x509 - # attribute is only present on those versions. - from OpenSSL.crypto import X509 - - x509 = X509() - if getattr(x509, "_x509", None) is None: - raise ImportError( - "'pyOpenSSL' module missing required functionality. " - "Try upgrading to v0.14 or newer." - ) - - -def _dnsname_to_stdlib(name): - """ - Converts a dNSName SubjectAlternativeName field to the form used by the - standard library on the given Python version. - - Cryptography produces a dNSName as a unicode string that was idna-decoded - from ASCII bytes. We need to idna-encode that string to get it back, and - then on Python 3 we also need to convert to unicode via UTF-8 (the stdlib - uses PyUnicode_FromStringAndSize on it, which decodes via UTF-8). - - If the name cannot be idna-encoded then we return None signalling that - the name given should be skipped. - """ - - def idna_encode(name): - """ - Borrowed wholesale from the Python Cryptography Project. It turns out - that we can't just safely call `idna.encode`: it can explode for - wildcard names. This avoids that problem. - """ - import idna - - try: - for prefix in [u"*.", u"."]: - if name.startswith(prefix): - name = name[len(prefix) :] - return prefix.encode("ascii") + idna.encode(name) - return idna.encode(name) - except idna.core.IDNAError: - return None - - # Don't send IPv6 addresses through the IDNA encoder. - if ":" in name: - return name - - name = idna_encode(name) - if name is None: - return None - elif sys.version_info >= (3, 0): - name = name.decode("utf-8") - return name - - -def get_subj_alt_name(peer_cert): - """ - Given an PyOpenSSL certificate, provides all the subject alternative names. - """ - # Pass the cert to cryptography, which has much better APIs for this. - if hasattr(peer_cert, "to_cryptography"): - cert = peer_cert.to_cryptography() - else: - # This is technically using private APIs, but should work across all - # relevant versions before PyOpenSSL got a proper API for this. - cert = _Certificate(openssl_backend, peer_cert._x509) - - # We want to find the SAN extension. Ask Cryptography to locate it (it's - # faster than looping in Python) - try: - ext = cert.extensions.get_extension_for_class(x509.SubjectAlternativeName).value - except x509.ExtensionNotFound: - # No such extension, return the empty list. - return [] - except ( - x509.DuplicateExtension, - UnsupportedExtension, - x509.UnsupportedGeneralNameType, - UnicodeError, - ) as e: - # A problem has been found with the quality of the certificate. Assume - # no SAN field is present. - log.warning( - "A problem was encountered with the certificate that prevented " - "urllib3 from finding the SubjectAlternativeName field. This can " - "affect certificate validation. The error was %s", - e, - ) - return [] - - # We want to return dNSName and iPAddress fields. We need to cast the IPs - # back to strings because the match_hostname function wants them as - # strings. - # Sadly the DNS names need to be idna encoded and then, on Python 3, UTF-8 - # decoded. This is pretty frustrating, but that's what the standard library - # does with certificates, and so we need to attempt to do the same. - # We also want to skip over names which cannot be idna encoded. - names = [ - ("DNS", name) - for name in map(_dnsname_to_stdlib, ext.get_values_for_type(x509.DNSName)) - if name is not None - ] - names.extend( - ("IP Address", str(name)) for name in ext.get_values_for_type(x509.IPAddress) - ) - - return names - - -class WrappedSocket(object): - """API-compatibility wrapper for Python OpenSSL's Connection-class. - - Note: _makefile_refs, _drop() and _reuse() are needed for the garbage - collector of pypy. - """ - - def __init__(self, connection, socket, suppress_ragged_eofs=True): - self.connection = connection - self.socket = socket - self.suppress_ragged_eofs = suppress_ragged_eofs - self._makefile_refs = 0 - self._closed = False - - def fileno(self): - return self.socket.fileno() - - # Copy-pasted from Python 3.5 source code - def _decref_socketios(self): - if self._makefile_refs > 0: - self._makefile_refs -= 1 - if self._closed: - self.close() - - def recv(self, *args, **kwargs): - try: - data = self.connection.recv(*args, **kwargs) - except OpenSSL.SSL.SysCallError as e: - if self.suppress_ragged_eofs and e.args == (-1, "Unexpected EOF"): - return b"" - else: - raise SocketError(str(e)) - except OpenSSL.SSL.ZeroReturnError: - if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN: - return b"" - else: - raise - except OpenSSL.SSL.WantReadError: - if not util.wait_for_read(self.socket, self.socket.gettimeout()): - raise timeout("The read operation timed out") - else: - return self.recv(*args, **kwargs) - - # TLS 1.3 post-handshake authentication - except OpenSSL.SSL.Error as e: - raise ssl.SSLError("read error: %r" % e) - else: - return data - - def recv_into(self, *args, **kwargs): - try: - return self.connection.recv_into(*args, **kwargs) - except OpenSSL.SSL.SysCallError as e: - if self.suppress_ragged_eofs and e.args == (-1, "Unexpected EOF"): - return 0 - else: - raise SocketError(str(e)) - except OpenSSL.SSL.ZeroReturnError: - if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN: - return 0 - else: - raise - except OpenSSL.SSL.WantReadError: - if not util.wait_for_read(self.socket, self.socket.gettimeout()): - raise timeout("The read operation timed out") - else: - return self.recv_into(*args, **kwargs) - - # TLS 1.3 post-handshake authentication - except OpenSSL.SSL.Error as e: - raise ssl.SSLError("read error: %r" % e) - - def settimeout(self, timeout): - return self.socket.settimeout(timeout) - - def _send_until_done(self, data): - while True: - try: - return self.connection.send(data) - except OpenSSL.SSL.WantWriteError: - if not util.wait_for_write(self.socket, self.socket.gettimeout()): - raise timeout() - continue - except OpenSSL.SSL.SysCallError as e: - raise SocketError(str(e)) - - def sendall(self, data): - total_sent = 0 - while total_sent < len(data): - sent = self._send_until_done( - data[total_sent : total_sent + SSL_WRITE_BLOCKSIZE] - ) - total_sent += sent - - def shutdown(self): - # FIXME rethrow compatible exceptions should we ever use this - self.connection.shutdown() - - def close(self): - if self._makefile_refs < 1: - try: - self._closed = True - return self.connection.close() - except OpenSSL.SSL.Error: - return - else: - self._makefile_refs -= 1 - - def getpeercert(self, binary_form=False): - x509 = self.connection.get_peer_certificate() - - if not x509: - return x509 - - if binary_form: - return OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_ASN1, x509) - - return { - "subject": ((("commonName", x509.get_subject().CN),),), - "subjectAltName": get_subj_alt_name(x509), - } - - def version(self): - return self.connection.get_protocol_version_name() - - def _reuse(self): - self._makefile_refs += 1 - - def _drop(self): - if self._makefile_refs < 1: - self.close() - else: - self._makefile_refs -= 1 - - -if _fileobject: # Platform-specific: Python 2 - - def makefile(self, mode, bufsize=-1): - self._makefile_refs += 1 - return _fileobject(self, mode, bufsize, close=True) - - -else: # Platform-specific: Python 3 - makefile = backport_makefile - -WrappedSocket.makefile = makefile - - -class PyOpenSSLContext(object): - """ - I am a wrapper class for the PyOpenSSL ``Context`` object. I am responsible - for translating the interface of the standard library ``SSLContext`` object - to calls into PyOpenSSL. - """ - - def __init__(self, protocol): - self.protocol = _openssl_versions[protocol] - self._ctx = OpenSSL.SSL.Context(self.protocol) - self._options = 0 - self.check_hostname = False - - @property - def options(self): - return self._options - - @options.setter - def options(self, value): - self._options = value - self._ctx.set_options(value) - - @property - def verify_mode(self): - return _openssl_to_stdlib_verify[self._ctx.get_verify_mode()] - - @verify_mode.setter - def verify_mode(self, value): - self._ctx.set_verify(_stdlib_to_openssl_verify[value], _verify_callback) - - def set_default_verify_paths(self): - self._ctx.set_default_verify_paths() - - def set_ciphers(self, ciphers): - if isinstance(ciphers, six.text_type): - ciphers = ciphers.encode("utf-8") - self._ctx.set_cipher_list(ciphers) - - def load_verify_locations(self, cafile=None, capath=None, cadata=None): - if cafile is not None: - cafile = cafile.encode("utf-8") - if capath is not None: - capath = capath.encode("utf-8") - try: - self._ctx.load_verify_locations(cafile, capath) - if cadata is not None: - self._ctx.load_verify_locations(BytesIO(cadata)) - except OpenSSL.SSL.Error as e: - raise ssl.SSLError("unable to load trusted certificates: %r" % e) - - def load_cert_chain(self, certfile, keyfile=None, password=None): - self._ctx.use_certificate_chain_file(certfile) - if password is not None: - if not isinstance(password, six.binary_type): - password = password.encode("utf-8") - self._ctx.set_passwd_cb(lambda *_: password) - self._ctx.use_privatekey_file(keyfile or certfile) - - def set_alpn_protocols(self, protocols): - protocols = [six.ensure_binary(p) for p in protocols] - return self._ctx.set_alpn_protos(protocols) - - def wrap_socket( - self, - sock, - server_side=False, - do_handshake_on_connect=True, - suppress_ragged_eofs=True, - server_hostname=None, - ): - cnx = OpenSSL.SSL.Connection(self._ctx, sock) - - if isinstance(server_hostname, six.text_type): # Platform-specific: Python 3 - server_hostname = server_hostname.encode("utf-8") - - if server_hostname is not None: - cnx.set_tlsext_host_name(server_hostname) - - cnx.set_connect_state() - - while True: - try: - cnx.do_handshake() - except OpenSSL.SSL.WantReadError: - if not util.wait_for_read(sock, sock.gettimeout()): - raise timeout("select timed out") - continue - except OpenSSL.SSL.Error as e: - raise ssl.SSLError("bad handshake: %r" % e) - break - - return WrappedSocket(cnx, sock) - - -def _verify_callback(cnx, x509, err_no, err_depth, return_code): - return err_no == 0 diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/contrib/securetransport.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/contrib/securetransport.py deleted file mode 100644 index 554c015fed..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/contrib/securetransport.py +++ /dev/null @@ -1,922 +0,0 @@ -""" -SecureTranport support for urllib3 via ctypes. - -This makes platform-native TLS available to urllib3 users on macOS without the -use of a compiler. This is an important feature because the Python Package -Index is moving to become a TLSv1.2-or-higher server, and the default OpenSSL -that ships with macOS is not capable of doing TLSv1.2. The only way to resolve -this is to give macOS users an alternative solution to the problem, and that -solution is to use SecureTransport. - -We use ctypes here because this solution must not require a compiler. That's -because pip is not allowed to require a compiler either. - -This is not intended to be a seriously long-term solution to this problem. -The hope is that PEP 543 will eventually solve this issue for us, at which -point we can retire this contrib module. But in the short term, we need to -solve the impending tire fire that is Python on Mac without this kind of -contrib module. So...here we are. - -To use this module, simply import and inject it:: - - import urllib3.contrib.securetransport - urllib3.contrib.securetransport.inject_into_urllib3() - -Happy TLSing! - -This code is a bastardised version of the code found in Will Bond's oscrypto -library. An enormous debt is owed to him for blazing this trail for us. For -that reason, this code should be considered to be covered both by urllib3's -license and by oscrypto's: - -.. code-block:: - - Copyright (c) 2015-2016 Will Bond - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -""" -from __future__ import absolute_import - -import contextlib -import ctypes -import errno -import os.path -import shutil -import socket -import ssl -import struct -import threading -import weakref - -import six - -from .. import util -from ..util.ssl_ import PROTOCOL_TLS_CLIENT -from ._securetransport.bindings import CoreFoundation, Security, SecurityConst -from ._securetransport.low_level import ( - _assert_no_error, - _build_tls_unknown_ca_alert, - _cert_array_from_pem, - _create_cfstring_array, - _load_client_cert_chain, - _temporary_keychain, -) - -try: # Platform-specific: Python 2 - from socket import _fileobject -except ImportError: # Platform-specific: Python 3 - _fileobject = None - from ..packages.backports.makefile import backport_makefile - -__all__ = ["inject_into_urllib3", "extract_from_urllib3"] - -# SNI always works -HAS_SNI = True - -orig_util_HAS_SNI = util.HAS_SNI -orig_util_SSLContext = util.ssl_.SSLContext - -# This dictionary is used by the read callback to obtain a handle to the -# calling wrapped socket. This is a pretty silly approach, but for now it'll -# do. I feel like I should be able to smuggle a handle to the wrapped socket -# directly in the SSLConnectionRef, but for now this approach will work I -# guess. -# -# We need to lock around this structure for inserts, but we don't do it for -# reads/writes in the callbacks. The reasoning here goes as follows: -# -# 1. It is not possible to call into the callbacks before the dictionary is -# populated, so once in the callback the id must be in the dictionary. -# 2. The callbacks don't mutate the dictionary, they only read from it, and -# so cannot conflict with any of the insertions. -# -# This is good: if we had to lock in the callbacks we'd drastically slow down -# the performance of this code. -_connection_refs = weakref.WeakValueDictionary() -_connection_ref_lock = threading.Lock() - -# Limit writes to 16kB. This is OpenSSL's limit, but we'll cargo-cult it over -# for no better reason than we need *a* limit, and this one is right there. -SSL_WRITE_BLOCKSIZE = 16384 - -# This is our equivalent of util.ssl_.DEFAULT_CIPHERS, but expanded out to -# individual cipher suites. We need to do this because this is how -# SecureTransport wants them. -CIPHER_SUITES = [ - SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, - SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, - SecurityConst.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - SecurityConst.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - SecurityConst.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, - SecurityConst.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, - SecurityConst.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, - SecurityConst.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, - SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, - SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, - SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, - SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, - SecurityConst.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, - SecurityConst.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, - SecurityConst.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, - SecurityConst.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, - SecurityConst.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, - SecurityConst.TLS_DHE_RSA_WITH_AES_256_CBC_SHA, - SecurityConst.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, - SecurityConst.TLS_DHE_RSA_WITH_AES_128_CBC_SHA, - SecurityConst.TLS_AES_256_GCM_SHA384, - SecurityConst.TLS_AES_128_GCM_SHA256, - SecurityConst.TLS_RSA_WITH_AES_256_GCM_SHA384, - SecurityConst.TLS_RSA_WITH_AES_128_GCM_SHA256, - SecurityConst.TLS_AES_128_CCM_8_SHA256, - SecurityConst.TLS_AES_128_CCM_SHA256, - SecurityConst.TLS_RSA_WITH_AES_256_CBC_SHA256, - SecurityConst.TLS_RSA_WITH_AES_128_CBC_SHA256, - SecurityConst.TLS_RSA_WITH_AES_256_CBC_SHA, - SecurityConst.TLS_RSA_WITH_AES_128_CBC_SHA, -] - -# Basically this is simple: for PROTOCOL_SSLv23 we turn it into a low of -# TLSv1 and a high of TLSv1.2. For everything else, we pin to that version. -# TLSv1 to 1.2 are supported on macOS 10.8+ -_protocol_to_min_max = { - util.PROTOCOL_TLS: (SecurityConst.kTLSProtocol1, SecurityConst.kTLSProtocol12), - PROTOCOL_TLS_CLIENT: (SecurityConst.kTLSProtocol1, SecurityConst.kTLSProtocol12), -} - -if hasattr(ssl, "PROTOCOL_SSLv2"): - _protocol_to_min_max[ssl.PROTOCOL_SSLv2] = ( - SecurityConst.kSSLProtocol2, - SecurityConst.kSSLProtocol2, - ) -if hasattr(ssl, "PROTOCOL_SSLv3"): - _protocol_to_min_max[ssl.PROTOCOL_SSLv3] = ( - SecurityConst.kSSLProtocol3, - SecurityConst.kSSLProtocol3, - ) -if hasattr(ssl, "PROTOCOL_TLSv1"): - _protocol_to_min_max[ssl.PROTOCOL_TLSv1] = ( - SecurityConst.kTLSProtocol1, - SecurityConst.kTLSProtocol1, - ) -if hasattr(ssl, "PROTOCOL_TLSv1_1"): - _protocol_to_min_max[ssl.PROTOCOL_TLSv1_1] = ( - SecurityConst.kTLSProtocol11, - SecurityConst.kTLSProtocol11, - ) -if hasattr(ssl, "PROTOCOL_TLSv1_2"): - _protocol_to_min_max[ssl.PROTOCOL_TLSv1_2] = ( - SecurityConst.kTLSProtocol12, - SecurityConst.kTLSProtocol12, - ) - - -def inject_into_urllib3(): - """ - Monkey-patch urllib3 with SecureTransport-backed SSL-support. - """ - util.SSLContext = SecureTransportContext - util.ssl_.SSLContext = SecureTransportContext - util.HAS_SNI = HAS_SNI - util.ssl_.HAS_SNI = HAS_SNI - util.IS_SECURETRANSPORT = True - util.ssl_.IS_SECURETRANSPORT = True - - -def extract_from_urllib3(): - """ - Undo monkey-patching by :func:`inject_into_urllib3`. - """ - util.SSLContext = orig_util_SSLContext - util.ssl_.SSLContext = orig_util_SSLContext - util.HAS_SNI = orig_util_HAS_SNI - util.ssl_.HAS_SNI = orig_util_HAS_SNI - util.IS_SECURETRANSPORT = False - util.ssl_.IS_SECURETRANSPORT = False - - -def _read_callback(connection_id, data_buffer, data_length_pointer): - """ - SecureTransport read callback. This is called by ST to request that data - be returned from the socket. - """ - wrapped_socket = None - try: - wrapped_socket = _connection_refs.get(connection_id) - if wrapped_socket is None: - return SecurityConst.errSSLInternal - base_socket = wrapped_socket.socket - - requested_length = data_length_pointer[0] - - timeout = wrapped_socket.gettimeout() - error = None - read_count = 0 - - try: - while read_count < requested_length: - if timeout is None or timeout >= 0: - if not util.wait_for_read(base_socket, timeout): - raise socket.error(errno.EAGAIN, "timed out") - - remaining = requested_length - read_count - buffer = (ctypes.c_char * remaining).from_address( - data_buffer + read_count - ) - chunk_size = base_socket.recv_into(buffer, remaining) - read_count += chunk_size - if not chunk_size: - if not read_count: - return SecurityConst.errSSLClosedGraceful - break - except (socket.error) as e: - error = e.errno - - if error is not None and error != errno.EAGAIN: - data_length_pointer[0] = read_count - if error == errno.ECONNRESET or error == errno.EPIPE: - return SecurityConst.errSSLClosedAbort - raise - - data_length_pointer[0] = read_count - - if read_count != requested_length: - return SecurityConst.errSSLWouldBlock - - return 0 - except Exception as e: - if wrapped_socket is not None: - wrapped_socket._exception = e - return SecurityConst.errSSLInternal - - -def _write_callback(connection_id, data_buffer, data_length_pointer): - """ - SecureTransport write callback. This is called by ST to request that data - actually be sent on the network. - """ - wrapped_socket = None - try: - wrapped_socket = _connection_refs.get(connection_id) - if wrapped_socket is None: - return SecurityConst.errSSLInternal - base_socket = wrapped_socket.socket - - bytes_to_write = data_length_pointer[0] - data = ctypes.string_at(data_buffer, bytes_to_write) - - timeout = wrapped_socket.gettimeout() - error = None - sent = 0 - - try: - while sent < bytes_to_write: - if timeout is None or timeout >= 0: - if not util.wait_for_write(base_socket, timeout): - raise socket.error(errno.EAGAIN, "timed out") - chunk_sent = base_socket.send(data) - sent += chunk_sent - - # This has some needless copying here, but I'm not sure there's - # much value in optimising this data path. - data = data[chunk_sent:] - except (socket.error) as e: - error = e.errno - - if error is not None and error != errno.EAGAIN: - data_length_pointer[0] = sent - if error == errno.ECONNRESET or error == errno.EPIPE: - return SecurityConst.errSSLClosedAbort - raise - - data_length_pointer[0] = sent - - if sent != bytes_to_write: - return SecurityConst.errSSLWouldBlock - - return 0 - except Exception as e: - if wrapped_socket is not None: - wrapped_socket._exception = e - return SecurityConst.errSSLInternal - - -# We need to keep these two objects references alive: if they get GC'd while -# in use then SecureTransport could attempt to call a function that is in freed -# memory. That would be...uh...bad. Yeah, that's the word. Bad. -_read_callback_pointer = Security.SSLReadFunc(_read_callback) -_write_callback_pointer = Security.SSLWriteFunc(_write_callback) - - -class WrappedSocket(object): - """ - API-compatibility wrapper for Python's OpenSSL wrapped socket object. - - Note: _makefile_refs, _drop(), and _reuse() are needed for the garbage - collector of PyPy. - """ - - def __init__(self, socket): - self.socket = socket - self.context = None - self._makefile_refs = 0 - self._closed = False - self._exception = None - self._keychain = None - self._keychain_dir = None - self._client_cert_chain = None - - # We save off the previously-configured timeout and then set it to - # zero. This is done because we use select and friends to handle the - # timeouts, but if we leave the timeout set on the lower socket then - # Python will "kindly" call select on that socket again for us. Avoid - # that by forcing the timeout to zero. - self._timeout = self.socket.gettimeout() - self.socket.settimeout(0) - - @contextlib.contextmanager - def _raise_on_error(self): - """ - A context manager that can be used to wrap calls that do I/O from - SecureTransport. If any of the I/O callbacks hit an exception, this - context manager will correctly propagate the exception after the fact. - This avoids silently swallowing those exceptions. - - It also correctly forces the socket closed. - """ - self._exception = None - - # We explicitly don't catch around this yield because in the unlikely - # event that an exception was hit in the block we don't want to swallow - # it. - yield - if self._exception is not None: - exception, self._exception = self._exception, None - self.close() - raise exception - - def _set_ciphers(self): - """ - Sets up the allowed ciphers. By default this matches the set in - util.ssl_.DEFAULT_CIPHERS, at least as supported by macOS. This is done - custom and doesn't allow changing at this time, mostly because parsing - OpenSSL cipher strings is going to be a freaking nightmare. - """ - ciphers = (Security.SSLCipherSuite * len(CIPHER_SUITES))(*CIPHER_SUITES) - result = Security.SSLSetEnabledCiphers( - self.context, ciphers, len(CIPHER_SUITES) - ) - _assert_no_error(result) - - def _set_alpn_protocols(self, protocols): - """ - Sets up the ALPN protocols on the context. - """ - if not protocols: - return - protocols_arr = _create_cfstring_array(protocols) - try: - result = Security.SSLSetALPNProtocols(self.context, protocols_arr) - _assert_no_error(result) - finally: - CoreFoundation.CFRelease(protocols_arr) - - def _custom_validate(self, verify, trust_bundle): - """ - Called when we have set custom validation. We do this in two cases: - first, when cert validation is entirely disabled; and second, when - using a custom trust DB. - Raises an SSLError if the connection is not trusted. - """ - # If we disabled cert validation, just say: cool. - if not verify: - return - - successes = ( - SecurityConst.kSecTrustResultUnspecified, - SecurityConst.kSecTrustResultProceed, - ) - try: - trust_result = self._evaluate_trust(trust_bundle) - if trust_result in successes: - return - reason = "error code: %d" % (trust_result,) - except Exception as e: - # Do not trust on error - reason = "exception: %r" % (e,) - - # SecureTransport does not send an alert nor shuts down the connection. - rec = _build_tls_unknown_ca_alert(self.version()) - self.socket.sendall(rec) - # close the connection immediately - # l_onoff = 1, activate linger - # l_linger = 0, linger for 0 seoncds - opts = struct.pack("ii", 1, 0) - self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, opts) - self.close() - raise ssl.SSLError("certificate verify failed, %s" % reason) - - def _evaluate_trust(self, trust_bundle): - # We want data in memory, so load it up. - if os.path.isfile(trust_bundle): - with open(trust_bundle, "rb") as f: - trust_bundle = f.read() - - cert_array = None - trust = Security.SecTrustRef() - - try: - # Get a CFArray that contains the certs we want. - cert_array = _cert_array_from_pem(trust_bundle) - - # Ok, now the hard part. We want to get the SecTrustRef that ST has - # created for this connection, shove our CAs into it, tell ST to - # ignore everything else it knows, and then ask if it can build a - # chain. This is a buuuunch of code. - result = Security.SSLCopyPeerTrust(self.context, ctypes.byref(trust)) - _assert_no_error(result) - if not trust: - raise ssl.SSLError("Failed to copy trust reference") - - result = Security.SecTrustSetAnchorCertificates(trust, cert_array) - _assert_no_error(result) - - result = Security.SecTrustSetAnchorCertificatesOnly(trust, True) - _assert_no_error(result) - - trust_result = Security.SecTrustResultType() - result = Security.SecTrustEvaluate(trust, ctypes.byref(trust_result)) - _assert_no_error(result) - finally: - if trust: - CoreFoundation.CFRelease(trust) - - if cert_array is not None: - CoreFoundation.CFRelease(cert_array) - - return trust_result.value - - def handshake( - self, - server_hostname, - verify, - trust_bundle, - min_version, - max_version, - client_cert, - client_key, - client_key_passphrase, - alpn_protocols, - ): - """ - Actually performs the TLS handshake. This is run automatically by - wrapped socket, and shouldn't be needed in user code. - """ - # First, we do the initial bits of connection setup. We need to create - # a context, set its I/O funcs, and set the connection reference. - self.context = Security.SSLCreateContext( - None, SecurityConst.kSSLClientSide, SecurityConst.kSSLStreamType - ) - result = Security.SSLSetIOFuncs( - self.context, _read_callback_pointer, _write_callback_pointer - ) - _assert_no_error(result) - - # Here we need to compute the handle to use. We do this by taking the - # id of self modulo 2**31 - 1. If this is already in the dictionary, we - # just keep incrementing by one until we find a free space. - with _connection_ref_lock: - handle = id(self) % 2147483647 - while handle in _connection_refs: - handle = (handle + 1) % 2147483647 - _connection_refs[handle] = self - - result = Security.SSLSetConnection(self.context, handle) - _assert_no_error(result) - - # If we have a server hostname, we should set that too. - if server_hostname: - if not isinstance(server_hostname, bytes): - server_hostname = server_hostname.encode("utf-8") - - result = Security.SSLSetPeerDomainName( - self.context, server_hostname, len(server_hostname) - ) - _assert_no_error(result) - - # Setup the ciphers. - self._set_ciphers() - - # Setup the ALPN protocols. - self._set_alpn_protocols(alpn_protocols) - - # Set the minimum and maximum TLS versions. - result = Security.SSLSetProtocolVersionMin(self.context, min_version) - _assert_no_error(result) - - result = Security.SSLSetProtocolVersionMax(self.context, max_version) - _assert_no_error(result) - - # If there's a trust DB, we need to use it. We do that by telling - # SecureTransport to break on server auth. We also do that if we don't - # want to validate the certs at all: we just won't actually do any - # authing in that case. - if not verify or trust_bundle is not None: - result = Security.SSLSetSessionOption( - self.context, SecurityConst.kSSLSessionOptionBreakOnServerAuth, True - ) - _assert_no_error(result) - - # If there's a client cert, we need to use it. - if client_cert: - self._keychain, self._keychain_dir = _temporary_keychain() - self._client_cert_chain = _load_client_cert_chain( - self._keychain, client_cert, client_key - ) - result = Security.SSLSetCertificate(self.context, self._client_cert_chain) - _assert_no_error(result) - - while True: - with self._raise_on_error(): - result = Security.SSLHandshake(self.context) - - if result == SecurityConst.errSSLWouldBlock: - raise socket.timeout("handshake timed out") - elif result == SecurityConst.errSSLServerAuthCompleted: - self._custom_validate(verify, trust_bundle) - continue - else: - _assert_no_error(result) - break - - def fileno(self): - return self.socket.fileno() - - # Copy-pasted from Python 3.5 source code - def _decref_socketios(self): - if self._makefile_refs > 0: - self._makefile_refs -= 1 - if self._closed: - self.close() - - def recv(self, bufsiz): - buffer = ctypes.create_string_buffer(bufsiz) - bytes_read = self.recv_into(buffer, bufsiz) - data = buffer[:bytes_read] - return data - - def recv_into(self, buffer, nbytes=None): - # Read short on EOF. - if self._closed: - return 0 - - if nbytes is None: - nbytes = len(buffer) - - buffer = (ctypes.c_char * nbytes).from_buffer(buffer) - processed_bytes = ctypes.c_size_t(0) - - with self._raise_on_error(): - result = Security.SSLRead( - self.context, buffer, nbytes, ctypes.byref(processed_bytes) - ) - - # There are some result codes that we want to treat as "not always - # errors". Specifically, those are errSSLWouldBlock, - # errSSLClosedGraceful, and errSSLClosedNoNotify. - if result == SecurityConst.errSSLWouldBlock: - # If we didn't process any bytes, then this was just a time out. - # However, we can get errSSLWouldBlock in situations when we *did* - # read some data, and in those cases we should just read "short" - # and return. - if processed_bytes.value == 0: - # Timed out, no data read. - raise socket.timeout("recv timed out") - elif result in ( - SecurityConst.errSSLClosedGraceful, - SecurityConst.errSSLClosedNoNotify, - ): - # The remote peer has closed this connection. We should do so as - # well. Note that we don't actually return here because in - # principle this could actually be fired along with return data. - # It's unlikely though. - self.close() - else: - _assert_no_error(result) - - # Ok, we read and probably succeeded. We should return whatever data - # was actually read. - return processed_bytes.value - - def settimeout(self, timeout): - self._timeout = timeout - - def gettimeout(self): - return self._timeout - - def send(self, data): - processed_bytes = ctypes.c_size_t(0) - - with self._raise_on_error(): - result = Security.SSLWrite( - self.context, data, len(data), ctypes.byref(processed_bytes) - ) - - if result == SecurityConst.errSSLWouldBlock and processed_bytes.value == 0: - # Timed out - raise socket.timeout("send timed out") - else: - _assert_no_error(result) - - # We sent, and probably succeeded. Tell them how much we sent. - return processed_bytes.value - - def sendall(self, data): - total_sent = 0 - while total_sent < len(data): - sent = self.send(data[total_sent : total_sent + SSL_WRITE_BLOCKSIZE]) - total_sent += sent - - def shutdown(self): - with self._raise_on_error(): - Security.SSLClose(self.context) - - def close(self): - # TODO: should I do clean shutdown here? Do I have to? - if self._makefile_refs < 1: - self._closed = True - if self.context: - CoreFoundation.CFRelease(self.context) - self.context = None - if self._client_cert_chain: - CoreFoundation.CFRelease(self._client_cert_chain) - self._client_cert_chain = None - if self._keychain: - Security.SecKeychainDelete(self._keychain) - CoreFoundation.CFRelease(self._keychain) - shutil.rmtree(self._keychain_dir) - self._keychain = self._keychain_dir = None - return self.socket.close() - else: - self._makefile_refs -= 1 - - def getpeercert(self, binary_form=False): - # Urgh, annoying. - # - # Here's how we do this: - # - # 1. Call SSLCopyPeerTrust to get hold of the trust object for this - # connection. - # 2. Call SecTrustGetCertificateAtIndex for index 0 to get the leaf. - # 3. To get the CN, call SecCertificateCopyCommonName and process that - # string so that it's of the appropriate type. - # 4. To get the SAN, we need to do something a bit more complex: - # a. Call SecCertificateCopyValues to get the data, requesting - # kSecOIDSubjectAltName. - # b. Mess about with this dictionary to try to get the SANs out. - # - # This is gross. Really gross. It's going to be a few hundred LoC extra - # just to repeat something that SecureTransport can *already do*. So my - # operating assumption at this time is that what we want to do is - # instead to just flag to urllib3 that it shouldn't do its own hostname - # validation when using SecureTransport. - if not binary_form: - raise ValueError("SecureTransport only supports dumping binary certs") - trust = Security.SecTrustRef() - certdata = None - der_bytes = None - - try: - # Grab the trust store. - result = Security.SSLCopyPeerTrust(self.context, ctypes.byref(trust)) - _assert_no_error(result) - if not trust: - # Probably we haven't done the handshake yet. No biggie. - return None - - cert_count = Security.SecTrustGetCertificateCount(trust) - if not cert_count: - # Also a case that might happen if we haven't handshaked. - # Handshook? Handshaken? - return None - - leaf = Security.SecTrustGetCertificateAtIndex(trust, 0) - assert leaf - - # Ok, now we want the DER bytes. - certdata = Security.SecCertificateCopyData(leaf) - assert certdata - - data_length = CoreFoundation.CFDataGetLength(certdata) - data_buffer = CoreFoundation.CFDataGetBytePtr(certdata) - der_bytes = ctypes.string_at(data_buffer, data_length) - finally: - if certdata: - CoreFoundation.CFRelease(certdata) - if trust: - CoreFoundation.CFRelease(trust) - - return der_bytes - - def version(self): - protocol = Security.SSLProtocol() - result = Security.SSLGetNegotiatedProtocolVersion( - self.context, ctypes.byref(protocol) - ) - _assert_no_error(result) - if protocol.value == SecurityConst.kTLSProtocol13: - raise ssl.SSLError("SecureTransport does not support TLS 1.3") - elif protocol.value == SecurityConst.kTLSProtocol12: - return "TLSv1.2" - elif protocol.value == SecurityConst.kTLSProtocol11: - return "TLSv1.1" - elif protocol.value == SecurityConst.kTLSProtocol1: - return "TLSv1" - elif protocol.value == SecurityConst.kSSLProtocol3: - return "SSLv3" - elif protocol.value == SecurityConst.kSSLProtocol2: - return "SSLv2" - else: - raise ssl.SSLError("Unknown TLS version: %r" % protocol) - - def _reuse(self): - self._makefile_refs += 1 - - def _drop(self): - if self._makefile_refs < 1: - self.close() - else: - self._makefile_refs -= 1 - - -if _fileobject: # Platform-specific: Python 2 - - def makefile(self, mode, bufsize=-1): - self._makefile_refs += 1 - return _fileobject(self, mode, bufsize, close=True) - - -else: # Platform-specific: Python 3 - - def makefile(self, mode="r", buffering=None, *args, **kwargs): - # We disable buffering with SecureTransport because it conflicts with - # the buffering that ST does internally (see issue #1153 for more). - buffering = 0 - return backport_makefile(self, mode, buffering, *args, **kwargs) - - -WrappedSocket.makefile = makefile - - -class SecureTransportContext(object): - """ - I am a wrapper class for the SecureTransport library, to translate the - interface of the standard library ``SSLContext`` object to calls into - SecureTransport. - """ - - def __init__(self, protocol): - self._min_version, self._max_version = _protocol_to_min_max[protocol] - self._options = 0 - self._verify = False - self._trust_bundle = None - self._client_cert = None - self._client_key = None - self._client_key_passphrase = None - self._alpn_protocols = None - - @property - def check_hostname(self): - """ - SecureTransport cannot have its hostname checking disabled. For more, - see the comment on getpeercert() in this file. - """ - return True - - @check_hostname.setter - def check_hostname(self, value): - """ - SecureTransport cannot have its hostname checking disabled. For more, - see the comment on getpeercert() in this file. - """ - pass - - @property - def options(self): - # TODO: Well, crap. - # - # So this is the bit of the code that is the most likely to cause us - # trouble. Essentially we need to enumerate all of the SSL options that - # users might want to use and try to see if we can sensibly translate - # them, or whether we should just ignore them. - return self._options - - @options.setter - def options(self, value): - # TODO: Update in line with above. - self._options = value - - @property - def verify_mode(self): - return ssl.CERT_REQUIRED if self._verify else ssl.CERT_NONE - - @verify_mode.setter - def verify_mode(self, value): - self._verify = True if value == ssl.CERT_REQUIRED else False - - def set_default_verify_paths(self): - # So, this has to do something a bit weird. Specifically, what it does - # is nothing. - # - # This means that, if we had previously had load_verify_locations - # called, this does not undo that. We need to do that because it turns - # out that the rest of the urllib3 code will attempt to load the - # default verify paths if it hasn't been told about any paths, even if - # the context itself was sometime earlier. We resolve that by just - # ignoring it. - pass - - def load_default_certs(self): - return self.set_default_verify_paths() - - def set_ciphers(self, ciphers): - # For now, we just require the default cipher string. - if ciphers != util.ssl_.DEFAULT_CIPHERS: - raise ValueError("SecureTransport doesn't support custom cipher strings") - - def load_verify_locations(self, cafile=None, capath=None, cadata=None): - # OK, we only really support cadata and cafile. - if capath is not None: - raise ValueError("SecureTransport does not support cert directories") - - # Raise if cafile does not exist. - if cafile is not None: - with open(cafile): - pass - - self._trust_bundle = cafile or cadata - - def load_cert_chain(self, certfile, keyfile=None, password=None): - self._client_cert = certfile - self._client_key = keyfile - self._client_cert_passphrase = password - - def set_alpn_protocols(self, protocols): - """ - Sets the ALPN protocols that will later be set on the context. - - Raises a NotImplementedError if ALPN is not supported. - """ - if not hasattr(Security, "SSLSetALPNProtocols"): - raise NotImplementedError( - "SecureTransport supports ALPN only in macOS 10.12+" - ) - self._alpn_protocols = [six.ensure_binary(p) for p in protocols] - - def wrap_socket( - self, - sock, - server_side=False, - do_handshake_on_connect=True, - suppress_ragged_eofs=True, - server_hostname=None, - ): - # So, what do we do here? Firstly, we assert some properties. This is a - # stripped down shim, so there is some functionality we don't support. - # See PEP 543 for the real deal. - assert not server_side - assert do_handshake_on_connect - assert suppress_ragged_eofs - - # Ok, we're good to go. Now we want to create the wrapped socket object - # and store it in the appropriate place. - wrapped_socket = WrappedSocket(sock) - - # Now we can handshake - wrapped_socket.handshake( - server_hostname, - self._verify, - self._trust_bundle, - self._min_version, - self._max_version, - self._client_cert, - self._client_key, - self._client_key_passphrase, - self._alpn_protocols, - ) - return wrapped_socket diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/contrib/socks.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/contrib/socks.py deleted file mode 100644 index c326e80dd1..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/contrib/socks.py +++ /dev/null @@ -1,216 +0,0 @@ -# -*- coding: utf-8 -*- -""" -This module contains provisional support for SOCKS proxies from within -urllib3. This module supports SOCKS4, SOCKS4A (an extension of SOCKS4), and -SOCKS5. To enable its functionality, either install PySocks or install this -module with the ``socks`` extra. - -The SOCKS implementation supports the full range of urllib3 features. It also -supports the following SOCKS features: - -- SOCKS4A (``proxy_url='socks4a://...``) -- SOCKS4 (``proxy_url='socks4://...``) -- SOCKS5 with remote DNS (``proxy_url='socks5h://...``) -- SOCKS5 with local DNS (``proxy_url='socks5://...``) -- Usernames and passwords for the SOCKS proxy - -.. note:: - It is recommended to use ``socks5h://`` or ``socks4a://`` schemes in - your ``proxy_url`` to ensure that DNS resolution is done from the remote - server instead of client-side when connecting to a domain name. - -SOCKS4 supports IPv4 and domain names with the SOCKS4A extension. SOCKS5 -supports IPv4, IPv6, and domain names. - -When connecting to a SOCKS4 proxy the ``username`` portion of the ``proxy_url`` -will be sent as the ``userid`` section of the SOCKS request: - -.. code-block:: python - - proxy_url="socks4a://@proxy-host" - -When connecting to a SOCKS5 proxy the ``username`` and ``password`` portion -of the ``proxy_url`` will be sent as the username/password to authenticate -with the proxy: - -.. code-block:: python - - proxy_url="socks5h://:@proxy-host" - -""" -from __future__ import absolute_import - -try: - import socks -except ImportError: - import warnings - - from ..exceptions import DependencyWarning - - warnings.warn( - ( - "SOCKS support in urllib3 requires the installation of optional " - "dependencies: specifically, PySocks. For more information, see " - "https://urllib3.readthedocs.io/en/1.26.x/contrib.html#socks-proxies" - ), - DependencyWarning, - ) - raise - -from socket import error as SocketError -from socket import timeout as SocketTimeout - -from ..connection import HTTPConnection, HTTPSConnection -from ..connectionpool import HTTPConnectionPool, HTTPSConnectionPool -from ..exceptions import ConnectTimeoutError, NewConnectionError -from ..poolmanager import PoolManager -from ..util.url import parse_url - -try: - import ssl -except ImportError: - ssl = None - - -class SOCKSConnection(HTTPConnection): - """ - A plain-text HTTP connection that connects via a SOCKS proxy. - """ - - def __init__(self, *args, **kwargs): - self._socks_options = kwargs.pop("_socks_options") - super(SOCKSConnection, self).__init__(*args, **kwargs) - - def _new_conn(self): - """ - Establish a new connection via the SOCKS proxy. - """ - extra_kw = {} - if self.source_address: - extra_kw["source_address"] = self.source_address - - if self.socket_options: - extra_kw["socket_options"] = self.socket_options - - try: - conn = socks.create_connection( - (self.host, self.port), - proxy_type=self._socks_options["socks_version"], - proxy_addr=self._socks_options["proxy_host"], - proxy_port=self._socks_options["proxy_port"], - proxy_username=self._socks_options["username"], - proxy_password=self._socks_options["password"], - proxy_rdns=self._socks_options["rdns"], - timeout=self.timeout, - **extra_kw - ) - - except SocketTimeout: - raise ConnectTimeoutError( - self, - "Connection to %s timed out. (connect timeout=%s)" - % (self.host, self.timeout), - ) - - except socks.ProxyError as e: - # This is fragile as hell, but it seems to be the only way to raise - # useful errors here. - if e.socket_err: - error = e.socket_err - if isinstance(error, SocketTimeout): - raise ConnectTimeoutError( - self, - "Connection to %s timed out. (connect timeout=%s)" - % (self.host, self.timeout), - ) - else: - raise NewConnectionError( - self, "Failed to establish a new connection: %s" % error - ) - else: - raise NewConnectionError( - self, "Failed to establish a new connection: %s" % e - ) - - except SocketError as e: # Defensive: PySocks should catch all these. - raise NewConnectionError( - self, "Failed to establish a new connection: %s" % e - ) - - return conn - - -# We don't need to duplicate the Verified/Unverified distinction from -# urllib3/connection.py here because the HTTPSConnection will already have been -# correctly set to either the Verified or Unverified form by that module. This -# means the SOCKSHTTPSConnection will automatically be the correct type. -class SOCKSHTTPSConnection(SOCKSConnection, HTTPSConnection): - pass - - -class SOCKSHTTPConnectionPool(HTTPConnectionPool): - ConnectionCls = SOCKSConnection - - -class SOCKSHTTPSConnectionPool(HTTPSConnectionPool): - ConnectionCls = SOCKSHTTPSConnection - - -class SOCKSProxyManager(PoolManager): - """ - A version of the urllib3 ProxyManager that routes connections via the - defined SOCKS proxy. - """ - - pool_classes_by_scheme = { - "http": SOCKSHTTPConnectionPool, - "https": SOCKSHTTPSConnectionPool, - } - - def __init__( - self, - proxy_url, - username=None, - password=None, - num_pools=10, - headers=None, - **connection_pool_kw - ): - parsed = parse_url(proxy_url) - - if username is None and password is None and parsed.auth is not None: - split = parsed.auth.split(":") - if len(split) == 2: - username, password = split - if parsed.scheme == "socks5": - socks_version = socks.PROXY_TYPE_SOCKS5 - rdns = False - elif parsed.scheme == "socks5h": - socks_version = socks.PROXY_TYPE_SOCKS5 - rdns = True - elif parsed.scheme == "socks4": - socks_version = socks.PROXY_TYPE_SOCKS4 - rdns = False - elif parsed.scheme == "socks4a": - socks_version = socks.PROXY_TYPE_SOCKS4 - rdns = True - else: - raise ValueError("Unable to determine SOCKS version from %s" % proxy_url) - - self.proxy_url = proxy_url - - socks_options = { - "socks_version": socks_version, - "proxy_host": parsed.host, - "proxy_port": parsed.port, - "username": username, - "password": password, - "rdns": rdns, - } - connection_pool_kw["_socks_options"] = socks_options - - super(SOCKSProxyManager, self).__init__( - num_pools, headers, **connection_pool_kw - ) - - self.pool_classes_by_scheme = SOCKSProxyManager.pool_classes_by_scheme diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/exceptions.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/exceptions.py deleted file mode 100644 index cba6f3f560..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/exceptions.py +++ /dev/null @@ -1,323 +0,0 @@ -from __future__ import absolute_import - -from .packages.six.moves.http_client import IncompleteRead as httplib_IncompleteRead - -# Base Exceptions - - -class HTTPError(Exception): - """Base exception used by this module.""" - - pass - - -class HTTPWarning(Warning): - """Base warning used by this module.""" - - pass - - -class PoolError(HTTPError): - """Base exception for errors caused within a pool.""" - - def __init__(self, pool, message): - self.pool = pool - HTTPError.__init__(self, "%s: %s" % (pool, message)) - - def __reduce__(self): - # For pickling purposes. - return self.__class__, (None, None) - - -class RequestError(PoolError): - """Base exception for PoolErrors that have associated URLs.""" - - def __init__(self, pool, url, message): - self.url = url - PoolError.__init__(self, pool, message) - - def __reduce__(self): - # For pickling purposes. - return self.__class__, (None, self.url, None) - - -class SSLError(HTTPError): - """Raised when SSL certificate fails in an HTTPS connection.""" - - pass - - -class ProxyError(HTTPError): - """Raised when the connection to a proxy fails.""" - - def __init__(self, message, error, *args): - super(ProxyError, self).__init__(message, error, *args) - self.original_error = error - - -class DecodeError(HTTPError): - """Raised when automatic decoding based on Content-Type fails.""" - - pass - - -class ProtocolError(HTTPError): - """Raised when something unexpected happens mid-request/response.""" - - pass - - -#: Renamed to ProtocolError but aliased for backwards compatibility. -ConnectionError = ProtocolError - - -# Leaf Exceptions - - -class MaxRetryError(RequestError): - """Raised when the maximum number of retries is exceeded. - - :param pool: The connection pool - :type pool: :class:`~urllib3.connectionpool.HTTPConnectionPool` - :param string url: The requested Url - :param exceptions.Exception reason: The underlying error - - """ - - def __init__(self, pool, url, reason=None): - self.reason = reason - - message = "Max retries exceeded with url: %s (Caused by %r)" % (url, reason) - - RequestError.__init__(self, pool, url, message) - - -class HostChangedError(RequestError): - """Raised when an existing pool gets a request for a foreign host.""" - - def __init__(self, pool, url, retries=3): - message = "Tried to open a foreign host with url: %s" % url - RequestError.__init__(self, pool, url, message) - self.retries = retries - - -class TimeoutStateError(HTTPError): - """Raised when passing an invalid state to a timeout""" - - pass - - -class TimeoutError(HTTPError): - """Raised when a socket timeout error occurs. - - Catching this error will catch both :exc:`ReadTimeoutErrors - ` and :exc:`ConnectTimeoutErrors `. - """ - - pass - - -class ReadTimeoutError(TimeoutError, RequestError): - """Raised when a socket timeout occurs while receiving data from a server""" - - pass - - -# This timeout error does not have a URL attached and needs to inherit from the -# base HTTPError -class ConnectTimeoutError(TimeoutError): - """Raised when a socket timeout occurs while connecting to a server""" - - pass - - -class NewConnectionError(ConnectTimeoutError, PoolError): - """Raised when we fail to establish a new connection. Usually ECONNREFUSED.""" - - pass - - -class EmptyPoolError(PoolError): - """Raised when a pool runs out of connections and no more are allowed.""" - - pass - - -class ClosedPoolError(PoolError): - """Raised when a request enters a pool after the pool has been closed.""" - - pass - - -class LocationValueError(ValueError, HTTPError): - """Raised when there is something wrong with a given URL input.""" - - pass - - -class LocationParseError(LocationValueError): - """Raised when get_host or similar fails to parse the URL input.""" - - def __init__(self, location): - message = "Failed to parse: %s" % location - HTTPError.__init__(self, message) - - self.location = location - - -class URLSchemeUnknown(LocationValueError): - """Raised when a URL input has an unsupported scheme.""" - - def __init__(self, scheme): - message = "Not supported URL scheme %s" % scheme - super(URLSchemeUnknown, self).__init__(message) - - self.scheme = scheme - - -class ResponseError(HTTPError): - """Used as a container for an error reason supplied in a MaxRetryError.""" - - GENERIC_ERROR = "too many error responses" - SPECIFIC_ERROR = "too many {status_code} error responses" - - -class SecurityWarning(HTTPWarning): - """Warned when performing security reducing actions""" - - pass - - -class SubjectAltNameWarning(SecurityWarning): - """Warned when connecting to a host with a certificate missing a SAN.""" - - pass - - -class InsecureRequestWarning(SecurityWarning): - """Warned when making an unverified HTTPS request.""" - - pass - - -class SystemTimeWarning(SecurityWarning): - """Warned when system time is suspected to be wrong""" - - pass - - -class InsecurePlatformWarning(SecurityWarning): - """Warned when certain TLS/SSL configuration is not available on a platform.""" - - pass - - -class SNIMissingWarning(HTTPWarning): - """Warned when making a HTTPS request without SNI available.""" - - pass - - -class DependencyWarning(HTTPWarning): - """ - Warned when an attempt is made to import a module with missing optional - dependencies. - """ - - pass - - -class ResponseNotChunked(ProtocolError, ValueError): - """Response needs to be chunked in order to read it as chunks.""" - - pass - - -class BodyNotHttplibCompatible(HTTPError): - """ - Body should be :class:`http.client.HTTPResponse` like - (have an fp attribute which returns raw chunks) for read_chunked(). - """ - - pass - - -class IncompleteRead(HTTPError, httplib_IncompleteRead): - """ - Response length doesn't match expected Content-Length - - Subclass of :class:`http.client.IncompleteRead` to allow int value - for ``partial`` to avoid creating large objects on streamed reads. - """ - - def __init__(self, partial, expected): - super(IncompleteRead, self).__init__(partial, expected) - - def __repr__(self): - return "IncompleteRead(%i bytes read, %i more expected)" % ( - self.partial, - self.expected, - ) - - -class InvalidChunkLength(HTTPError, httplib_IncompleteRead): - """Invalid chunk length in a chunked response.""" - - def __init__(self, response, length): - super(InvalidChunkLength, self).__init__( - response.tell(), response.length_remaining - ) - self.response = response - self.length = length - - def __repr__(self): - return "InvalidChunkLength(got length %r, %i bytes read)" % ( - self.length, - self.partial, - ) - - -class InvalidHeader(HTTPError): - """The header provided was somehow invalid.""" - - pass - - -class ProxySchemeUnknown(AssertionError, URLSchemeUnknown): - """ProxyManager does not support the supplied scheme""" - - # TODO(t-8ch): Stop inheriting from AssertionError in v2.0. - - def __init__(self, scheme): - # 'localhost' is here because our URL parser parses - # localhost:8080 -> scheme=localhost, remove if we fix this. - if scheme == "localhost": - scheme = None - if scheme is None: - message = "Proxy URL had no scheme, should start with http:// or https://" - else: - message = ( - "Proxy URL had unsupported scheme %s, should use http:// or https://" - % scheme - ) - super(ProxySchemeUnknown, self).__init__(message) - - -class ProxySchemeUnsupported(ValueError): - """Fetching HTTPS resources through HTTPS proxies is unsupported""" - - pass - - -class HeaderParsingError(HTTPError): - """Raised by assert_header_parsing, but we convert it to a log.warning statement.""" - - def __init__(self, defects, unparsed_data): - message = "%s, unparsed data: %r" % (defects or "Unknown", unparsed_data) - super(HeaderParsingError, self).__init__(message) - - -class UnrewindableBodyError(HTTPError): - """urllib3 encountered an error when trying to rewind a body""" - - pass diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/fields.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/fields.py deleted file mode 100644 index 9d630f491d..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/fields.py +++ /dev/null @@ -1,274 +0,0 @@ -from __future__ import absolute_import - -import email.utils -import mimetypes -import re - -from .packages import six - - -def guess_content_type(filename, default="application/octet-stream"): - """ - Guess the "Content-Type" of a file. - - :param filename: - The filename to guess the "Content-Type" of using :mod:`mimetypes`. - :param default: - If no "Content-Type" can be guessed, default to `default`. - """ - if filename: - return mimetypes.guess_type(filename)[0] or default - return default - - -def format_header_param_rfc2231(name, value): - """ - Helper function to format and quote a single header parameter using the - strategy defined in RFC 2231. - - Particularly useful for header parameters which might contain - non-ASCII values, like file names. This follows - `RFC 2388 Section 4.4 `_. - - :param name: - The name of the parameter, a string expected to be ASCII only. - :param value: - The value of the parameter, provided as ``bytes`` or `str``. - :ret: - An RFC-2231-formatted unicode string. - """ - if isinstance(value, six.binary_type): - value = value.decode("utf-8") - - if not any(ch in value for ch in '"\\\r\n'): - result = u'%s="%s"' % (name, value) - try: - result.encode("ascii") - except (UnicodeEncodeError, UnicodeDecodeError): - pass - else: - return result - - if six.PY2: # Python 2: - value = value.encode("utf-8") - - # encode_rfc2231 accepts an encoded string and returns an ascii-encoded - # string in Python 2 but accepts and returns unicode strings in Python 3 - value = email.utils.encode_rfc2231(value, "utf-8") - value = "%s*=%s" % (name, value) - - if six.PY2: # Python 2: - value = value.decode("utf-8") - - return value - - -_HTML5_REPLACEMENTS = { - u"\u0022": u"%22", - # Replace "\" with "\\". - u"\u005C": u"\u005C\u005C", -} - -# All control characters from 0x00 to 0x1F *except* 0x1B. -_HTML5_REPLACEMENTS.update( - { - six.unichr(cc): u"%{:02X}".format(cc) - for cc in range(0x00, 0x1F + 1) - if cc not in (0x1B,) - } -) - - -def _replace_multiple(value, needles_and_replacements): - def replacer(match): - return needles_and_replacements[match.group(0)] - - pattern = re.compile( - r"|".join([re.escape(needle) for needle in needles_and_replacements.keys()]) - ) - - result = pattern.sub(replacer, value) - - return result - - -def format_header_param_html5(name, value): - """ - Helper function to format and quote a single header parameter using the - HTML5 strategy. - - Particularly useful for header parameters which might contain - non-ASCII values, like file names. This follows the `HTML5 Working Draft - Section 4.10.22.7`_ and matches the behavior of curl and modern browsers. - - .. _HTML5 Working Draft Section 4.10.22.7: - https://w3c.github.io/html/sec-forms.html#multipart-form-data - - :param name: - The name of the parameter, a string expected to be ASCII only. - :param value: - The value of the parameter, provided as ``bytes`` or `str``. - :ret: - A unicode string, stripped of troublesome characters. - """ - if isinstance(value, six.binary_type): - value = value.decode("utf-8") - - value = _replace_multiple(value, _HTML5_REPLACEMENTS) - - return u'%s="%s"' % (name, value) - - -# For backwards-compatibility. -format_header_param = format_header_param_html5 - - -class RequestField(object): - """ - A data container for request body parameters. - - :param name: - The name of this request field. Must be unicode. - :param data: - The data/value body. - :param filename: - An optional filename of the request field. Must be unicode. - :param headers: - An optional dict-like object of headers to initially use for the field. - :param header_formatter: - An optional callable that is used to encode and format the headers. By - default, this is :func:`format_header_param_html5`. - """ - - def __init__( - self, - name, - data, - filename=None, - headers=None, - header_formatter=format_header_param_html5, - ): - self._name = name - self._filename = filename - self.data = data - self.headers = {} - if headers: - self.headers = dict(headers) - self.header_formatter = header_formatter - - @classmethod - def from_tuples(cls, fieldname, value, header_formatter=format_header_param_html5): - """ - A :class:`~urllib3.fields.RequestField` factory from old-style tuple parameters. - - Supports constructing :class:`~urllib3.fields.RequestField` from - parameter of key/value strings AND key/filetuple. A filetuple is a - (filename, data, MIME type) tuple where the MIME type is optional. - For example:: - - 'foo': 'bar', - 'fakefile': ('foofile.txt', 'contents of foofile'), - 'realfile': ('barfile.txt', open('realfile').read()), - 'typedfile': ('bazfile.bin', open('bazfile').read(), 'image/jpeg'), - 'nonamefile': 'contents of nonamefile field', - - Field names and filenames must be unicode. - """ - if isinstance(value, tuple): - if len(value) == 3: - filename, data, content_type = value - else: - filename, data = value - content_type = guess_content_type(filename) - else: - filename = None - content_type = None - data = value - - request_param = cls( - fieldname, data, filename=filename, header_formatter=header_formatter - ) - request_param.make_multipart(content_type=content_type) - - return request_param - - def _render_part(self, name, value): - """ - Overridable helper function to format a single header parameter. By - default, this calls ``self.header_formatter``. - - :param name: - The name of the parameter, a string expected to be ASCII only. - :param value: - The value of the parameter, provided as a unicode string. - """ - - return self.header_formatter(name, value) - - def _render_parts(self, header_parts): - """ - Helper function to format and quote a single header. - - Useful for single headers that are composed of multiple items. E.g., - 'Content-Disposition' fields. - - :param header_parts: - A sequence of (k, v) tuples or a :class:`dict` of (k, v) to format - as `k1="v1"; k2="v2"; ...`. - """ - parts = [] - iterable = header_parts - if isinstance(header_parts, dict): - iterable = header_parts.items() - - for name, value in iterable: - if value is not None: - parts.append(self._render_part(name, value)) - - return u"; ".join(parts) - - def render_headers(self): - """ - Renders the headers for this request field. - """ - lines = [] - - sort_keys = ["Content-Disposition", "Content-Type", "Content-Location"] - for sort_key in sort_keys: - if self.headers.get(sort_key, False): - lines.append(u"%s: %s" % (sort_key, self.headers[sort_key])) - - for header_name, header_value in self.headers.items(): - if header_name not in sort_keys: - if header_value: - lines.append(u"%s: %s" % (header_name, header_value)) - - lines.append(u"\r\n") - return u"\r\n".join(lines) - - def make_multipart( - self, content_disposition=None, content_type=None, content_location=None - ): - """ - Makes this request field into a multipart request field. - - This method overrides "Content-Disposition", "Content-Type" and - "Content-Location" headers to the request parameter. - - :param content_type: - The 'Content-Type' of the request body. - :param content_location: - The 'Content-Location' of the request body. - - """ - self.headers["Content-Disposition"] = content_disposition or u"form-data" - self.headers["Content-Disposition"] += u"; ".join( - [ - u"", - self._render_parts( - ((u"name", self._name), (u"filename", self._filename)) - ), - ] - ) - self.headers["Content-Type"] = content_type - self.headers["Content-Location"] = content_location diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/filepost.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/filepost.py deleted file mode 100644 index 36c9252c64..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/filepost.py +++ /dev/null @@ -1,98 +0,0 @@ -from __future__ import absolute_import - -import binascii -import codecs -import os -from io import BytesIO - -from .fields import RequestField -from .packages import six -from .packages.six import b - -writer = codecs.lookup("utf-8")[3] - - -def choose_boundary(): - """ - Our embarrassingly-simple replacement for mimetools.choose_boundary. - """ - boundary = binascii.hexlify(os.urandom(16)) - if not six.PY2: - boundary = boundary.decode("ascii") - return boundary - - -def iter_field_objects(fields): - """ - Iterate over fields. - - Supports list of (k, v) tuples and dicts, and lists of - :class:`~urllib3.fields.RequestField`. - - """ - if isinstance(fields, dict): - i = six.iteritems(fields) - else: - i = iter(fields) - - for field in i: - if isinstance(field, RequestField): - yield field - else: - yield RequestField.from_tuples(*field) - - -def iter_fields(fields): - """ - .. deprecated:: 1.6 - - Iterate over fields. - - The addition of :class:`~urllib3.fields.RequestField` makes this function - obsolete. Instead, use :func:`iter_field_objects`, which returns - :class:`~urllib3.fields.RequestField` objects. - - Supports list of (k, v) tuples and dicts. - """ - if isinstance(fields, dict): - return ((k, v) for k, v in six.iteritems(fields)) - - return ((k, v) for k, v in fields) - - -def encode_multipart_formdata(fields, boundary=None): - """ - Encode a dictionary of ``fields`` using the multipart/form-data MIME format. - - :param fields: - Dictionary of fields or list of (key, :class:`~urllib3.fields.RequestField`). - - :param boundary: - If not specified, then a random boundary will be generated using - :func:`urllib3.filepost.choose_boundary`. - """ - body = BytesIO() - if boundary is None: - boundary = choose_boundary() - - for field in iter_field_objects(fields): - body.write(b("--%s\r\n" % (boundary))) - - writer(body).write(field.render_headers()) - data = field.data - - if isinstance(data, int): - data = str(data) # Backwards compatibility - - if isinstance(data, six.text_type): - writer(body).write(data) - else: - body.write(data) - - body.write(b"\r\n") - - body.write(b("--%s--\r\n" % (boundary))) - - content_type = str("multipart/form-data; boundary=%s" % boundary) - - return body.getvalue(), content_type diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/packages/__init__.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/packages/__init__.py deleted file mode 100644 index fce4caa65d..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/packages/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -from __future__ import absolute_import - -from . import ssl_match_hostname - -__all__ = ("ssl_match_hostname",) diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/packages/backports/__init__.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/packages/backports/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/packages/backports/makefile.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/packages/backports/makefile.py deleted file mode 100644 index b8fb2154b6..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/packages/backports/makefile.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding: utf-8 -*- -""" -backports.makefile -~~~~~~~~~~~~~~~~~~ - -Backports the Python 3 ``socket.makefile`` method for use with anything that -wants to create a "fake" socket object. -""" -import io -from socket import SocketIO - - -def backport_makefile( - self, mode="r", buffering=None, encoding=None, errors=None, newline=None -): - """ - Backport of ``socket.makefile`` from Python 3.5. - """ - if not set(mode) <= {"r", "w", "b"}: - raise ValueError("invalid mode %r (only r, w, b allowed)" % (mode,)) - writing = "w" in mode - reading = "r" in mode or not writing - assert reading or writing - binary = "b" in mode - rawmode = "" - if reading: - rawmode += "r" - if writing: - rawmode += "w" - raw = SocketIO(self, rawmode) - self._makefile_refs += 1 - if buffering is None: - buffering = -1 - if buffering < 0: - buffering = io.DEFAULT_BUFFER_SIZE - if buffering == 0: - if not binary: - raise ValueError("unbuffered streams must be binary") - return raw - if reading and writing: - buffer = io.BufferedRWPair(raw, raw, buffering) - elif reading: - buffer = io.BufferedReader(raw, buffering) - else: - assert writing - buffer = io.BufferedWriter(raw, buffering) - if binary: - return buffer - text = io.TextIOWrapper(buffer, encoding, errors, newline) - text.mode = mode - return text diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/packages/six.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/packages/six.py deleted file mode 100644 index ba50acb062..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/packages/six.py +++ /dev/null @@ -1,1077 +0,0 @@ -# Copyright (c) 2010-2020 Benjamin Peterson -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -"""Utilities for writing code that runs on Python 2 and 3""" - -from __future__ import absolute_import - -import functools -import itertools -import operator -import sys -import types - -__author__ = "Benjamin Peterson " -__version__ = "1.16.0" - - -# Useful for very coarse version differentiation. -PY2 = sys.version_info[0] == 2 -PY3 = sys.version_info[0] == 3 -PY34 = sys.version_info[0:2] >= (3, 4) - -if PY3: - string_types = (str,) - integer_types = (int,) - class_types = (type,) - text_type = str - binary_type = bytes - - MAXSIZE = sys.maxsize -else: - string_types = (basestring,) - integer_types = (int, long) - class_types = (type, types.ClassType) - text_type = unicode - binary_type = str - - if sys.platform.startswith("java"): - # Jython always uses 32 bits. - MAXSIZE = int((1 << 31) - 1) - else: - # It's possible to have sizeof(long) != sizeof(Py_ssize_t). - class X(object): - def __len__(self): - return 1 << 31 - - try: - len(X()) - except OverflowError: - # 32-bit - MAXSIZE = int((1 << 31) - 1) - else: - # 64-bit - MAXSIZE = int((1 << 63) - 1) - del X - -if PY34: - from importlib.util import spec_from_loader -else: - spec_from_loader = None - - -def _add_doc(func, doc): - """Add documentation to a function.""" - func.__doc__ = doc - - -def _import_module(name): - """Import module, returning the module after the last dot.""" - __import__(name) - return sys.modules[name] - - -class _LazyDescr(object): - def __init__(self, name): - self.name = name - - def __get__(self, obj, tp): - result = self._resolve() - setattr(obj, self.name, result) # Invokes __set__. - try: - # This is a bit ugly, but it avoids running this again by - # removing this descriptor. - delattr(obj.__class__, self.name) - except AttributeError: - pass - return result - - -class MovedModule(_LazyDescr): - def __init__(self, name, old, new=None): - super(MovedModule, self).__init__(name) - if PY3: - if new is None: - new = name - self.mod = new - else: - self.mod = old - - def _resolve(self): - return _import_module(self.mod) - - def __getattr__(self, attr): - _module = self._resolve() - value = getattr(_module, attr) - setattr(self, attr, value) - return value - - -class _LazyModule(types.ModuleType): - def __init__(self, name): - super(_LazyModule, self).__init__(name) - self.__doc__ = self.__class__.__doc__ - - def __dir__(self): - attrs = ["__doc__", "__name__"] - attrs += [attr.name for attr in self._moved_attributes] - return attrs - - # Subclasses should override this - _moved_attributes = [] - - -class MovedAttribute(_LazyDescr): - def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): - super(MovedAttribute, self).__init__(name) - if PY3: - if new_mod is None: - new_mod = name - self.mod = new_mod - if new_attr is None: - if old_attr is None: - new_attr = name - else: - new_attr = old_attr - self.attr = new_attr - else: - self.mod = old_mod - if old_attr is None: - old_attr = name - self.attr = old_attr - - def _resolve(self): - module = _import_module(self.mod) - return getattr(module, self.attr) - - -class _SixMetaPathImporter(object): - - """ - A meta path importer to import six.moves and its submodules. - - This class implements a PEP302 finder and loader. It should be compatible - with Python 2.5 and all existing versions of Python3 - """ - - def __init__(self, six_module_name): - self.name = six_module_name - self.known_modules = {} - - def _add_module(self, mod, *fullnames): - for fullname in fullnames: - self.known_modules[self.name + "." + fullname] = mod - - def _get_module(self, fullname): - return self.known_modules[self.name + "." + fullname] - - def find_module(self, fullname, path=None): - if fullname in self.known_modules: - return self - return None - - def find_spec(self, fullname, path, target=None): - if fullname in self.known_modules: - return spec_from_loader(fullname, self) - return None - - def __get_module(self, fullname): - try: - return self.known_modules[fullname] - except KeyError: - raise ImportError("This loader does not know module " + fullname) - - def load_module(self, fullname): - try: - # in case of a reload - return sys.modules[fullname] - except KeyError: - pass - mod = self.__get_module(fullname) - if isinstance(mod, MovedModule): - mod = mod._resolve() - else: - mod.__loader__ = self - sys.modules[fullname] = mod - return mod - - def is_package(self, fullname): - """ - Return true, if the named module is a package. - - We need this method to get correct spec objects with - Python 3.4 (see PEP451) - """ - return hasattr(self.__get_module(fullname), "__path__") - - def get_code(self, fullname): - """Return None - - Required, if is_package is implemented""" - self.__get_module(fullname) # eventually raises ImportError - return None - - get_source = get_code # same as get_code - - def create_module(self, spec): - return self.load_module(spec.name) - - def exec_module(self, module): - pass - - -_importer = _SixMetaPathImporter(__name__) - - -class _MovedItems(_LazyModule): - - """Lazy loading of moved objects""" - - __path__ = [] # mark as package - - -_moved_attributes = [ - MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"), - MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"), - MovedAttribute( - "filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse" - ), - MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"), - MovedAttribute("intern", "__builtin__", "sys"), - MovedAttribute("map", "itertools", "builtins", "imap", "map"), - MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"), - MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"), - MovedAttribute("getoutput", "commands", "subprocess"), - MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"), - MovedAttribute( - "reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload" - ), - MovedAttribute("reduce", "__builtin__", "functools"), - MovedAttribute("shlex_quote", "pipes", "shlex", "quote"), - MovedAttribute("StringIO", "StringIO", "io"), - MovedAttribute("UserDict", "UserDict", "collections"), - MovedAttribute("UserList", "UserList", "collections"), - MovedAttribute("UserString", "UserString", "collections"), - MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"), - MovedAttribute("zip", "itertools", "builtins", "izip", "zip"), - MovedAttribute( - "zip_longest", "itertools", "itertools", "izip_longest", "zip_longest" - ), - MovedModule("builtins", "__builtin__"), - MovedModule("configparser", "ConfigParser"), - MovedModule( - "collections_abc", - "collections", - "collections.abc" if sys.version_info >= (3, 3) else "collections", - ), - MovedModule("copyreg", "copy_reg"), - MovedModule("dbm_gnu", "gdbm", "dbm.gnu"), - MovedModule("dbm_ndbm", "dbm", "dbm.ndbm"), - MovedModule( - "_dummy_thread", - "dummy_thread", - "_dummy_thread" if sys.version_info < (3, 9) else "_thread", - ), - MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), - MovedModule("http_cookies", "Cookie", "http.cookies"), - MovedModule("html_entities", "htmlentitydefs", "html.entities"), - MovedModule("html_parser", "HTMLParser", "html.parser"), - MovedModule("http_client", "httplib", "http.client"), - MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"), - MovedModule("email_mime_image", "email.MIMEImage", "email.mime.image"), - MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"), - MovedModule( - "email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart" - ), - MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"), - MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"), - MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"), - MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"), - MovedModule("cPickle", "cPickle", "pickle"), - MovedModule("queue", "Queue"), - MovedModule("reprlib", "repr"), - MovedModule("socketserver", "SocketServer"), - MovedModule("_thread", "thread", "_thread"), - MovedModule("tkinter", "Tkinter"), - MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"), - MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"), - MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"), - MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"), - MovedModule("tkinter_tix", "Tix", "tkinter.tix"), - MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"), - MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"), - MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"), - MovedModule("tkinter_colorchooser", "tkColorChooser", "tkinter.colorchooser"), - MovedModule("tkinter_commondialog", "tkCommonDialog", "tkinter.commondialog"), - MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), - MovedModule("tkinter_font", "tkFont", "tkinter.font"), - MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), - MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", "tkinter.simpledialog"), - MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"), - MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"), - MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"), - MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), - MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"), - MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"), -] -# Add windows specific modules. -if sys.platform == "win32": - _moved_attributes += [ - MovedModule("winreg", "_winreg"), - ] - -for attr in _moved_attributes: - setattr(_MovedItems, attr.name, attr) - if isinstance(attr, MovedModule): - _importer._add_module(attr, "moves." + attr.name) -del attr - -_MovedItems._moved_attributes = _moved_attributes - -moves = _MovedItems(__name__ + ".moves") -_importer._add_module(moves, "moves") - - -class Module_six_moves_urllib_parse(_LazyModule): - - """Lazy loading of moved objects in six.moves.urllib_parse""" - - -_urllib_parse_moved_attributes = [ - MovedAttribute("ParseResult", "urlparse", "urllib.parse"), - MovedAttribute("SplitResult", "urlparse", "urllib.parse"), - MovedAttribute("parse_qs", "urlparse", "urllib.parse"), - MovedAttribute("parse_qsl", "urlparse", "urllib.parse"), - MovedAttribute("urldefrag", "urlparse", "urllib.parse"), - MovedAttribute("urljoin", "urlparse", "urllib.parse"), - MovedAttribute("urlparse", "urlparse", "urllib.parse"), - MovedAttribute("urlsplit", "urlparse", "urllib.parse"), - MovedAttribute("urlunparse", "urlparse", "urllib.parse"), - MovedAttribute("urlunsplit", "urlparse", "urllib.parse"), - MovedAttribute("quote", "urllib", "urllib.parse"), - MovedAttribute("quote_plus", "urllib", "urllib.parse"), - MovedAttribute("unquote", "urllib", "urllib.parse"), - MovedAttribute("unquote_plus", "urllib", "urllib.parse"), - MovedAttribute( - "unquote_to_bytes", "urllib", "urllib.parse", "unquote", "unquote_to_bytes" - ), - MovedAttribute("urlencode", "urllib", "urllib.parse"), - MovedAttribute("splitquery", "urllib", "urllib.parse"), - MovedAttribute("splittag", "urllib", "urllib.parse"), - MovedAttribute("splituser", "urllib", "urllib.parse"), - MovedAttribute("splitvalue", "urllib", "urllib.parse"), - MovedAttribute("uses_fragment", "urlparse", "urllib.parse"), - MovedAttribute("uses_netloc", "urlparse", "urllib.parse"), - MovedAttribute("uses_params", "urlparse", "urllib.parse"), - MovedAttribute("uses_query", "urlparse", "urllib.parse"), - MovedAttribute("uses_relative", "urlparse", "urllib.parse"), -] -for attr in _urllib_parse_moved_attributes: - setattr(Module_six_moves_urllib_parse, attr.name, attr) -del attr - -Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes - -_importer._add_module( - Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"), - "moves.urllib_parse", - "moves.urllib.parse", -) - - -class Module_six_moves_urllib_error(_LazyModule): - - """Lazy loading of moved objects in six.moves.urllib_error""" - - -_urllib_error_moved_attributes = [ - MovedAttribute("URLError", "urllib2", "urllib.error"), - MovedAttribute("HTTPError", "urllib2", "urllib.error"), - MovedAttribute("ContentTooShortError", "urllib", "urllib.error"), -] -for attr in _urllib_error_moved_attributes: - setattr(Module_six_moves_urllib_error, attr.name, attr) -del attr - -Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes - -_importer._add_module( - Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"), - "moves.urllib_error", - "moves.urllib.error", -) - - -class Module_six_moves_urllib_request(_LazyModule): - - """Lazy loading of moved objects in six.moves.urllib_request""" - - -_urllib_request_moved_attributes = [ - MovedAttribute("urlopen", "urllib2", "urllib.request"), - MovedAttribute("install_opener", "urllib2", "urllib.request"), - MovedAttribute("build_opener", "urllib2", "urllib.request"), - MovedAttribute("pathname2url", "urllib", "urllib.request"), - MovedAttribute("url2pathname", "urllib", "urllib.request"), - MovedAttribute("getproxies", "urllib", "urllib.request"), - MovedAttribute("Request", "urllib2", "urllib.request"), - MovedAttribute("OpenerDirector", "urllib2", "urllib.request"), - MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"), - MovedAttribute("ProxyHandler", "urllib2", "urllib.request"), - MovedAttribute("BaseHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"), - MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"), - MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"), - MovedAttribute("FileHandler", "urllib2", "urllib.request"), - MovedAttribute("FTPHandler", "urllib2", "urllib.request"), - MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"), - MovedAttribute("UnknownHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"), - MovedAttribute("urlretrieve", "urllib", "urllib.request"), - MovedAttribute("urlcleanup", "urllib", "urllib.request"), - MovedAttribute("URLopener", "urllib", "urllib.request"), - MovedAttribute("FancyURLopener", "urllib", "urllib.request"), - MovedAttribute("proxy_bypass", "urllib", "urllib.request"), - MovedAttribute("parse_http_list", "urllib2", "urllib.request"), - MovedAttribute("parse_keqv_list", "urllib2", "urllib.request"), -] -for attr in _urllib_request_moved_attributes: - setattr(Module_six_moves_urllib_request, attr.name, attr) -del attr - -Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes - -_importer._add_module( - Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"), - "moves.urllib_request", - "moves.urllib.request", -) - - -class Module_six_moves_urllib_response(_LazyModule): - - """Lazy loading of moved objects in six.moves.urllib_response""" - - -_urllib_response_moved_attributes = [ - MovedAttribute("addbase", "urllib", "urllib.response"), - MovedAttribute("addclosehook", "urllib", "urllib.response"), - MovedAttribute("addinfo", "urllib", "urllib.response"), - MovedAttribute("addinfourl", "urllib", "urllib.response"), -] -for attr in _urllib_response_moved_attributes: - setattr(Module_six_moves_urllib_response, attr.name, attr) -del attr - -Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes - -_importer._add_module( - Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"), - "moves.urllib_response", - "moves.urllib.response", -) - - -class Module_six_moves_urllib_robotparser(_LazyModule): - - """Lazy loading of moved objects in six.moves.urllib_robotparser""" - - -_urllib_robotparser_moved_attributes = [ - MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"), -] -for attr in _urllib_robotparser_moved_attributes: - setattr(Module_six_moves_urllib_robotparser, attr.name, attr) -del attr - -Module_six_moves_urllib_robotparser._moved_attributes = ( - _urllib_robotparser_moved_attributes -) - -_importer._add_module( - Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"), - "moves.urllib_robotparser", - "moves.urllib.robotparser", -) - - -class Module_six_moves_urllib(types.ModuleType): - - """Create a six.moves.urllib namespace that resembles the Python 3 namespace""" - - __path__ = [] # mark as package - parse = _importer._get_module("moves.urllib_parse") - error = _importer._get_module("moves.urllib_error") - request = _importer._get_module("moves.urllib_request") - response = _importer._get_module("moves.urllib_response") - robotparser = _importer._get_module("moves.urllib_robotparser") - - def __dir__(self): - return ["parse", "error", "request", "response", "robotparser"] - - -_importer._add_module( - Module_six_moves_urllib(__name__ + ".moves.urllib"), "moves.urllib" -) - - -def add_move(move): - """Add an item to six.moves.""" - setattr(_MovedItems, move.name, move) - - -def remove_move(name): - """Remove item from six.moves.""" - try: - delattr(_MovedItems, name) - except AttributeError: - try: - del moves.__dict__[name] - except KeyError: - raise AttributeError("no such move, %r" % (name,)) - - -if PY3: - _meth_func = "__func__" - _meth_self = "__self__" - - _func_closure = "__closure__" - _func_code = "__code__" - _func_defaults = "__defaults__" - _func_globals = "__globals__" -else: - _meth_func = "im_func" - _meth_self = "im_self" - - _func_closure = "func_closure" - _func_code = "func_code" - _func_defaults = "func_defaults" - _func_globals = "func_globals" - - -try: - advance_iterator = next -except NameError: - - def advance_iterator(it): - return it.next() - - -next = advance_iterator - - -try: - callable = callable -except NameError: - - def callable(obj): - return any("__call__" in klass.__dict__ for klass in type(obj).__mro__) - - -if PY3: - - def get_unbound_function(unbound): - return unbound - - create_bound_method = types.MethodType - - def create_unbound_method(func, cls): - return func - - Iterator = object -else: - - def get_unbound_function(unbound): - return unbound.im_func - - def create_bound_method(func, obj): - return types.MethodType(func, obj, obj.__class__) - - def create_unbound_method(func, cls): - return types.MethodType(func, None, cls) - - class Iterator(object): - def next(self): - return type(self).__next__(self) - - callable = callable -_add_doc( - get_unbound_function, """Get the function out of a possibly unbound function""" -) - - -get_method_function = operator.attrgetter(_meth_func) -get_method_self = operator.attrgetter(_meth_self) -get_function_closure = operator.attrgetter(_func_closure) -get_function_code = operator.attrgetter(_func_code) -get_function_defaults = operator.attrgetter(_func_defaults) -get_function_globals = operator.attrgetter(_func_globals) - - -if PY3: - - def iterkeys(d, **kw): - return iter(d.keys(**kw)) - - def itervalues(d, **kw): - return iter(d.values(**kw)) - - def iteritems(d, **kw): - return iter(d.items(**kw)) - - def iterlists(d, **kw): - return iter(d.lists(**kw)) - - viewkeys = operator.methodcaller("keys") - - viewvalues = operator.methodcaller("values") - - viewitems = operator.methodcaller("items") -else: - - def iterkeys(d, **kw): - return d.iterkeys(**kw) - - def itervalues(d, **kw): - return d.itervalues(**kw) - - def iteritems(d, **kw): - return d.iteritems(**kw) - - def iterlists(d, **kw): - return d.iterlists(**kw) - - viewkeys = operator.methodcaller("viewkeys") - - viewvalues = operator.methodcaller("viewvalues") - - viewitems = operator.methodcaller("viewitems") - -_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.") -_add_doc(itervalues, "Return an iterator over the values of a dictionary.") -_add_doc(iteritems, "Return an iterator over the (key, value) pairs of a dictionary.") -_add_doc( - iterlists, "Return an iterator over the (key, [values]) pairs of a dictionary." -) - - -if PY3: - - def b(s): - return s.encode("latin-1") - - def u(s): - return s - - unichr = chr - import struct - - int2byte = struct.Struct(">B").pack - del struct - byte2int = operator.itemgetter(0) - indexbytes = operator.getitem - iterbytes = iter - import io - - StringIO = io.StringIO - BytesIO = io.BytesIO - del io - _assertCountEqual = "assertCountEqual" - if sys.version_info[1] <= 1: - _assertRaisesRegex = "assertRaisesRegexp" - _assertRegex = "assertRegexpMatches" - _assertNotRegex = "assertNotRegexpMatches" - else: - _assertRaisesRegex = "assertRaisesRegex" - _assertRegex = "assertRegex" - _assertNotRegex = "assertNotRegex" -else: - - def b(s): - return s - - # Workaround for standalone backslash - - def u(s): - return unicode(s.replace(r"\\", r"\\\\"), "unicode_escape") - - unichr = unichr - int2byte = chr - - def byte2int(bs): - return ord(bs[0]) - - def indexbytes(buf, i): - return ord(buf[i]) - - iterbytes = functools.partial(itertools.imap, ord) - import StringIO - - StringIO = BytesIO = StringIO.StringIO - _assertCountEqual = "assertItemsEqual" - _assertRaisesRegex = "assertRaisesRegexp" - _assertRegex = "assertRegexpMatches" - _assertNotRegex = "assertNotRegexpMatches" -_add_doc(b, """Byte literal""") -_add_doc(u, """Text literal""") - - -def assertCountEqual(self, *args, **kwargs): - return getattr(self, _assertCountEqual)(*args, **kwargs) - - -def assertRaisesRegex(self, *args, **kwargs): - return getattr(self, _assertRaisesRegex)(*args, **kwargs) - - -def assertRegex(self, *args, **kwargs): - return getattr(self, _assertRegex)(*args, **kwargs) - - -def assertNotRegex(self, *args, **kwargs): - return getattr(self, _assertNotRegex)(*args, **kwargs) - - -if PY3: - exec_ = getattr(moves.builtins, "exec") - - def reraise(tp, value, tb=None): - try: - if value is None: - value = tp() - if value.__traceback__ is not tb: - raise value.with_traceback(tb) - raise value - finally: - value = None - tb = None - - -else: - - def exec_(_code_, _globs_=None, _locs_=None): - """Execute code in a namespace.""" - if _globs_ is None: - frame = sys._getframe(1) - _globs_ = frame.f_globals - if _locs_ is None: - _locs_ = frame.f_locals - del frame - elif _locs_ is None: - _locs_ = _globs_ - exec ("""exec _code_ in _globs_, _locs_""") - - exec_( - """def reraise(tp, value, tb=None): - try: - raise tp, value, tb - finally: - tb = None -""" - ) - - -if sys.version_info[:2] > (3,): - exec_( - """def raise_from(value, from_value): - try: - raise value from from_value - finally: - value = None -""" - ) -else: - - def raise_from(value, from_value): - raise value - - -print_ = getattr(moves.builtins, "print", None) -if print_ is None: - - def print_(*args, **kwargs): - """The new-style print function for Python 2.4 and 2.5.""" - fp = kwargs.pop("file", sys.stdout) - if fp is None: - return - - def write(data): - if not isinstance(data, basestring): - data = str(data) - # If the file has an encoding, encode unicode with it. - if ( - isinstance(fp, file) - and isinstance(data, unicode) - and fp.encoding is not None - ): - errors = getattr(fp, "errors", None) - if errors is None: - errors = "strict" - data = data.encode(fp.encoding, errors) - fp.write(data) - - want_unicode = False - sep = kwargs.pop("sep", None) - if sep is not None: - if isinstance(sep, unicode): - want_unicode = True - elif not isinstance(sep, str): - raise TypeError("sep must be None or a string") - end = kwargs.pop("end", None) - if end is not None: - if isinstance(end, unicode): - want_unicode = True - elif not isinstance(end, str): - raise TypeError("end must be None or a string") - if kwargs: - raise TypeError("invalid keyword arguments to print()") - if not want_unicode: - for arg in args: - if isinstance(arg, unicode): - want_unicode = True - break - if want_unicode: - newline = unicode("\n") - space = unicode(" ") - else: - newline = "\n" - space = " " - if sep is None: - sep = space - if end is None: - end = newline - for i, arg in enumerate(args): - if i: - write(sep) - write(arg) - write(end) - - -if sys.version_info[:2] < (3, 3): - _print = print_ - - def print_(*args, **kwargs): - fp = kwargs.get("file", sys.stdout) - flush = kwargs.pop("flush", False) - _print(*args, **kwargs) - if flush and fp is not None: - fp.flush() - - -_add_doc(reraise, """Reraise an exception.""") - -if sys.version_info[0:2] < (3, 4): - # This does exactly the same what the :func:`py3:functools.update_wrapper` - # function does on Python versions after 3.2. It sets the ``__wrapped__`` - # attribute on ``wrapper`` object and it doesn't raise an error if any of - # the attributes mentioned in ``assigned`` and ``updated`` are missing on - # ``wrapped`` object. - def _update_wrapper( - wrapper, - wrapped, - assigned=functools.WRAPPER_ASSIGNMENTS, - updated=functools.WRAPPER_UPDATES, - ): - for attr in assigned: - try: - value = getattr(wrapped, attr) - except AttributeError: - continue - else: - setattr(wrapper, attr, value) - for attr in updated: - getattr(wrapper, attr).update(getattr(wrapped, attr, {})) - wrapper.__wrapped__ = wrapped - return wrapper - - _update_wrapper.__doc__ = functools.update_wrapper.__doc__ - - def wraps( - wrapped, - assigned=functools.WRAPPER_ASSIGNMENTS, - updated=functools.WRAPPER_UPDATES, - ): - return functools.partial( - _update_wrapper, wrapped=wrapped, assigned=assigned, updated=updated - ) - - wraps.__doc__ = functools.wraps.__doc__ - -else: - wraps = functools.wraps - - -def with_metaclass(meta, *bases): - """Create a base class with a metaclass.""" - # This requires a bit of explanation: the basic idea is to make a dummy - # metaclass for one level of class instantiation that replaces itself with - # the actual metaclass. - class metaclass(type): - def __new__(cls, name, this_bases, d): - if sys.version_info[:2] >= (3, 7): - # This version introduced PEP 560 that requires a bit - # of extra care (we mimic what is done by __build_class__). - resolved_bases = types.resolve_bases(bases) - if resolved_bases is not bases: - d["__orig_bases__"] = bases - else: - resolved_bases = bases - return meta(name, resolved_bases, d) - - @classmethod - def __prepare__(cls, name, this_bases): - return meta.__prepare__(name, bases) - - return type.__new__(metaclass, "temporary_class", (), {}) - - -def add_metaclass(metaclass): - """Class decorator for creating a class with a metaclass.""" - - def wrapper(cls): - orig_vars = cls.__dict__.copy() - slots = orig_vars.get("__slots__") - if slots is not None: - if isinstance(slots, str): - slots = [slots] - for slots_var in slots: - orig_vars.pop(slots_var) - orig_vars.pop("__dict__", None) - orig_vars.pop("__weakref__", None) - if hasattr(cls, "__qualname__"): - orig_vars["__qualname__"] = cls.__qualname__ - return metaclass(cls.__name__, cls.__bases__, orig_vars) - - return wrapper - - -def ensure_binary(s, encoding="utf-8", errors="strict"): - """Coerce **s** to six.binary_type. - - For Python 2: - - `unicode` -> encoded to `str` - - `str` -> `str` - - For Python 3: - - `str` -> encoded to `bytes` - - `bytes` -> `bytes` - """ - if isinstance(s, binary_type): - return s - if isinstance(s, text_type): - return s.encode(encoding, errors) - raise TypeError("not expecting type '%s'" % type(s)) - - -def ensure_str(s, encoding="utf-8", errors="strict"): - """Coerce *s* to `str`. - - For Python 2: - - `unicode` -> encoded to `str` - - `str` -> `str` - - For Python 3: - - `str` -> `str` - - `bytes` -> decoded to `str` - """ - # Optimization: Fast return for the common case. - if type(s) is str: - return s - if PY2 and isinstance(s, text_type): - return s.encode(encoding, errors) - elif PY3 and isinstance(s, binary_type): - return s.decode(encoding, errors) - elif not isinstance(s, (text_type, binary_type)): - raise TypeError("not expecting type '%s'" % type(s)) - return s - - -def ensure_text(s, encoding="utf-8", errors="strict"): - """Coerce *s* to six.text_type. - - For Python 2: - - `unicode` -> `unicode` - - `str` -> `unicode` - - For Python 3: - - `str` -> `str` - - `bytes` -> decoded to `str` - """ - if isinstance(s, binary_type): - return s.decode(encoding, errors) - elif isinstance(s, text_type): - return s - else: - raise TypeError("not expecting type '%s'" % type(s)) - - -def python_2_unicode_compatible(klass): - """ - A class decorator that defines __unicode__ and __str__ methods under Python 2. - Under Python 3 it does nothing. - - To support Python 2 and 3 with a single code base, define a __str__ method - returning text and apply this decorator to the class. - """ - if PY2: - if "__str__" not in klass.__dict__: - raise ValueError( - "@python_2_unicode_compatible cannot be applied " - "to %s because it doesn't define __str__()." % klass.__name__ - ) - klass.__unicode__ = klass.__str__ - klass.__str__ = lambda self: self.__unicode__().encode("utf-8") - return klass - - -# Complete the moves implementation. -# This code is at the end of this module to speed up module loading. -# Turn this module into a package. -__path__ = [] # required for PEP 302 and PEP 451 -__package__ = __name__ # see PEP 366 @ReservedAssignment -if globals().get("__spec__") is not None: - __spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable -# Remove other six meta path importers, since they cause problems. This can -# happen if six is removed from sys.modules and then reloaded. (Setuptools does -# this for some reason.) -if sys.meta_path: - for i, importer in enumerate(sys.meta_path): - # Here's some real nastiness: Another "instance" of the six module might - # be floating around. Therefore, we can't use isinstance() to check for - # the six meta path importer, since the other six instance will have - # inserted an importer with different class. - if ( - type(importer).__name__ == "_SixMetaPathImporter" - and importer.name == __name__ - ): - del sys.meta_path[i] - break - del i, importer -# Finally, add the importer to the meta path import hook. -sys.meta_path.append(_importer) diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/packages/ssl_match_hostname/__init__.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/packages/ssl_match_hostname/__init__.py deleted file mode 100644 index ef3fde5206..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/packages/ssl_match_hostname/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ -import sys - -try: - # Our match_hostname function is the same as 3.10's, so we only want to - # import the match_hostname function if it's at least that good. - # We also fallback on Python 3.10+ because our code doesn't emit - # deprecation warnings and is the same as Python 3.10 otherwise. - if sys.version_info < (3, 5) or sys.version_info >= (3, 10): - raise ImportError("Fallback to vendored code") - - from ssl import CertificateError, match_hostname -except ImportError: - try: - # Backport of the function from a pypi module - from backports.ssl_match_hostname import ( # type: ignore - CertificateError, - match_hostname, - ) - except ImportError: - # Our vendored copy - from ._implementation import CertificateError, match_hostname # type: ignore - -# Not needed, but documenting what we provide. -__all__ = ("CertificateError", "match_hostname") diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/packages/ssl_match_hostname/_implementation.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/packages/ssl_match_hostname/_implementation.py deleted file mode 100644 index 689208d3c6..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/packages/ssl_match_hostname/_implementation.py +++ /dev/null @@ -1,160 +0,0 @@ -"""The match_hostname() function from Python 3.3.3, essential when using SSL.""" - -# Note: This file is under the PSF license as the code comes from the python -# stdlib. http://docs.python.org/3/license.html - -import re -import sys - -# ipaddress has been backported to 2.6+ in pypi. If it is installed on the -# system, use it to handle IPAddress ServerAltnames (this was added in -# python-3.5) otherwise only do DNS matching. This allows -# backports.ssl_match_hostname to continue to be used in Python 2.7. -try: - import ipaddress -except ImportError: - ipaddress = None - -__version__ = "3.5.0.1" - - -class CertificateError(ValueError): - pass - - -def _dnsname_match(dn, hostname, max_wildcards=1): - """Matching according to RFC 6125, section 6.4.3 - - http://tools.ietf.org/html/rfc6125#section-6.4.3 - """ - pats = [] - if not dn: - return False - - # Ported from python3-syntax: - # leftmost, *remainder = dn.split(r'.') - parts = dn.split(r".") - leftmost = parts[0] - remainder = parts[1:] - - wildcards = leftmost.count("*") - if wildcards > max_wildcards: - # Issue #17980: avoid denials of service by refusing more - # than one wildcard per fragment. A survey of established - # policy among SSL implementations showed it to be a - # reasonable choice. - raise CertificateError( - "too many wildcards in certificate DNS name: " + repr(dn) - ) - - # speed up common case w/o wildcards - if not wildcards: - return dn.lower() == hostname.lower() - - # RFC 6125, section 6.4.3, subitem 1. - # The client SHOULD NOT attempt to match a presented identifier in which - # the wildcard character comprises a label other than the left-most label. - if leftmost == "*": - # When '*' is a fragment by itself, it matches a non-empty dotless - # fragment. - pats.append("[^.]+") - elif leftmost.startswith("xn--") or hostname.startswith("xn--"): - # RFC 6125, section 6.4.3, subitem 3. - # The client SHOULD NOT attempt to match a presented identifier - # where the wildcard character is embedded within an A-label or - # U-label of an internationalized domain name. - pats.append(re.escape(leftmost)) - else: - # Otherwise, '*' matches any dotless string, e.g. www* - pats.append(re.escape(leftmost).replace(r"\*", "[^.]*")) - - # add the remaining fragments, ignore any wildcards - for frag in remainder: - pats.append(re.escape(frag)) - - pat = re.compile(r"\A" + r"\.".join(pats) + r"\Z", re.IGNORECASE) - return pat.match(hostname) - - -def _to_unicode(obj): - if isinstance(obj, str) and sys.version_info < (3,): - obj = unicode(obj, encoding="ascii", errors="strict") - return obj - - -def _ipaddress_match(ipname, host_ip): - """Exact matching of IP addresses. - - RFC 6125 explicitly doesn't define an algorithm for this - (section 1.7.2 - "Out of Scope"). - """ - # OpenSSL may add a trailing newline to a subjectAltName's IP address - # Divergence from upstream: ipaddress can't handle byte str - ip = ipaddress.ip_address(_to_unicode(ipname).rstrip()) - return ip == host_ip - - -def match_hostname(cert, hostname): - """Verify that *cert* (in decoded format as returned by - SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125 - rules are followed, but IP addresses are not accepted for *hostname*. - - CertificateError is raised on failure. On success, the function - returns nothing. - """ - if not cert: - raise ValueError( - "empty or no certificate, match_hostname needs a " - "SSL socket or SSL context with either " - "CERT_OPTIONAL or CERT_REQUIRED" - ) - try: - # Divergence from upstream: ipaddress can't handle byte str - host_ip = ipaddress.ip_address(_to_unicode(hostname)) - except ValueError: - # Not an IP address (common case) - host_ip = None - except UnicodeError: - # Divergence from upstream: Have to deal with ipaddress not taking - # byte strings. addresses should be all ascii, so we consider it not - # an ipaddress in this case - host_ip = None - except AttributeError: - # Divergence from upstream: Make ipaddress library optional - if ipaddress is None: - host_ip = None - else: - raise - dnsnames = [] - san = cert.get("subjectAltName", ()) - for key, value in san: - if key == "DNS": - if host_ip is None and _dnsname_match(value, hostname): - return - dnsnames.append(value) - elif key == "IP Address": - if host_ip is not None and _ipaddress_match(value, host_ip): - return - dnsnames.append(value) - if not dnsnames: - # The subject is only checked when there is no dNSName entry - # in subjectAltName - for sub in cert.get("subject", ()): - for key, value in sub: - # XXX according to RFC 2818, the most specific Common Name - # must be used. - if key == "commonName": - if _dnsname_match(value, hostname): - return - dnsnames.append(value) - if len(dnsnames) > 1: - raise CertificateError( - "hostname %r " - "doesn't match either of %s" % (hostname, ", ".join(map(repr, dnsnames))) - ) - elif len(dnsnames) == 1: - raise CertificateError("hostname %r doesn't match %r" % (hostname, dnsnames[0])) - else: - raise CertificateError( - "no appropriate commonName or subjectAltName fields were found" - ) diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/poolmanager.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/poolmanager.py deleted file mode 100644 index 3a31a285bf..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/poolmanager.py +++ /dev/null @@ -1,536 +0,0 @@ -from __future__ import absolute_import - -import collections -import functools -import logging - -from ._collections import RecentlyUsedContainer -from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool, port_by_scheme -from .exceptions import ( - LocationValueError, - MaxRetryError, - ProxySchemeUnknown, - ProxySchemeUnsupported, - URLSchemeUnknown, -) -from .packages import six -from .packages.six.moves.urllib.parse import urljoin -from .request import RequestMethods -from .util.proxy import connection_requires_http_tunnel -from .util.retry import Retry -from .util.url import parse_url - -__all__ = ["PoolManager", "ProxyManager", "proxy_from_url"] - - -log = logging.getLogger(__name__) - -SSL_KEYWORDS = ( - "key_file", - "cert_file", - "cert_reqs", - "ca_certs", - "ssl_version", - "ca_cert_dir", - "ssl_context", - "key_password", -) - -# All known keyword arguments that could be provided to the pool manager, its -# pools, or the underlying connections. This is used to construct a pool key. -_key_fields = ( - "key_scheme", # str - "key_host", # str - "key_port", # int - "key_timeout", # int or float or Timeout - "key_retries", # int or Retry - "key_strict", # bool - "key_block", # bool - "key_source_address", # str - "key_key_file", # str - "key_key_password", # str - "key_cert_file", # str - "key_cert_reqs", # str - "key_ca_certs", # str - "key_ssl_version", # str - "key_ca_cert_dir", # str - "key_ssl_context", # instance of ssl.SSLContext or urllib3.util.ssl_.SSLContext - "key_maxsize", # int - "key_headers", # dict - "key__proxy", # parsed proxy url - "key__proxy_headers", # dict - "key__proxy_config", # class - "key_socket_options", # list of (level (int), optname (int), value (int or str)) tuples - "key__socks_options", # dict - "key_assert_hostname", # bool or string - "key_assert_fingerprint", # str - "key_server_hostname", # str -) - -#: The namedtuple class used to construct keys for the connection pool. -#: All custom key schemes should include the fields in this key at a minimum. -PoolKey = collections.namedtuple("PoolKey", _key_fields) - -_proxy_config_fields = ("ssl_context", "use_forwarding_for_https") -ProxyConfig = collections.namedtuple("ProxyConfig", _proxy_config_fields) - - -def _default_key_normalizer(key_class, request_context): - """ - Create a pool key out of a request context dictionary. - - According to RFC 3986, both the scheme and host are case-insensitive. - Therefore, this function normalizes both before constructing the pool - key for an HTTPS request. If you wish to change this behaviour, provide - alternate callables to ``key_fn_by_scheme``. - - :param key_class: - The class to use when constructing the key. This should be a namedtuple - with the ``scheme`` and ``host`` keys at a minimum. - :type key_class: namedtuple - :param request_context: - A dictionary-like object that contain the context for a request. - :type request_context: dict - - :return: A namedtuple that can be used as a connection pool key. - :rtype: PoolKey - """ - # Since we mutate the dictionary, make a copy first - context = request_context.copy() - context["scheme"] = context["scheme"].lower() - context["host"] = context["host"].lower() - - # These are both dictionaries and need to be transformed into frozensets - for key in ("headers", "_proxy_headers", "_socks_options"): - if key in context and context[key] is not None: - context[key] = frozenset(context[key].items()) - - # The socket_options key may be a list and needs to be transformed into a - # tuple. - socket_opts = context.get("socket_options") - if socket_opts is not None: - context["socket_options"] = tuple(socket_opts) - - # Map the kwargs to the names in the namedtuple - this is necessary since - # namedtuples can't have fields starting with '_'. - for key in list(context.keys()): - context["key_" + key] = context.pop(key) - - # Default to ``None`` for keys missing from the context - for field in key_class._fields: - if field not in context: - context[field] = None - - return key_class(**context) - - -#: A dictionary that maps a scheme to a callable that creates a pool key. -#: This can be used to alter the way pool keys are constructed, if desired. -#: Each PoolManager makes a copy of this dictionary so they can be configured -#: globally here, or individually on the instance. -key_fn_by_scheme = { - "http": functools.partial(_default_key_normalizer, PoolKey), - "https": functools.partial(_default_key_normalizer, PoolKey), -} - -pool_classes_by_scheme = {"http": HTTPConnectionPool, "https": HTTPSConnectionPool} - - -class PoolManager(RequestMethods): - """ - Allows for arbitrary requests while transparently keeping track of - necessary connection pools for you. - - :param num_pools: - Number of connection pools to cache before discarding the least - recently used pool. - - :param headers: - Headers to include with all requests, unless other headers are given - explicitly. - - :param \\**connection_pool_kw: - Additional parameters are used to create fresh - :class:`urllib3.connectionpool.ConnectionPool` instances. - - Example:: - - >>> manager = PoolManager(num_pools=2) - >>> r = manager.request('GET', 'http://google.com/') - >>> r = manager.request('GET', 'http://google.com/mail') - >>> r = manager.request('GET', 'http://yahoo.com/') - >>> len(manager.pools) - 2 - - """ - - proxy = None - proxy_config = None - - def __init__(self, num_pools=10, headers=None, **connection_pool_kw): - RequestMethods.__init__(self, headers) - self.connection_pool_kw = connection_pool_kw - self.pools = RecentlyUsedContainer(num_pools, dispose_func=lambda p: p.close()) - - # Locally set the pool classes and keys so other PoolManagers can - # override them. - self.pool_classes_by_scheme = pool_classes_by_scheme - self.key_fn_by_scheme = key_fn_by_scheme.copy() - - def __enter__(self): - return self - - def __exit__(self, exc_type, exc_val, exc_tb): - self.clear() - # Return False to re-raise any potential exceptions - return False - - def _new_pool(self, scheme, host, port, request_context=None): - """ - Create a new :class:`urllib3.connectionpool.ConnectionPool` based on host, port, scheme, and - any additional pool keyword arguments. - - If ``request_context`` is provided, it is provided as keyword arguments - to the pool class used. This method is used to actually create the - connection pools handed out by :meth:`connection_from_url` and - companion methods. It is intended to be overridden for customization. - """ - pool_cls = self.pool_classes_by_scheme[scheme] - if request_context is None: - request_context = self.connection_pool_kw.copy() - - # Although the context has everything necessary to create the pool, - # this function has historically only used the scheme, host, and port - # in the positional args. When an API change is acceptable these can - # be removed. - for key in ("scheme", "host", "port"): - request_context.pop(key, None) - - if scheme == "http": - for kw in SSL_KEYWORDS: - request_context.pop(kw, None) - - return pool_cls(host, port, **request_context) - - def clear(self): - """ - Empty our store of pools and direct them all to close. - - This will not affect in-flight connections, but they will not be - re-used after completion. - """ - self.pools.clear() - - def connection_from_host(self, host, port=None, scheme="http", pool_kwargs=None): - """ - Get a :class:`urllib3.connectionpool.ConnectionPool` based on the host, port, and scheme. - - If ``port`` isn't given, it will be derived from the ``scheme`` using - ``urllib3.connectionpool.port_by_scheme``. If ``pool_kwargs`` is - provided, it is merged with the instance's ``connection_pool_kw`` - variable and used to create the new connection pool, if one is - needed. - """ - - if not host: - raise LocationValueError("No host specified.") - - request_context = self._merge_pool_kwargs(pool_kwargs) - request_context["scheme"] = scheme or "http" - if not port: - port = port_by_scheme.get(request_context["scheme"].lower(), 80) - request_context["port"] = port - request_context["host"] = host - - return self.connection_from_context(request_context) - - def connection_from_context(self, request_context): - """ - Get a :class:`urllib3.connectionpool.ConnectionPool` based on the request context. - - ``request_context`` must at least contain the ``scheme`` key and its - value must be a key in ``key_fn_by_scheme`` instance variable. - """ - scheme = request_context["scheme"].lower() - pool_key_constructor = self.key_fn_by_scheme.get(scheme) - if not pool_key_constructor: - raise URLSchemeUnknown(scheme) - pool_key = pool_key_constructor(request_context) - - return self.connection_from_pool_key(pool_key, request_context=request_context) - - def connection_from_pool_key(self, pool_key, request_context=None): - """ - Get a :class:`urllib3.connectionpool.ConnectionPool` based on the provided pool key. - - ``pool_key`` should be a namedtuple that only contains immutable - objects. At a minimum it must have the ``scheme``, ``host``, and - ``port`` fields. - """ - with self.pools.lock: - # If the scheme, host, or port doesn't match existing open - # connections, open a new ConnectionPool. - pool = self.pools.get(pool_key) - if pool: - return pool - - # Make a fresh ConnectionPool of the desired type - scheme = request_context["scheme"] - host = request_context["host"] - port = request_context["port"] - pool = self._new_pool(scheme, host, port, request_context=request_context) - self.pools[pool_key] = pool - - return pool - - def connection_from_url(self, url, pool_kwargs=None): - """ - Similar to :func:`urllib3.connectionpool.connection_from_url`. - - If ``pool_kwargs`` is not provided and a new pool needs to be - constructed, ``self.connection_pool_kw`` is used to initialize - the :class:`urllib3.connectionpool.ConnectionPool`. If ``pool_kwargs`` - is provided, it is used instead. Note that if a new pool does not - need to be created for the request, the provided ``pool_kwargs`` are - not used. - """ - u = parse_url(url) - return self.connection_from_host( - u.host, port=u.port, scheme=u.scheme, pool_kwargs=pool_kwargs - ) - - def _merge_pool_kwargs(self, override): - """ - Merge a dictionary of override values for self.connection_pool_kw. - - This does not modify self.connection_pool_kw and returns a new dict. - Any keys in the override dictionary with a value of ``None`` are - removed from the merged dictionary. - """ - base_pool_kwargs = self.connection_pool_kw.copy() - if override: - for key, value in override.items(): - if value is None: - try: - del base_pool_kwargs[key] - except KeyError: - pass - else: - base_pool_kwargs[key] = value - return base_pool_kwargs - - def _proxy_requires_url_absolute_form(self, parsed_url): - """ - Indicates if the proxy requires the complete destination URL in the - request. Normally this is only needed when not using an HTTP CONNECT - tunnel. - """ - if self.proxy is None: - return False - - return not connection_requires_http_tunnel( - self.proxy, self.proxy_config, parsed_url.scheme - ) - - def _validate_proxy_scheme_url_selection(self, url_scheme): - """ - Validates that were not attempting to do TLS in TLS connections on - Python2 or with unsupported SSL implementations. - """ - if self.proxy is None or url_scheme != "https": - return - - if self.proxy.scheme != "https": - return - - if six.PY2 and not self.proxy_config.use_forwarding_for_https: - raise ProxySchemeUnsupported( - "Contacting HTTPS destinations through HTTPS proxies " - "'via CONNECT tunnels' is not supported in Python 2" - ) - - def urlopen(self, method, url, redirect=True, **kw): - """ - Same as :meth:`urllib3.HTTPConnectionPool.urlopen` - with custom cross-host redirect logic and only sends the request-uri - portion of the ``url``. - - The given ``url`` parameter must be absolute, such that an appropriate - :class:`urllib3.connectionpool.ConnectionPool` can be chosen for it. - """ - u = parse_url(url) - self._validate_proxy_scheme_url_selection(u.scheme) - - conn = self.connection_from_host(u.host, port=u.port, scheme=u.scheme) - - kw["assert_same_host"] = False - kw["redirect"] = False - - if "headers" not in kw: - kw["headers"] = self.headers.copy() - - if self._proxy_requires_url_absolute_form(u): - response = conn.urlopen(method, url, **kw) - else: - response = conn.urlopen(method, u.request_uri, **kw) - - redirect_location = redirect and response.get_redirect_location() - if not redirect_location: - return response - - # Support relative URLs for redirecting. - redirect_location = urljoin(url, redirect_location) - - # RFC 7231, Section 6.4.4 - if response.status == 303: - method = "GET" - - retries = kw.get("retries") - if not isinstance(retries, Retry): - retries = Retry.from_int(retries, redirect=redirect) - - # Strip headers marked as unsafe to forward to the redirected location. - # Check remove_headers_on_redirect to avoid a potential network call within - # conn.is_same_host() which may use socket.gethostbyname() in the future. - if retries.remove_headers_on_redirect and not conn.is_same_host( - redirect_location - ): - headers = list(six.iterkeys(kw["headers"])) - for header in headers: - if header.lower() in retries.remove_headers_on_redirect: - kw["headers"].pop(header, None) - - try: - retries = retries.increment(method, url, response=response, _pool=conn) - except MaxRetryError: - if retries.raise_on_redirect: - response.drain_conn() - raise - return response - - kw["retries"] = retries - kw["redirect"] = redirect - - log.info("Redirecting %s -> %s", url, redirect_location) - - response.drain_conn() - return self.urlopen(method, redirect_location, **kw) - - -class ProxyManager(PoolManager): - """ - Behaves just like :class:`PoolManager`, but sends all requests through - the defined proxy, using the CONNECT method for HTTPS URLs. - - :param proxy_url: - The URL of the proxy to be used. - - :param proxy_headers: - A dictionary containing headers that will be sent to the proxy. In case - of HTTP they are being sent with each request, while in the - HTTPS/CONNECT case they are sent only once. Could be used for proxy - authentication. - - :param proxy_ssl_context: - The proxy SSL context is used to establish the TLS connection to the - proxy when using HTTPS proxies. - - :param use_forwarding_for_https: - (Defaults to False) If set to True will forward requests to the HTTPS - proxy to be made on behalf of the client instead of creating a TLS - tunnel via the CONNECT method. **Enabling this flag means that request - and response headers and content will be visible from the HTTPS proxy** - whereas tunneling keeps request and response headers and content - private. IP address, target hostname, SNI, and port are always visible - to an HTTPS proxy even when this flag is disabled. - - Example: - >>> proxy = urllib3.ProxyManager('http://localhost:3128/') - >>> r1 = proxy.request('GET', 'http://google.com/') - >>> r2 = proxy.request('GET', 'http://httpbin.org/') - >>> len(proxy.pools) - 1 - >>> r3 = proxy.request('GET', 'https://httpbin.org/') - >>> r4 = proxy.request('GET', 'https://twitter.com/') - >>> len(proxy.pools) - 3 - - """ - - def __init__( - self, - proxy_url, - num_pools=10, - headers=None, - proxy_headers=None, - proxy_ssl_context=None, - use_forwarding_for_https=False, - **connection_pool_kw - ): - - if isinstance(proxy_url, HTTPConnectionPool): - proxy_url = "%s://%s:%i" % ( - proxy_url.scheme, - proxy_url.host, - proxy_url.port, - ) - proxy = parse_url(proxy_url) - - if proxy.scheme not in ("http", "https"): - raise ProxySchemeUnknown(proxy.scheme) - - if not proxy.port: - port = port_by_scheme.get(proxy.scheme, 80) - proxy = proxy._replace(port=port) - - self.proxy = proxy - self.proxy_headers = proxy_headers or {} - self.proxy_ssl_context = proxy_ssl_context - self.proxy_config = ProxyConfig(proxy_ssl_context, use_forwarding_for_https) - - connection_pool_kw["_proxy"] = self.proxy - connection_pool_kw["_proxy_headers"] = self.proxy_headers - connection_pool_kw["_proxy_config"] = self.proxy_config - - super(ProxyManager, self).__init__(num_pools, headers, **connection_pool_kw) - - def connection_from_host(self, host, port=None, scheme="http", pool_kwargs=None): - if scheme == "https": - return super(ProxyManager, self).connection_from_host( - host, port, scheme, pool_kwargs=pool_kwargs - ) - - return super(ProxyManager, self).connection_from_host( - self.proxy.host, self.proxy.port, self.proxy.scheme, pool_kwargs=pool_kwargs - ) - - def _set_proxy_headers(self, url, headers=None): - """ - Sets headers needed by proxies: specifically, the Accept and Host - headers. Only sets headers not provided by the user. - """ - headers_ = {"Accept": "*/*"} - - netloc = parse_url(url).netloc - if netloc: - headers_["Host"] = netloc - - if headers: - headers_.update(headers) - return headers_ - - def urlopen(self, method, url, redirect=True, **kw): - "Same as HTTP(S)ConnectionPool.urlopen, ``url`` must be absolute." - u = parse_url(url) - if not connection_requires_http_tunnel(self.proxy, self.proxy_config, u.scheme): - # For connections using HTTP CONNECT, httplib sets the necessary - # headers on the CONNECT to the proxy. If we're not using CONNECT, - # we'll definitely need to set 'Host' at the very least. - headers = kw.get("headers", self.headers) - kw["headers"] = self._set_proxy_headers(url, headers) - - return super(ProxyManager, self).urlopen(method, url, redirect=redirect, **kw) - - -def proxy_from_url(url, **kw): - return ProxyManager(proxy_url=url, **kw) diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/request.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/request.py deleted file mode 100644 index 398386a5b9..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/request.py +++ /dev/null @@ -1,170 +0,0 @@ -from __future__ import absolute_import - -from .filepost import encode_multipart_formdata -from .packages.six.moves.urllib.parse import urlencode - -__all__ = ["RequestMethods"] - - -class RequestMethods(object): - """ - Convenience mixin for classes who implement a :meth:`urlopen` method, such - as :class:`urllib3.HTTPConnectionPool` and - :class:`urllib3.PoolManager`. - - Provides behavior for making common types of HTTP request methods and - decides which type of request field encoding to use. - - Specifically, - - :meth:`.request_encode_url` is for sending requests whose fields are - encoded in the URL (such as GET, HEAD, DELETE). - - :meth:`.request_encode_body` is for sending requests whose fields are - encoded in the *body* of the request using multipart or www-form-urlencoded - (such as for POST, PUT, PATCH). - - :meth:`.request` is for making any kind of request, it will look up the - appropriate encoding format and use one of the above two methods to make - the request. - - Initializer parameters: - - :param headers: - Headers to include with all requests, unless other headers are given - explicitly. - """ - - _encode_url_methods = {"DELETE", "GET", "HEAD", "OPTIONS"} - - def __init__(self, headers=None): - self.headers = headers or {} - - def urlopen( - self, - method, - url, - body=None, - headers=None, - encode_multipart=True, - multipart_boundary=None, - **kw - ): # Abstract - raise NotImplementedError( - "Classes extending RequestMethods must implement " - "their own ``urlopen`` method." - ) - - def request(self, method, url, fields=None, headers=None, **urlopen_kw): - """ - Make a request using :meth:`urlopen` with the appropriate encoding of - ``fields`` based on the ``method`` used. - - This is a convenience method that requires the least amount of manual - effort. It can be used in most situations, while still having the - option to drop down to more specific methods when necessary, such as - :meth:`request_encode_url`, :meth:`request_encode_body`, - or even the lowest level :meth:`urlopen`. - """ - method = method.upper() - - urlopen_kw["request_url"] = url - - if method in self._encode_url_methods: - return self.request_encode_url( - method, url, fields=fields, headers=headers, **urlopen_kw - ) - else: - return self.request_encode_body( - method, url, fields=fields, headers=headers, **urlopen_kw - ) - - def request_encode_url(self, method, url, fields=None, headers=None, **urlopen_kw): - """ - Make a request using :meth:`urlopen` with the ``fields`` encoded in - the url. This is useful for request methods like GET, HEAD, DELETE, etc. - """ - if headers is None: - headers = self.headers - - extra_kw = {"headers": headers} - extra_kw.update(urlopen_kw) - - if fields: - url += "?" + urlencode(fields) - - return self.urlopen(method, url, **extra_kw) - - def request_encode_body( - self, - method, - url, - fields=None, - headers=None, - encode_multipart=True, - multipart_boundary=None, - **urlopen_kw - ): - """ - Make a request using :meth:`urlopen` with the ``fields`` encoded in - the body. This is useful for request methods like POST, PUT, PATCH, etc. - - When ``encode_multipart=True`` (default), then - :func:`urllib3.encode_multipart_formdata` is used to encode - the payload with the appropriate content type. Otherwise - :func:`urllib.parse.urlencode` is used with the - 'application/x-www-form-urlencoded' content type. - - Multipart encoding must be used when posting files, and it's reasonably - safe to use it in other times too. However, it may break request - signing, such as with OAuth. - - Supports an optional ``fields`` parameter of key/value strings AND - key/filetuple. A filetuple is a (filename, data, MIME type) tuple where - the MIME type is optional. For example:: - - fields = { - 'foo': 'bar', - 'fakefile': ('foofile.txt', 'contents of foofile'), - 'realfile': ('barfile.txt', open('realfile').read()), - 'typedfile': ('bazfile.bin', open('bazfile').read(), - 'image/jpeg'), - 'nonamefile': 'contents of nonamefile field', - } - - When uploading a file, providing a filename (the first parameter of the - tuple) is optional but recommended to best mimic behavior of browsers. - - Note that if ``headers`` are supplied, the 'Content-Type' header will - be overwritten because it depends on the dynamic random boundary string - which is used to compose the body of the request. The random boundary - string can be explicitly set with the ``multipart_boundary`` parameter. - """ - if headers is None: - headers = self.headers - - extra_kw = {"headers": {}} - - if fields: - if "body" in urlopen_kw: - raise TypeError( - "request got values for both 'fields' and 'body', can only specify one." - ) - - if encode_multipart: - body, content_type = encode_multipart_formdata( - fields, boundary=multipart_boundary - ) - else: - body, content_type = ( - urlencode(fields), - "application/x-www-form-urlencoded", - ) - - extra_kw["body"] = body - extra_kw["headers"] = {"Content-Type": content_type} - - extra_kw["headers"].update(headers) - extra_kw.update(urlopen_kw) - - return self.urlopen(method, url, **extra_kw) diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/response.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/response.py deleted file mode 100644 index 38693f4fc6..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/response.py +++ /dev/null @@ -1,821 +0,0 @@ -from __future__ import absolute_import - -import io -import logging -import zlib -from contextlib import contextmanager -from socket import error as SocketError -from socket import timeout as SocketTimeout - -try: - import brotli -except ImportError: - brotli = None - -from ._collections import HTTPHeaderDict -from .connection import BaseSSLError, HTTPException -from .exceptions import ( - BodyNotHttplibCompatible, - DecodeError, - HTTPError, - IncompleteRead, - InvalidChunkLength, - InvalidHeader, - ProtocolError, - ReadTimeoutError, - ResponseNotChunked, - SSLError, -) -from .packages import six -from .util.response import is_fp_closed, is_response_to_head - -log = logging.getLogger(__name__) - - -class DeflateDecoder(object): - def __init__(self): - self._first_try = True - self._data = b"" - self._obj = zlib.decompressobj() - - def __getattr__(self, name): - return getattr(self._obj, name) - - def decompress(self, data): - if not data: - return data - - if not self._first_try: - return self._obj.decompress(data) - - self._data += data - try: - decompressed = self._obj.decompress(data) - if decompressed: - self._first_try = False - self._data = None - return decompressed - except zlib.error: - self._first_try = False - self._obj = zlib.decompressobj(-zlib.MAX_WBITS) - try: - return self.decompress(self._data) - finally: - self._data = None - - -class GzipDecoderState(object): - - FIRST_MEMBER = 0 - OTHER_MEMBERS = 1 - SWALLOW_DATA = 2 - - -class GzipDecoder(object): - def __init__(self): - self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS) - self._state = GzipDecoderState.FIRST_MEMBER - - def __getattr__(self, name): - return getattr(self._obj, name) - - def decompress(self, data): - ret = bytearray() - if self._state == GzipDecoderState.SWALLOW_DATA or not data: - return bytes(ret) - while True: - try: - ret += self._obj.decompress(data) - except zlib.error: - previous_state = self._state - # Ignore data after the first error - self._state = GzipDecoderState.SWALLOW_DATA - if previous_state == GzipDecoderState.OTHER_MEMBERS: - # Allow trailing garbage acceptable in other gzip clients - return bytes(ret) - raise - data = self._obj.unused_data - if not data: - return bytes(ret) - self._state = GzipDecoderState.OTHER_MEMBERS - self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS) - - -if brotli is not None: - - class BrotliDecoder(object): - # Supports both 'brotlipy' and 'Brotli' packages - # since they share an import name. The top branches - # are for 'brotlipy' and bottom branches for 'Brotli' - def __init__(self): - self._obj = brotli.Decompressor() - if hasattr(self._obj, "decompress"): - self.decompress = self._obj.decompress - else: - self.decompress = self._obj.process - - def flush(self): - if hasattr(self._obj, "flush"): - return self._obj.flush() - return b"" - - -class MultiDecoder(object): - """ - From RFC7231: - If one or more encodings have been applied to a representation, the - sender that applied the encodings MUST generate a Content-Encoding - header field that lists the content codings in the order in which - they were applied. - """ - - def __init__(self, modes): - self._decoders = [_get_decoder(m.strip()) for m in modes.split(",")] - - def flush(self): - return self._decoders[0].flush() - - def decompress(self, data): - for d in reversed(self._decoders): - data = d.decompress(data) - return data - - -def _get_decoder(mode): - if "," in mode: - return MultiDecoder(mode) - - if mode == "gzip": - return GzipDecoder() - - if brotli is not None and mode == "br": - return BrotliDecoder() - - return DeflateDecoder() - - -class HTTPResponse(io.IOBase): - """ - HTTP Response container. - - Backwards-compatible with :class:`http.client.HTTPResponse` but the response ``body`` is - loaded and decoded on-demand when the ``data`` property is accessed. This - class is also compatible with the Python standard library's :mod:`io` - module, and can hence be treated as a readable object in the context of that - framework. - - Extra parameters for behaviour not present in :class:`http.client.HTTPResponse`: - - :param preload_content: - If True, the response's body will be preloaded during construction. - - :param decode_content: - If True, will attempt to decode the body based on the - 'content-encoding' header. - - :param original_response: - When this HTTPResponse wrapper is generated from an :class:`http.client.HTTPResponse` - object, it's convenient to include the original for debug purposes. It's - otherwise unused. - - :param retries: - The retries contains the last :class:`~urllib3.util.retry.Retry` that - was used during the request. - - :param enforce_content_length: - Enforce content length checking. Body returned by server must match - value of Content-Length header, if present. Otherwise, raise error. - """ - - CONTENT_DECODERS = ["gzip", "deflate"] - if brotli is not None: - CONTENT_DECODERS += ["br"] - REDIRECT_STATUSES = [301, 302, 303, 307, 308] - - def __init__( - self, - body="", - headers=None, - status=0, - version=0, - reason=None, - strict=0, - preload_content=True, - decode_content=True, - original_response=None, - pool=None, - connection=None, - msg=None, - retries=None, - enforce_content_length=False, - request_method=None, - request_url=None, - auto_close=True, - ): - - if isinstance(headers, HTTPHeaderDict): - self.headers = headers - else: - self.headers = HTTPHeaderDict(headers) - self.status = status - self.version = version - self.reason = reason - self.strict = strict - self.decode_content = decode_content - self.retries = retries - self.enforce_content_length = enforce_content_length - self.auto_close = auto_close - - self._decoder = None - self._body = None - self._fp = None - self._original_response = original_response - self._fp_bytes_read = 0 - self.msg = msg - self._request_url = request_url - - if body and isinstance(body, (six.string_types, bytes)): - self._body = body - - self._pool = pool - self._connection = connection - - if hasattr(body, "read"): - self._fp = body - - # Are we using the chunked-style of transfer encoding? - self.chunked = False - self.chunk_left = None - tr_enc = self.headers.get("transfer-encoding", "").lower() - # Don't incur the penalty of creating a list and then discarding it - encodings = (enc.strip() for enc in tr_enc.split(",")) - if "chunked" in encodings: - self.chunked = True - - # Determine length of response - self.length_remaining = self._init_length(request_method) - - # If requested, preload the body. - if preload_content and not self._body: - self._body = self.read(decode_content=decode_content) - - def get_redirect_location(self): - """ - Should we redirect and where to? - - :returns: Truthy redirect location string if we got a redirect status - code and valid location. ``None`` if redirect status and no - location. ``False`` if not a redirect status code. - """ - if self.status in self.REDIRECT_STATUSES: - return self.headers.get("location") - - return False - - def release_conn(self): - if not self._pool or not self._connection: - return - - self._pool._put_conn(self._connection) - self._connection = None - - def drain_conn(self): - """ - Read and discard any remaining HTTP response data in the response connection. - - Unread data in the HTTPResponse connection blocks the connection from being released back to the pool. - """ - try: - self.read() - except (HTTPError, SocketError, BaseSSLError, HTTPException): - pass - - @property - def data(self): - # For backwards-compat with earlier urllib3 0.4 and earlier. - if self._body: - return self._body - - if self._fp: - return self.read(cache_content=True) - - @property - def connection(self): - return self._connection - - def isclosed(self): - return is_fp_closed(self._fp) - - def tell(self): - """ - Obtain the number of bytes pulled over the wire so far. May differ from - the amount of content returned by :meth:``urllib3.response.HTTPResponse.read`` - if bytes are encoded on the wire (e.g, compressed). - """ - return self._fp_bytes_read - - def _init_length(self, request_method): - """ - Set initial length value for Response content if available. - """ - length = self.headers.get("content-length") - - if length is not None: - if self.chunked: - # This Response will fail with an IncompleteRead if it can't be - # received as chunked. This method falls back to attempt reading - # the response before raising an exception. - log.warning( - "Received response with both Content-Length and " - "Transfer-Encoding set. This is expressly forbidden " - "by RFC 7230 sec 3.3.2. Ignoring Content-Length and " - "attempting to process response as Transfer-Encoding: " - "chunked." - ) - return None - - try: - # RFC 7230 section 3.3.2 specifies multiple content lengths can - # be sent in a single Content-Length header - # (e.g. Content-Length: 42, 42). This line ensures the values - # are all valid ints and that as long as the `set` length is 1, - # all values are the same. Otherwise, the header is invalid. - lengths = set([int(val) for val in length.split(",")]) - if len(lengths) > 1: - raise InvalidHeader( - "Content-Length contained multiple " - "unmatching values (%s)" % length - ) - length = lengths.pop() - except ValueError: - length = None - else: - if length < 0: - length = None - - # Convert status to int for comparison - # In some cases, httplib returns a status of "_UNKNOWN" - try: - status = int(self.status) - except ValueError: - status = 0 - - # Check for responses that shouldn't include a body - if status in (204, 304) or 100 <= status < 200 or request_method == "HEAD": - length = 0 - - return length - - def _init_decoder(self): - """ - Set-up the _decoder attribute if necessary. - """ - # Note: content-encoding value should be case-insensitive, per RFC 7230 - # Section 3.2 - content_encoding = self.headers.get("content-encoding", "").lower() - if self._decoder is None: - if content_encoding in self.CONTENT_DECODERS: - self._decoder = _get_decoder(content_encoding) - elif "," in content_encoding: - encodings = [ - e.strip() - for e in content_encoding.split(",") - if e.strip() in self.CONTENT_DECODERS - ] - if len(encodings): - self._decoder = _get_decoder(content_encoding) - - DECODER_ERROR_CLASSES = (IOError, zlib.error) - if brotli is not None: - DECODER_ERROR_CLASSES += (brotli.error,) - - def _decode(self, data, decode_content, flush_decoder): - """ - Decode the data passed in and potentially flush the decoder. - """ - if not decode_content: - return data - - try: - if self._decoder: - data = self._decoder.decompress(data) - except self.DECODER_ERROR_CLASSES as e: - content_encoding = self.headers.get("content-encoding", "").lower() - raise DecodeError( - "Received response with content-encoding: %s, but " - "failed to decode it." % content_encoding, - e, - ) - if flush_decoder: - data += self._flush_decoder() - - return data - - def _flush_decoder(self): - """ - Flushes the decoder. Should only be called if the decoder is actually - being used. - """ - if self._decoder: - buf = self._decoder.decompress(b"") - return buf + self._decoder.flush() - - return b"" - - @contextmanager - def _error_catcher(self): - """ - Catch low-level python exceptions, instead re-raising urllib3 - variants, so that low-level exceptions are not leaked in the - high-level api. - - On exit, release the connection back to the pool. - """ - clean_exit = False - - try: - try: - yield - - except SocketTimeout: - # FIXME: Ideally we'd like to include the url in the ReadTimeoutError but - # there is yet no clean way to get at it from this context. - raise ReadTimeoutError(self._pool, None, "Read timed out.") - - except BaseSSLError as e: - # FIXME: Is there a better way to differentiate between SSLErrors? - if "read operation timed out" not in str(e): - # SSL errors related to framing/MAC get wrapped and reraised here - raise SSLError(e) - - raise ReadTimeoutError(self._pool, None, "Read timed out.") - - except (HTTPException, SocketError) as e: - # This includes IncompleteRead. - raise ProtocolError("Connection broken: %r" % e, e) - - # If no exception is thrown, we should avoid cleaning up - # unnecessarily. - clean_exit = True - finally: - # If we didn't terminate cleanly, we need to throw away our - # connection. - if not clean_exit: - # The response may not be closed but we're not going to use it - # anymore so close it now to ensure that the connection is - # released back to the pool. - if self._original_response: - self._original_response.close() - - # Closing the response may not actually be sufficient to close - # everything, so if we have a hold of the connection close that - # too. - if self._connection: - self._connection.close() - - # If we hold the original response but it's closed now, we should - # return the connection back to the pool. - if self._original_response and self._original_response.isclosed(): - self.release_conn() - - def read(self, amt=None, decode_content=None, cache_content=False): - """ - Similar to :meth:`http.client.HTTPResponse.read`, but with two additional - parameters: ``decode_content`` and ``cache_content``. - - :param amt: - How much of the content to read. If specified, caching is skipped - because it doesn't make sense to cache partial content as the full - response. - - :param decode_content: - If True, will attempt to decode the body based on the - 'content-encoding' header. - - :param cache_content: - If True, will save the returned data such that the same result is - returned despite of the state of the underlying file object. This - is useful if you want the ``.data`` property to continue working - after having ``.read()`` the file object. (Overridden if ``amt`` is - set.) - """ - self._init_decoder() - if decode_content is None: - decode_content = self.decode_content - - if self._fp is None: - return - - flush_decoder = False - fp_closed = getattr(self._fp, "closed", False) - - with self._error_catcher(): - if amt is None: - # cStringIO doesn't like amt=None - data = self._fp.read() if not fp_closed else b"" - flush_decoder = True - else: - cache_content = False - data = self._fp.read(amt) if not fp_closed else b"" - if ( - amt != 0 and not data - ): # Platform-specific: Buggy versions of Python. - # Close the connection when no data is returned - # - # This is redundant to what httplib/http.client _should_ - # already do. However, versions of python released before - # December 15, 2012 (http://bugs.python.org/issue16298) do - # not properly close the connection in all cases. There is - # no harm in redundantly calling close. - self._fp.close() - flush_decoder = True - if self.enforce_content_length and self.length_remaining not in ( - 0, - None, - ): - # This is an edge case that httplib failed to cover due - # to concerns of backward compatibility. We're - # addressing it here to make sure IncompleteRead is - # raised during streaming, so all calls with incorrect - # Content-Length are caught. - raise IncompleteRead(self._fp_bytes_read, self.length_remaining) - - if data: - self._fp_bytes_read += len(data) - if self.length_remaining is not None: - self.length_remaining -= len(data) - - data = self._decode(data, decode_content, flush_decoder) - - if cache_content: - self._body = data - - return data - - def stream(self, amt=2 ** 16, decode_content=None): - """ - A generator wrapper for the read() method. A call will block until - ``amt`` bytes have been read from the connection or until the - connection is closed. - - :param amt: - How much of the content to read. The generator will return up to - much data per iteration, but may return less. This is particularly - likely when using compressed data. However, the empty string will - never be returned. - - :param decode_content: - If True, will attempt to decode the body based on the - 'content-encoding' header. - """ - if self.chunked and self.supports_chunked_reads(): - for line in self.read_chunked(amt, decode_content=decode_content): - yield line - else: - while not is_fp_closed(self._fp): - data = self.read(amt=amt, decode_content=decode_content) - - if data: - yield data - - @classmethod - def from_httplib(ResponseCls, r, **response_kw): - """ - Given an :class:`http.client.HTTPResponse` instance ``r``, return a - corresponding :class:`urllib3.response.HTTPResponse` object. - - Remaining parameters are passed to the HTTPResponse constructor, along - with ``original_response=r``. - """ - headers = r.msg - - if not isinstance(headers, HTTPHeaderDict): - if six.PY2: - # Python 2.7 - headers = HTTPHeaderDict.from_httplib(headers) - else: - headers = HTTPHeaderDict(headers.items()) - - # HTTPResponse objects in Python 3 don't have a .strict attribute - strict = getattr(r, "strict", 0) - resp = ResponseCls( - body=r, - headers=headers, - status=r.status, - version=r.version, - reason=r.reason, - strict=strict, - original_response=r, - **response_kw - ) - return resp - - # Backwards-compatibility methods for http.client.HTTPResponse - def getheaders(self): - return self.headers - - def getheader(self, name, default=None): - return self.headers.get(name, default) - - # Backwards compatibility for http.cookiejar - def info(self): - return self.headers - - # Overrides from io.IOBase - def close(self): - if not self.closed: - self._fp.close() - - if self._connection: - self._connection.close() - - if not self.auto_close: - io.IOBase.close(self) - - @property - def closed(self): - if not self.auto_close: - return io.IOBase.closed.__get__(self) - elif self._fp is None: - return True - elif hasattr(self._fp, "isclosed"): - return self._fp.isclosed() - elif hasattr(self._fp, "closed"): - return self._fp.closed - else: - return True - - def fileno(self): - if self._fp is None: - raise IOError("HTTPResponse has no file to get a fileno from") - elif hasattr(self._fp, "fileno"): - return self._fp.fileno() - else: - raise IOError( - "The file-like object this HTTPResponse is wrapped " - "around has no file descriptor" - ) - - def flush(self): - if ( - self._fp is not None - and hasattr(self._fp, "flush") - and not getattr(self._fp, "closed", False) - ): - return self._fp.flush() - - def readable(self): - # This method is required for `io` module compatibility. - return True - - def readinto(self, b): - # This method is required for `io` module compatibility. - temp = self.read(len(b)) - if len(temp) == 0: - return 0 - else: - b[: len(temp)] = temp - return len(temp) - - def supports_chunked_reads(self): - """ - Checks if the underlying file-like object looks like a - :class:`http.client.HTTPResponse` object. We do this by testing for - the fp attribute. If it is present we assume it returns raw chunks as - processed by read_chunked(). - """ - return hasattr(self._fp, "fp") - - def _update_chunk_length(self): - # First, we'll figure out length of a chunk and then - # we'll try to read it from socket. - if self.chunk_left is not None: - return - line = self._fp.fp.readline() - line = line.split(b";", 1)[0] - try: - self.chunk_left = int(line, 16) - except ValueError: - # Invalid chunked protocol response, abort. - self.close() - raise InvalidChunkLength(self, line) - - def _handle_chunk(self, amt): - returned_chunk = None - if amt is None: - chunk = self._fp._safe_read(self.chunk_left) - returned_chunk = chunk - self._fp._safe_read(2) # Toss the CRLF at the end of the chunk. - self.chunk_left = None - elif amt < self.chunk_left: - value = self._fp._safe_read(amt) - self.chunk_left = self.chunk_left - amt - returned_chunk = value - elif amt == self.chunk_left: - value = self._fp._safe_read(amt) - self._fp._safe_read(2) # Toss the CRLF at the end of the chunk. - self.chunk_left = None - returned_chunk = value - else: # amt > self.chunk_left - returned_chunk = self._fp._safe_read(self.chunk_left) - self._fp._safe_read(2) # Toss the CRLF at the end of the chunk. - self.chunk_left = None - return returned_chunk - - def read_chunked(self, amt=None, decode_content=None): - """ - Similar to :meth:`HTTPResponse.read`, but with an additional - parameter: ``decode_content``. - - :param amt: - How much of the content to read. If specified, caching is skipped - because it doesn't make sense to cache partial content as the full - response. - - :param decode_content: - If True, will attempt to decode the body based on the - 'content-encoding' header. - """ - self._init_decoder() - # FIXME: Rewrite this method and make it a class with a better structured logic. - if not self.chunked: - raise ResponseNotChunked( - "Response is not chunked. " - "Header 'transfer-encoding: chunked' is missing." - ) - if not self.supports_chunked_reads(): - raise BodyNotHttplibCompatible( - "Body should be http.client.HTTPResponse like. " - "It should have have an fp attribute which returns raw chunks." - ) - - with self._error_catcher(): - # Don't bother reading the body of a HEAD request. - if self._original_response and is_response_to_head(self._original_response): - self._original_response.close() - return - - # If a response is already read and closed - # then return immediately. - if self._fp.fp is None: - return - - while True: - self._update_chunk_length() - if self.chunk_left == 0: - break - chunk = self._handle_chunk(amt) - decoded = self._decode( - chunk, decode_content=decode_content, flush_decoder=False - ) - if decoded: - yield decoded - - if decode_content: - # On CPython and PyPy, we should never need to flush the - # decoder. However, on Jython we *might* need to, so - # lets defensively do it anyway. - decoded = self._flush_decoder() - if decoded: # Platform-specific: Jython. - yield decoded - - # Chunk content ends with \r\n: discard it. - while True: - line = self._fp.fp.readline() - if not line: - # Some sites may not end with '\r\n'. - break - if line == b"\r\n": - break - - # We read everything; close the "file". - if self._original_response: - self._original_response.close() - - def geturl(self): - """ - Returns the URL that was the source of this response. - If the request that generated this response redirected, this method - will return the final redirect location. - """ - if self.retries is not None and len(self.retries.history): - return self.retries.history[-1].redirect_location - else: - return self._request_url - - def __iter__(self): - buffer = [] - for chunk in self.stream(decode_content=True): - if b"\n" in chunk: - chunk = chunk.split(b"\n") - yield b"".join(buffer) + chunk[0] + b"\n" - for x in chunk[1:-1]: - yield x + b"\n" - if chunk[-1]: - buffer = [chunk[-1]] - else: - buffer = [] - else: - buffer.append(chunk) - if buffer: - yield b"".join(buffer) diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/util/__init__.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/util/__init__.py deleted file mode 100644 index 4547fc522b..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/util/__init__.py +++ /dev/null @@ -1,49 +0,0 @@ -from __future__ import absolute_import - -# For backwards compatibility, provide imports that used to be here. -from .connection import is_connection_dropped -from .request import SKIP_HEADER, SKIPPABLE_HEADERS, make_headers -from .response import is_fp_closed -from .retry import Retry -from .ssl_ import ( - ALPN_PROTOCOLS, - HAS_SNI, - IS_PYOPENSSL, - IS_SECURETRANSPORT, - PROTOCOL_TLS, - SSLContext, - assert_fingerprint, - resolve_cert_reqs, - resolve_ssl_version, - ssl_wrap_socket, -) -from .timeout import Timeout, current_time -from .url import Url, get_host, parse_url, split_first -from .wait import wait_for_read, wait_for_write - -__all__ = ( - "HAS_SNI", - "IS_PYOPENSSL", - "IS_SECURETRANSPORT", - "SSLContext", - "PROTOCOL_TLS", - "ALPN_PROTOCOLS", - "Retry", - "Timeout", - "Url", - "assert_fingerprint", - "current_time", - "is_connection_dropped", - "is_fp_closed", - "get_host", - "parse_url", - "make_headers", - "resolve_cert_reqs", - "resolve_ssl_version", - "split_first", - "ssl_wrap_socket", - "wait_for_read", - "wait_for_write", - "SKIP_HEADER", - "SKIPPABLE_HEADERS", -) diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/util/connection.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/util/connection.py deleted file mode 100644 index bdc240c50c..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/util/connection.py +++ /dev/null @@ -1,150 +0,0 @@ -from __future__ import absolute_import - -import socket - -from urllib3.exceptions import LocationParseError - -from ..contrib import _appengine_environ -from ..packages import six -from .wait import NoWayToWaitForSocketError, wait_for_read - - -def is_connection_dropped(conn): # Platform-specific - """ - Returns True if the connection is dropped and should be closed. - - :param conn: - :class:`http.client.HTTPConnection` object. - - Note: For platforms like AppEngine, this will always return ``False`` to - let the platform handle connection recycling transparently for us. - """ - sock = getattr(conn, "sock", False) - if sock is False: # Platform-specific: AppEngine - return False - if sock is None: # Connection already closed (such as by httplib). - return True - try: - # Returns True if readable, which here means it's been dropped - return wait_for_read(sock, timeout=0.0) - except NoWayToWaitForSocketError: # Platform-specific: AppEngine - return False - - -# This function is copied from socket.py in the Python 2.7 standard -# library test suite. Added to its signature is only `socket_options`. -# One additional modification is that we avoid binding to IPv6 servers -# discovered in DNS if the system doesn't have IPv6 functionality. -def create_connection( - address, - timeout=socket._GLOBAL_DEFAULT_TIMEOUT, - source_address=None, - socket_options=None, -): - """Connect to *address* and return the socket object. - - Convenience function. Connect to *address* (a 2-tuple ``(host, - port)``) and return the socket object. Passing the optional - *timeout* parameter will set the timeout on the socket instance - before attempting to connect. If no *timeout* is supplied, the - global default timeout setting returned by :func:`socket.getdefaulttimeout` - is used. If *source_address* is set it must be a tuple of (host, port) - for the socket to bind as a source address before making the connection. - An host of '' or port 0 tells the OS to use the default. - """ - - host, port = address - if host.startswith("["): - host = host.strip("[]") - err = None - - # Using the value from allowed_gai_family() in the context of getaddrinfo lets - # us select whether to work with IPv4 DNS records, IPv6 records, or both. - # The original create_connection function always returns all records. - family = allowed_gai_family() - - try: - host.encode("idna") - except UnicodeError: - return six.raise_from( - LocationParseError(u"'%s', label empty or too long" % host), None - ) - - for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): - af, socktype, proto, canonname, sa = res - sock = None - try: - sock = socket.socket(af, socktype, proto) - - # If provided, set socket level options before connecting. - _set_socket_options(sock, socket_options) - - if timeout is not socket._GLOBAL_DEFAULT_TIMEOUT: - sock.settimeout(timeout) - if source_address: - sock.bind(source_address) - sock.connect(sa) - return sock - - except socket.error as e: - err = e - if sock is not None: - sock.close() - sock = None - - if err is not None: - raise err - - raise socket.error("getaddrinfo returns an empty list") - - -def _set_socket_options(sock, options): - if options is None: - return - - for opt in options: - sock.setsockopt(*opt) - - -def allowed_gai_family(): - """This function is designed to work in the context of - getaddrinfo, where family=socket.AF_UNSPEC is the default and - will perform a DNS search for both IPv6 and IPv4 records.""" - - family = socket.AF_INET - if HAS_IPV6: - family = socket.AF_UNSPEC - return family - - -def _has_ipv6(host): - """Returns True if the system can bind an IPv6 address.""" - sock = None - has_ipv6 = False - - # App Engine doesn't support IPV6 sockets and actually has a quota on the - # number of sockets that can be used, so just early out here instead of - # creating a socket needlessly. - # See https://github.com/urllib3/urllib3/issues/1446 - if _appengine_environ.is_appengine_sandbox(): - return False - - if socket.has_ipv6: - # has_ipv6 returns true if cPython was compiled with IPv6 support. - # It does not tell us if the system has IPv6 support enabled. To - # determine that we must bind to an IPv6 address. - # https://github.com/urllib3/urllib3/pull/611 - # https://bugs.python.org/issue658327 - try: - sock = socket.socket(socket.AF_INET6) - sock.bind((host, 0)) - has_ipv6 = True - except Exception: - pass - - if sock: - sock.close() - return has_ipv6 - - -HAS_IPV6 = _has_ipv6("::1") diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/util/proxy.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/util/proxy.py deleted file mode 100644 index 34f884d5b3..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/util/proxy.py +++ /dev/null @@ -1,56 +0,0 @@ -from .ssl_ import create_urllib3_context, resolve_cert_reqs, resolve_ssl_version - - -def connection_requires_http_tunnel( - proxy_url=None, proxy_config=None, destination_scheme=None -): - """ - Returns True if the connection requires an HTTP CONNECT through the proxy. - - :param URL proxy_url: - URL of the proxy. - :param ProxyConfig proxy_config: - Proxy configuration from poolmanager.py - :param str destination_scheme: - The scheme of the destination. (i.e https, http, etc) - """ - # If we're not using a proxy, no way to use a tunnel. - if proxy_url is None: - return False - - # HTTP destinations never require tunneling, we always forward. - if destination_scheme == "http": - return False - - # Support for forwarding with HTTPS proxies and HTTPS destinations. - if ( - proxy_url.scheme == "https" - and proxy_config - and proxy_config.use_forwarding_for_https - ): - return False - - # Otherwise always use a tunnel. - return True - - -def create_proxy_ssl_context( - ssl_version, cert_reqs, ca_certs=None, ca_cert_dir=None, ca_cert_data=None -): - """ - Generates a default proxy ssl context if one hasn't been provided by the - user. - """ - ssl_context = create_urllib3_context( - ssl_version=resolve_ssl_version(ssl_version), - cert_reqs=resolve_cert_reqs(cert_reqs), - ) - if ( - not ca_certs - and not ca_cert_dir - and not ca_cert_data - and hasattr(ssl_context, "load_default_certs") - ): - ssl_context.load_default_certs() - - return ssl_context diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/util/queue.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/util/queue.py deleted file mode 100644 index 41784104ee..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/util/queue.py +++ /dev/null @@ -1,22 +0,0 @@ -import collections - -from ..packages import six -from ..packages.six.moves import queue - -if six.PY2: - # Queue is imported for side effects on MS Windows. See issue #229. - import Queue as _unused_module_Queue # noqa: F401 - - -class LifoQueue(queue.Queue): - def _init(self, _): - self.queue = collections.deque() - - def _qsize(self, len=len): - return len(self.queue) - - def _put(self, item): - self.queue.append(item) - - def _get(self): - return self.queue.pop() diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/util/request.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/util/request.py deleted file mode 100644 index 25103383ec..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/util/request.py +++ /dev/null @@ -1,143 +0,0 @@ -from __future__ import absolute_import - -from base64 import b64encode - -from ..exceptions import UnrewindableBodyError -from ..packages.six import b, integer_types - -# Pass as a value within ``headers`` to skip -# emitting some HTTP headers that are added automatically. -# The only headers that are supported are ``Accept-Encoding``, -# ``Host``, and ``User-Agent``. -SKIP_HEADER = "@@@SKIP_HEADER@@@" -SKIPPABLE_HEADERS = frozenset(["accept-encoding", "host", "user-agent"]) - -ACCEPT_ENCODING = "gzip,deflate" -try: - import brotli as _unused_module_brotli # noqa: F401 -except ImportError: - pass -else: - ACCEPT_ENCODING += ",br" - -_FAILEDTELL = object() - - -def make_headers( - keep_alive=None, - accept_encoding=None, - user_agent=None, - basic_auth=None, - proxy_basic_auth=None, - disable_cache=None, -): - """ - Shortcuts for generating request headers. - - :param keep_alive: - If ``True``, adds 'connection: keep-alive' header. - - :param accept_encoding: - Can be a boolean, list, or string. - ``True`` translates to 'gzip,deflate'. - List will get joined by comma. - String will be used as provided. - - :param user_agent: - String representing the user-agent you want, such as - "python-urllib3/0.6" - - :param basic_auth: - Colon-separated username:password string for 'authorization: basic ...' - auth header. - - :param proxy_basic_auth: - Colon-separated username:password string for 'proxy-authorization: basic ...' - auth header. - - :param disable_cache: - If ``True``, adds 'cache-control: no-cache' header. - - Example:: - - >>> make_headers(keep_alive=True, user_agent="Batman/1.0") - {'connection': 'keep-alive', 'user-agent': 'Batman/1.0'} - >>> make_headers(accept_encoding=True) - {'accept-encoding': 'gzip,deflate'} - """ - headers = {} - if accept_encoding: - if isinstance(accept_encoding, str): - pass - elif isinstance(accept_encoding, list): - accept_encoding = ",".join(accept_encoding) - else: - accept_encoding = ACCEPT_ENCODING - headers["accept-encoding"] = accept_encoding - - if user_agent: - headers["user-agent"] = user_agent - - if keep_alive: - headers["connection"] = "keep-alive" - - if basic_auth: - headers["authorization"] = "Basic " + b64encode(b(basic_auth)).decode("utf-8") - - if proxy_basic_auth: - headers["proxy-authorization"] = "Basic " + b64encode( - b(proxy_basic_auth) - ).decode("utf-8") - - if disable_cache: - headers["cache-control"] = "no-cache" - - return headers - - -def set_file_position(body, pos): - """ - If a position is provided, move file to that point. - Otherwise, we'll attempt to record a position for future use. - """ - if pos is not None: - rewind_body(body, pos) - elif getattr(body, "tell", None) is not None: - try: - pos = body.tell() - except (IOError, OSError): - # This differentiates from None, allowing us to catch - # a failed `tell()` later when trying to rewind the body. - pos = _FAILEDTELL - - return pos - - -def rewind_body(body, body_pos): - """ - Attempt to rewind body to a certain position. - Primarily used for request redirects and retries. - - :param body: - File-like object that supports seek. - - :param int pos: - Position to seek to in file. - """ - body_seek = getattr(body, "seek", None) - if body_seek is not None and isinstance(body_pos, integer_types): - try: - body_seek(body_pos) - except (IOError, OSError): - raise UnrewindableBodyError( - "An error occurred when rewinding request body for redirect/retry." - ) - elif body_pos is _FAILEDTELL: - raise UnrewindableBodyError( - "Unable to record file position for rewinding " - "request body during a redirect/retry." - ) - else: - raise ValueError( - "body_pos must be of type integer, instead it was %s." % type(body_pos) - ) diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/util/response.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/util/response.py deleted file mode 100644 index 5ea609cced..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/util/response.py +++ /dev/null @@ -1,107 +0,0 @@ -from __future__ import absolute_import - -from email.errors import MultipartInvariantViolationDefect, StartBoundaryNotFoundDefect - -from ..exceptions import HeaderParsingError -from ..packages.six.moves import http_client as httplib - - -def is_fp_closed(obj): - """ - Checks whether a given file-like object is closed. - - :param obj: - The file-like object to check. - """ - - try: - # Check `isclosed()` first, in case Python3 doesn't set `closed`. - # GH Issue #928 - return obj.isclosed() - except AttributeError: - pass - - try: - # Check via the official file-like-object way. - return obj.closed - except AttributeError: - pass - - try: - # Check if the object is a container for another file-like object that - # gets released on exhaustion (e.g. HTTPResponse). - return obj.fp is None - except AttributeError: - pass - - raise ValueError("Unable to determine whether fp is closed.") - - -def assert_header_parsing(headers): - """ - Asserts whether all headers have been successfully parsed. - Extracts encountered errors from the result of parsing headers. - - Only works on Python 3. - - :param http.client.HTTPMessage headers: Headers to verify. - - :raises urllib3.exceptions.HeaderParsingError: - If parsing errors are found. - """ - - # This will fail silently if we pass in the wrong kind of parameter. - # To make debugging easier add an explicit check. - if not isinstance(headers, httplib.HTTPMessage): - raise TypeError("expected httplib.Message, got {0}.".format(type(headers))) - - defects = getattr(headers, "defects", None) - get_payload = getattr(headers, "get_payload", None) - - unparsed_data = None - if get_payload: - # get_payload is actually email.message.Message.get_payload; - # we're only interested in the result if it's not a multipart message - if not headers.is_multipart(): - payload = get_payload() - - if isinstance(payload, (bytes, str)): - unparsed_data = payload - if defects: - # httplib is assuming a response body is available - # when parsing headers even when httplib only sends - # header data to parse_headers() This results in - # defects on multipart responses in particular. - # See: https://github.com/urllib3/urllib3/issues/800 - - # So we ignore the following defects: - # - StartBoundaryNotFoundDefect: - # The claimed start boundary was never found. - # - MultipartInvariantViolationDefect: - # A message claimed to be a multipart but no subparts were found. - defects = [ - defect - for defect in defects - if not isinstance( - defect, (StartBoundaryNotFoundDefect, MultipartInvariantViolationDefect) - ) - ] - - if defects or unparsed_data: - raise HeaderParsingError(defects=defects, unparsed_data=unparsed_data) - - -def is_response_to_head(response): - """ - Checks whether the request of a response has been a HEAD-request. - Handles the quirks of AppEngine. - - :param http.client.HTTPResponse response: - Response to check if the originating request - used 'HEAD' as a method. - """ - # FIXME: Can we do this somehow without accessing private httplib _method? - method = response._method - if isinstance(method, int): # Platform-specific: Appengine - return method == 3 - return method.upper() == "HEAD" diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/util/retry.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/util/retry.py deleted file mode 100644 index c7dc42f1d6..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/util/retry.py +++ /dev/null @@ -1,602 +0,0 @@ -from __future__ import absolute_import - -import email -import logging -import re -import time -import warnings -from collections import namedtuple -from itertools import takewhile - -from ..exceptions import ( - ConnectTimeoutError, - InvalidHeader, - MaxRetryError, - ProtocolError, - ProxyError, - ReadTimeoutError, - ResponseError, -) -from ..packages import six - -log = logging.getLogger(__name__) - - -# Data structure for representing the metadata of requests that result in a retry. -RequestHistory = namedtuple( - "RequestHistory", ["method", "url", "error", "status", "redirect_location"] -) - - -# TODO: In v2 we can remove this sentinel and metaclass with deprecated options. -_Default = object() - - -class _RetryMeta(type): - @property - def DEFAULT_METHOD_WHITELIST(cls): - warnings.warn( - "Using 'Retry.DEFAULT_METHOD_WHITELIST' is deprecated and " - "will be removed in v2.0. Use 'Retry.DEFAULT_ALLOWED_METHODS' instead", - DeprecationWarning, - ) - return cls.DEFAULT_ALLOWED_METHODS - - @DEFAULT_METHOD_WHITELIST.setter - def DEFAULT_METHOD_WHITELIST(cls, value): - warnings.warn( - "Using 'Retry.DEFAULT_METHOD_WHITELIST' is deprecated and " - "will be removed in v2.0. Use 'Retry.DEFAULT_ALLOWED_METHODS' instead", - DeprecationWarning, - ) - cls.DEFAULT_ALLOWED_METHODS = value - - @property - def DEFAULT_REDIRECT_HEADERS_BLACKLIST(cls): - warnings.warn( - "Using 'Retry.DEFAULT_REDIRECT_HEADERS_BLACKLIST' is deprecated and " - "will be removed in v2.0. Use 'Retry.DEFAULT_REMOVE_HEADERS_ON_REDIRECT' instead", - DeprecationWarning, - ) - return cls.DEFAULT_REMOVE_HEADERS_ON_REDIRECT - - @DEFAULT_REDIRECT_HEADERS_BLACKLIST.setter - def DEFAULT_REDIRECT_HEADERS_BLACKLIST(cls, value): - warnings.warn( - "Using 'Retry.DEFAULT_REDIRECT_HEADERS_BLACKLIST' is deprecated and " - "will be removed in v2.0. Use 'Retry.DEFAULT_REMOVE_HEADERS_ON_REDIRECT' instead", - DeprecationWarning, - ) - cls.DEFAULT_REMOVE_HEADERS_ON_REDIRECT = value - - -@six.add_metaclass(_RetryMeta) -class Retry(object): - """Retry configuration. - - Each retry attempt will create a new Retry object with updated values, so - they can be safely reused. - - Retries can be defined as a default for a pool:: - - retries = Retry(connect=5, read=2, redirect=5) - http = PoolManager(retries=retries) - response = http.request('GET', 'http://example.com/') - - Or per-request (which overrides the default for the pool):: - - response = http.request('GET', 'http://example.com/', retries=Retry(10)) - - Retries can be disabled by passing ``False``:: - - response = http.request('GET', 'http://example.com/', retries=False) - - Errors will be wrapped in :class:`~urllib3.exceptions.MaxRetryError` unless - retries are disabled, in which case the causing exception will be raised. - - :param int total: - Total number of retries to allow. Takes precedence over other counts. - - Set to ``None`` to remove this constraint and fall back on other - counts. - - Set to ``0`` to fail on the first retry. - - Set to ``False`` to disable and imply ``raise_on_redirect=False``. - - :param int connect: - How many connection-related errors to retry on. - - These are errors raised before the request is sent to the remote server, - which we assume has not triggered the server to process the request. - - Set to ``0`` to fail on the first retry of this type. - - :param int read: - How many times to retry on read errors. - - These errors are raised after the request was sent to the server, so the - request may have side-effects. - - Set to ``0`` to fail on the first retry of this type. - - :param int redirect: - How many redirects to perform. Limit this to avoid infinite redirect - loops. - - A redirect is a HTTP response with a status code 301, 302, 303, 307 or - 308. - - Set to ``0`` to fail on the first retry of this type. - - Set to ``False`` to disable and imply ``raise_on_redirect=False``. - - :param int status: - How many times to retry on bad status codes. - - These are retries made on responses, where status code matches - ``status_forcelist``. - - Set to ``0`` to fail on the first retry of this type. - - :param int other: - How many times to retry on other errors. - - Other errors are errors that are not connect, read, redirect or status errors. - These errors might be raised after the request was sent to the server, so the - request might have side-effects. - - Set to ``0`` to fail on the first retry of this type. - - If ``total`` is not set, it's a good idea to set this to 0 to account - for unexpected edge cases and avoid infinite retry loops. - - :param iterable allowed_methods: - Set of uppercased HTTP method verbs that we should retry on. - - By default, we only retry on methods which are considered to be - idempotent (multiple requests with the same parameters end with the - same state). See :attr:`Retry.DEFAULT_ALLOWED_METHODS`. - - Set to a ``False`` value to retry on any verb. - - .. warning:: - - Previously this parameter was named ``method_whitelist``, that - usage is deprecated in v1.26.0 and will be removed in v2.0. - - :param iterable status_forcelist: - A set of integer HTTP status codes that we should force a retry on. - A retry is initiated if the request method is in ``allowed_methods`` - and the response status code is in ``status_forcelist``. - - By default, this is disabled with ``None``. - - :param float backoff_factor: - A backoff factor to apply between attempts after the second try - (most errors are resolved immediately by a second try without a - delay). urllib3 will sleep for:: - - {backoff factor} * (2 ** ({number of total retries} - 1)) - - seconds. If the backoff_factor is 0.1, then :func:`.sleep` will sleep - for [0.0s, 0.2s, 0.4s, ...] between retries. It will never be longer - than :attr:`Retry.BACKOFF_MAX`. - - By default, backoff is disabled (set to 0). - - :param bool raise_on_redirect: Whether, if the number of redirects is - exhausted, to raise a MaxRetryError, or to return a response with a - response code in the 3xx range. - - :param bool raise_on_status: Similar meaning to ``raise_on_redirect``: - whether we should raise an exception, or return a response, - if status falls in ``status_forcelist`` range and retries have - been exhausted. - - :param tuple history: The history of the request encountered during - each call to :meth:`~Retry.increment`. The list is in the order - the requests occurred. Each list item is of class :class:`RequestHistory`. - - :param bool respect_retry_after_header: - Whether to respect Retry-After header on status codes defined as - :attr:`Retry.RETRY_AFTER_STATUS_CODES` or not. - - :param iterable remove_headers_on_redirect: - Sequence of headers to remove from the request when a response - indicating a redirect is returned before firing off the redirected - request. - """ - - #: Default methods to be used for ``allowed_methods`` - DEFAULT_ALLOWED_METHODS = frozenset( - ["HEAD", "GET", "PUT", "DELETE", "OPTIONS", "TRACE"] - ) - - #: Default status codes to be used for ``status_forcelist`` - RETRY_AFTER_STATUS_CODES = frozenset([413, 429, 503]) - - #: Default headers to be used for ``remove_headers_on_redirect`` - DEFAULT_REMOVE_HEADERS_ON_REDIRECT = frozenset(["Authorization"]) - - #: Maximum backoff time. - BACKOFF_MAX = 120 - - def __init__( - self, - total=10, - connect=None, - read=None, - redirect=None, - status=None, - other=None, - allowed_methods=_Default, - status_forcelist=None, - backoff_factor=0, - raise_on_redirect=True, - raise_on_status=True, - history=None, - respect_retry_after_header=True, - remove_headers_on_redirect=_Default, - # TODO: Deprecated, remove in v2.0 - method_whitelist=_Default, - ): - - if method_whitelist is not _Default: - if allowed_methods is not _Default: - raise ValueError( - "Using both 'allowed_methods' and " - "'method_whitelist' together is not allowed. " - "Instead only use 'allowed_methods'" - ) - warnings.warn( - "Using 'method_whitelist' with Retry is deprecated and " - "will be removed in v2.0. Use 'allowed_methods' instead", - DeprecationWarning, - stacklevel=2, - ) - allowed_methods = method_whitelist - if allowed_methods is _Default: - allowed_methods = self.DEFAULT_ALLOWED_METHODS - if remove_headers_on_redirect is _Default: - remove_headers_on_redirect = self.DEFAULT_REMOVE_HEADERS_ON_REDIRECT - - self.total = total - self.connect = connect - self.read = read - self.status = status - self.other = other - - if redirect is False or total is False: - redirect = 0 - raise_on_redirect = False - - self.redirect = redirect - self.status_forcelist = status_forcelist or set() - self.allowed_methods = allowed_methods - self.backoff_factor = backoff_factor - self.raise_on_redirect = raise_on_redirect - self.raise_on_status = raise_on_status - self.history = history or tuple() - self.respect_retry_after_header = respect_retry_after_header - self.remove_headers_on_redirect = frozenset( - [h.lower() for h in remove_headers_on_redirect] - ) - - def new(self, **kw): - params = dict( - total=self.total, - connect=self.connect, - read=self.read, - redirect=self.redirect, - status=self.status, - other=self.other, - status_forcelist=self.status_forcelist, - backoff_factor=self.backoff_factor, - raise_on_redirect=self.raise_on_redirect, - raise_on_status=self.raise_on_status, - history=self.history, - remove_headers_on_redirect=self.remove_headers_on_redirect, - respect_retry_after_header=self.respect_retry_after_header, - ) - - # TODO: If already given in **kw we use what's given to us - # If not given we need to figure out what to pass. We decide - # based on whether our class has the 'method_whitelist' property - # and if so we pass the deprecated 'method_whitelist' otherwise - # we use 'allowed_methods'. Remove in v2.0 - if "method_whitelist" not in kw and "allowed_methods" not in kw: - if "method_whitelist" in self.__dict__: - warnings.warn( - "Using 'method_whitelist' with Retry is deprecated and " - "will be removed in v2.0. Use 'allowed_methods' instead", - DeprecationWarning, - ) - params["method_whitelist"] = self.allowed_methods - else: - params["allowed_methods"] = self.allowed_methods - - params.update(kw) - return type(self)(**params) - - @classmethod - def from_int(cls, retries, redirect=True, default=None): - """Backwards-compatibility for the old retries format.""" - if retries is None: - retries = default if default is not None else cls.DEFAULT - - if isinstance(retries, Retry): - return retries - - redirect = bool(redirect) and None - new_retries = cls(retries, redirect=redirect) - log.debug("Converted retries value: %r -> %r", retries, new_retries) - return new_retries - - def get_backoff_time(self): - """Formula for computing the current backoff - - :rtype: float - """ - # We want to consider only the last consecutive errors sequence (Ignore redirects). - consecutive_errors_len = len( - list( - takewhile(lambda x: x.redirect_location is None, reversed(self.history)) - ) - ) - if consecutive_errors_len <= 1: - return 0 - - backoff_value = self.backoff_factor * (2 ** (consecutive_errors_len - 1)) - return min(self.BACKOFF_MAX, backoff_value) - - def parse_retry_after(self, retry_after): - # Whitespace: https://tools.ietf.org/html/rfc7230#section-3.2.4 - if re.match(r"^\s*[0-9]+\s*$", retry_after): - seconds = int(retry_after) - else: - retry_date_tuple = email.utils.parsedate_tz(retry_after) - if retry_date_tuple is None: - raise InvalidHeader("Invalid Retry-After header: %s" % retry_after) - if retry_date_tuple[9] is None: # Python 2 - # Assume UTC if no timezone was specified - # On Python2.7, parsedate_tz returns None for a timezone offset - # instead of 0 if no timezone is given, where mktime_tz treats - # a None timezone offset as local time. - retry_date_tuple = retry_date_tuple[:9] + (0,) + retry_date_tuple[10:] - - retry_date = email.utils.mktime_tz(retry_date_tuple) - seconds = retry_date - time.time() - - if seconds < 0: - seconds = 0 - - return seconds - - def get_retry_after(self, response): - """Get the value of Retry-After in seconds.""" - - retry_after = response.getheader("Retry-After") - - if retry_after is None: - return None - - return self.parse_retry_after(retry_after) - - def sleep_for_retry(self, response=None): - retry_after = self.get_retry_after(response) - if retry_after: - time.sleep(retry_after) - return True - - return False - - def _sleep_backoff(self): - backoff = self.get_backoff_time() - if backoff <= 0: - return - time.sleep(backoff) - - def sleep(self, response=None): - """Sleep between retry attempts. - - This method will respect a server's ``Retry-After`` response header - and sleep the duration of the time requested. If that is not present, it - will use an exponential backoff. By default, the backoff factor is 0 and - this method will return immediately. - """ - - if self.respect_retry_after_header and response: - slept = self.sleep_for_retry(response) - if slept: - return - - self._sleep_backoff() - - def _is_connection_error(self, err): - """Errors when we're fairly sure that the server did not receive the - request, so it should be safe to retry. - """ - if isinstance(err, ProxyError): - err = err.original_error - return isinstance(err, ConnectTimeoutError) - - def _is_read_error(self, err): - """Errors that occur after the request has been started, so we should - assume that the server began processing it. - """ - return isinstance(err, (ReadTimeoutError, ProtocolError)) - - def _is_method_retryable(self, method): - """Checks if a given HTTP method should be retried upon, depending if - it is included in the allowed_methods - """ - # TODO: For now favor if the Retry implementation sets its own method_whitelist - # property outside of our constructor to avoid breaking custom implementations. - if "method_whitelist" in self.__dict__: - warnings.warn( - "Using 'method_whitelist' with Retry is deprecated and " - "will be removed in v2.0. Use 'allowed_methods' instead", - DeprecationWarning, - ) - allowed_methods = self.method_whitelist - else: - allowed_methods = self.allowed_methods - - if allowed_methods and method.upper() not in allowed_methods: - return False - return True - - def is_retry(self, method, status_code, has_retry_after=False): - """Is this method/status code retryable? (Based on allowlists and control - variables such as the number of total retries to allow, whether to - respect the Retry-After header, whether this header is present, and - whether the returned status code is on the list of status codes to - be retried upon on the presence of the aforementioned header) - """ - if not self._is_method_retryable(method): - return False - - if self.status_forcelist and status_code in self.status_forcelist: - return True - - return ( - self.total - and self.respect_retry_after_header - and has_retry_after - and (status_code in self.RETRY_AFTER_STATUS_CODES) - ) - - def is_exhausted(self): - """Are we out of retries?""" - retry_counts = ( - self.total, - self.connect, - self.read, - self.redirect, - self.status, - self.other, - ) - retry_counts = list(filter(None, retry_counts)) - if not retry_counts: - return False - - return min(retry_counts) < 0 - - def increment( - self, - method=None, - url=None, - response=None, - error=None, - _pool=None, - _stacktrace=None, - ): - """Return a new Retry object with incremented retry counters. - - :param response: A response object, or None, if the server did not - return a response. - :type response: :class:`~urllib3.response.HTTPResponse` - :param Exception error: An error encountered during the request, or - None if the response was received successfully. - - :return: A new ``Retry`` object. - """ - if self.total is False and error: - # Disabled, indicate to re-raise the error. - raise six.reraise(type(error), error, _stacktrace) - - total = self.total - if total is not None: - total -= 1 - - connect = self.connect - read = self.read - redirect = self.redirect - status_count = self.status - other = self.other - cause = "unknown" - status = None - redirect_location = None - - if error and self._is_connection_error(error): - # Connect retry? - if connect is False: - raise six.reraise(type(error), error, _stacktrace) - elif connect is not None: - connect -= 1 - - elif error and self._is_read_error(error): - # Read retry? - if read is False or not self._is_method_retryable(method): - raise six.reraise(type(error), error, _stacktrace) - elif read is not None: - read -= 1 - - elif error: - # Other retry? - if other is not None: - other -= 1 - - elif response and response.get_redirect_location(): - # Redirect retry? - if redirect is not None: - redirect -= 1 - cause = "too many redirects" - redirect_location = response.get_redirect_location() - status = response.status - - else: - # Incrementing because of a server error like a 500 in - # status_forcelist and the given method is in the allowed_methods - cause = ResponseError.GENERIC_ERROR - if response and response.status: - if status_count is not None: - status_count -= 1 - cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) - status = response.status - - history = self.history + ( - RequestHistory(method, url, error, status, redirect_location), - ) - - new_retry = self.new( - total=total, - connect=connect, - read=read, - redirect=redirect, - status=status_count, - other=other, - history=history, - ) - - if new_retry.is_exhausted(): - raise MaxRetryError(_pool, url, error or ResponseError(cause)) - - log.debug("Incremented Retry for (url='%s'): %r", url, new_retry) - - return new_retry - - def __repr__(self): - return ( - "{cls.__name__}(total={self.total}, connect={self.connect}, " - "read={self.read}, redirect={self.redirect}, status={self.status})" - ).format(cls=type(self), self=self) - - def __getattr__(self, item): - if item == "method_whitelist": - # TODO: Remove this deprecated alias in v2.0 - warnings.warn( - "Using 'method_whitelist' with Retry is deprecated and " - "will be removed in v2.0. Use 'allowed_methods' instead", - DeprecationWarning, - ) - return self.allowed_methods - try: - return getattr(super(Retry, self), item) - except AttributeError: - return getattr(Retry, item) - - -# For backwards compatibility (equivalent to pre-v1.9): -Retry.DEFAULT = Retry(3) diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/util/ssl_.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/util/ssl_.py deleted file mode 100644 index 8f867812a5..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/util/ssl_.py +++ /dev/null @@ -1,495 +0,0 @@ -from __future__ import absolute_import - -import hmac -import os -import sys -import warnings -from binascii import hexlify, unhexlify -from hashlib import md5, sha1, sha256 - -from ..exceptions import ( - InsecurePlatformWarning, - ProxySchemeUnsupported, - SNIMissingWarning, - SSLError, -) -from ..packages import six -from .url import BRACELESS_IPV6_ADDRZ_RE, IPV4_RE - -SSLContext = None -SSLTransport = None -HAS_SNI = False -IS_PYOPENSSL = False -IS_SECURETRANSPORT = False -ALPN_PROTOCOLS = ["http/1.1"] - -# Maps the length of a digest to a possible hash function producing this digest -HASHFUNC_MAP = {32: md5, 40: sha1, 64: sha256} - - -def _const_compare_digest_backport(a, b): - """ - Compare two digests of equal length in constant time. - - The digests must be of type str/bytes. - Returns True if the digests match, and False otherwise. - """ - result = abs(len(a) - len(b)) - for left, right in zip(bytearray(a), bytearray(b)): - result |= left ^ right - return result == 0 - - -_const_compare_digest = getattr(hmac, "compare_digest", _const_compare_digest_backport) - -try: # Test for SSL features - import ssl - from ssl import CERT_REQUIRED, wrap_socket -except ImportError: - pass - -try: - from ssl import HAS_SNI # Has SNI? -except ImportError: - pass - -try: - from .ssltransport import SSLTransport -except ImportError: - pass - - -try: # Platform-specific: Python 3.6 - from ssl import PROTOCOL_TLS - - PROTOCOL_SSLv23 = PROTOCOL_TLS -except ImportError: - try: - from ssl import PROTOCOL_SSLv23 as PROTOCOL_TLS - - PROTOCOL_SSLv23 = PROTOCOL_TLS - except ImportError: - PROTOCOL_SSLv23 = PROTOCOL_TLS = 2 - -try: - from ssl import PROTOCOL_TLS_CLIENT -except ImportError: - PROTOCOL_TLS_CLIENT = PROTOCOL_TLS - - -try: - from ssl import OP_NO_COMPRESSION, OP_NO_SSLv2, OP_NO_SSLv3 -except ImportError: - OP_NO_SSLv2, OP_NO_SSLv3 = 0x1000000, 0x2000000 - OP_NO_COMPRESSION = 0x20000 - - -try: # OP_NO_TICKET was added in Python 3.6 - from ssl import OP_NO_TICKET -except ImportError: - OP_NO_TICKET = 0x4000 - - -# A secure default. -# Sources for more information on TLS ciphers: -# -# - https://wiki.mozilla.org/Security/Server_Side_TLS -# - https://www.ssllabs.com/projects/best-practices/index.html -# - https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/ -# -# The general intent is: -# - prefer cipher suites that offer perfect forward secrecy (DHE/ECDHE), -# - prefer ECDHE over DHE for better performance, -# - prefer any AES-GCM and ChaCha20 over any AES-CBC for better performance and -# security, -# - prefer AES-GCM over ChaCha20 because hardware-accelerated AES is common, -# - disable NULL authentication, MD5 MACs, DSS, and other -# insecure ciphers for security reasons. -# - NOTE: TLS 1.3 cipher suites are managed through a different interface -# not exposed by CPython (yet!) and are enabled by default if they're available. -DEFAULT_CIPHERS = ":".join( - [ - "ECDHE+AESGCM", - "ECDHE+CHACHA20", - "DHE+AESGCM", - "DHE+CHACHA20", - "ECDH+AESGCM", - "DH+AESGCM", - "ECDH+AES", - "DH+AES", - "RSA+AESGCM", - "RSA+AES", - "!aNULL", - "!eNULL", - "!MD5", - "!DSS", - ] -) - -try: - from ssl import SSLContext # Modern SSL? -except ImportError: - - class SSLContext(object): # Platform-specific: Python 2 - def __init__(self, protocol_version): - self.protocol = protocol_version - # Use default values from a real SSLContext - self.check_hostname = False - self.verify_mode = ssl.CERT_NONE - self.ca_certs = None - self.options = 0 - self.certfile = None - self.keyfile = None - self.ciphers = None - - def load_cert_chain(self, certfile, keyfile): - self.certfile = certfile - self.keyfile = keyfile - - def load_verify_locations(self, cafile=None, capath=None, cadata=None): - self.ca_certs = cafile - - if capath is not None: - raise SSLError("CA directories not supported in older Pythons") - - if cadata is not None: - raise SSLError("CA data not supported in older Pythons") - - def set_ciphers(self, cipher_suite): - self.ciphers = cipher_suite - - def wrap_socket(self, socket, server_hostname=None, server_side=False): - warnings.warn( - "A true SSLContext object is not available. This prevents " - "urllib3 from configuring SSL appropriately and may cause " - "certain SSL connections to fail. You can upgrade to a newer " - "version of Python to solve this. For more information, see " - "https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html" - "#ssl-warnings", - InsecurePlatformWarning, - ) - kwargs = { - "keyfile": self.keyfile, - "certfile": self.certfile, - "ca_certs": self.ca_certs, - "cert_reqs": self.verify_mode, - "ssl_version": self.protocol, - "server_side": server_side, - } - return wrap_socket(socket, ciphers=self.ciphers, **kwargs) - - -def assert_fingerprint(cert, fingerprint): - """ - Checks if given fingerprint matches the supplied certificate. - - :param cert: - Certificate as bytes object. - :param fingerprint: - Fingerprint as string of hexdigits, can be interspersed by colons. - """ - - fingerprint = fingerprint.replace(":", "").lower() - digest_length = len(fingerprint) - hashfunc = HASHFUNC_MAP.get(digest_length) - if not hashfunc: - raise SSLError("Fingerprint of invalid length: {0}".format(fingerprint)) - - # We need encode() here for py32; works on py2 and p33. - fingerprint_bytes = unhexlify(fingerprint.encode()) - - cert_digest = hashfunc(cert).digest() - - if not _const_compare_digest(cert_digest, fingerprint_bytes): - raise SSLError( - 'Fingerprints did not match. Expected "{0}", got "{1}".'.format( - fingerprint, hexlify(cert_digest) - ) - ) - - -def resolve_cert_reqs(candidate): - """ - Resolves the argument to a numeric constant, which can be passed to - the wrap_socket function/method from the ssl module. - Defaults to :data:`ssl.CERT_REQUIRED`. - If given a string it is assumed to be the name of the constant in the - :mod:`ssl` module or its abbreviation. - (So you can specify `REQUIRED` instead of `CERT_REQUIRED`. - If it's neither `None` nor a string we assume it is already the numeric - constant which can directly be passed to wrap_socket. - """ - if candidate is None: - return CERT_REQUIRED - - if isinstance(candidate, str): - res = getattr(ssl, candidate, None) - if res is None: - res = getattr(ssl, "CERT_" + candidate) - return res - - return candidate - - -def resolve_ssl_version(candidate): - """ - like resolve_cert_reqs - """ - if candidate is None: - return PROTOCOL_TLS - - if isinstance(candidate, str): - res = getattr(ssl, candidate, None) - if res is None: - res = getattr(ssl, "PROTOCOL_" + candidate) - return res - - return candidate - - -def create_urllib3_context( - ssl_version=None, cert_reqs=None, options=None, ciphers=None -): - """All arguments have the same meaning as ``ssl_wrap_socket``. - - By default, this function does a lot of the same work that - ``ssl.create_default_context`` does on Python 3.4+. It: - - - Disables SSLv2, SSLv3, and compression - - Sets a restricted set of server ciphers - - If you wish to enable SSLv3, you can do:: - - from urllib3.util import ssl_ - context = ssl_.create_urllib3_context() - context.options &= ~ssl_.OP_NO_SSLv3 - - You can do the same to enable compression (substituting ``COMPRESSION`` - for ``SSLv3`` in the last line above). - - :param ssl_version: - The desired protocol version to use. This will default to - PROTOCOL_SSLv23 which will negotiate the highest protocol that both - the server and your installation of OpenSSL support. - :param cert_reqs: - Whether to require the certificate verification. This defaults to - ``ssl.CERT_REQUIRED``. - :param options: - Specific OpenSSL options. These default to ``ssl.OP_NO_SSLv2``, - ``ssl.OP_NO_SSLv3``, ``ssl.OP_NO_COMPRESSION``, and ``ssl.OP_NO_TICKET``. - :param ciphers: - Which cipher suites to allow the server to select. - :returns: - Constructed SSLContext object with specified options - :rtype: SSLContext - """ - # PROTOCOL_TLS is deprecated in Python 3.10 - if not ssl_version or ssl_version == PROTOCOL_TLS: - ssl_version = PROTOCOL_TLS_CLIENT - - context = SSLContext(ssl_version) - - context.set_ciphers(ciphers or DEFAULT_CIPHERS) - - # Setting the default here, as we may have no ssl module on import - cert_reqs = ssl.CERT_REQUIRED if cert_reqs is None else cert_reqs - - if options is None: - options = 0 - # SSLv2 is easily broken and is considered harmful and dangerous - options |= OP_NO_SSLv2 - # SSLv3 has several problems and is now dangerous - options |= OP_NO_SSLv3 - # Disable compression to prevent CRIME attacks for OpenSSL 1.0+ - # (issue #309) - options |= OP_NO_COMPRESSION - # TLSv1.2 only. Unless set explicitly, do not request tickets. - # This may save some bandwidth on wire, and although the ticket is encrypted, - # there is a risk associated with it being on wire, - # if the server is not rotating its ticketing keys properly. - options |= OP_NO_TICKET - - context.options |= options - - # Enable post-handshake authentication for TLS 1.3, see GH #1634. PHA is - # necessary for conditional client cert authentication with TLS 1.3. - # The attribute is None for OpenSSL <= 1.1.0 or does not exist in older - # versions of Python. We only enable on Python 3.7.4+ or if certificate - # verification is enabled to work around Python issue #37428 - # See: https://bugs.python.org/issue37428 - if (cert_reqs == ssl.CERT_REQUIRED or sys.version_info >= (3, 7, 4)) and getattr( - context, "post_handshake_auth", None - ) is not None: - context.post_handshake_auth = True - - def disable_check_hostname(): - if ( - getattr(context, "check_hostname", None) is not None - ): # Platform-specific: Python 3.2 - # We do our own verification, including fingerprints and alternative - # hostnames. So disable it here - context.check_hostname = False - - # The order of the below lines setting verify_mode and check_hostname - # matter due to safe-guards SSLContext has to prevent an SSLContext with - # check_hostname=True, verify_mode=NONE/OPTIONAL. This is made even more - # complex because we don't know whether PROTOCOL_TLS_CLIENT will be used - # or not so we don't know the initial state of the freshly created SSLContext. - if cert_reqs == ssl.CERT_REQUIRED: - context.verify_mode = cert_reqs - disable_check_hostname() - else: - disable_check_hostname() - context.verify_mode = cert_reqs - - # Enable logging of TLS session keys via defacto standard environment variable - # 'SSLKEYLOGFILE', if the feature is available (Python 3.8+). Skip empty values. - if hasattr(context, "keylog_filename"): - sslkeylogfile = os.environ.get("SSLKEYLOGFILE") - if sslkeylogfile: - context.keylog_filename = sslkeylogfile - - return context - - -def ssl_wrap_socket( - sock, - keyfile=None, - certfile=None, - cert_reqs=None, - ca_certs=None, - server_hostname=None, - ssl_version=None, - ciphers=None, - ssl_context=None, - ca_cert_dir=None, - key_password=None, - ca_cert_data=None, - tls_in_tls=False, -): - """ - All arguments except for server_hostname, ssl_context, and ca_cert_dir have - the same meaning as they do when using :func:`ssl.wrap_socket`. - - :param server_hostname: - When SNI is supported, the expected hostname of the certificate - :param ssl_context: - A pre-made :class:`SSLContext` object. If none is provided, one will - be created using :func:`create_urllib3_context`. - :param ciphers: - A string of ciphers we wish the client to support. - :param ca_cert_dir: - A directory containing CA certificates in multiple separate files, as - supported by OpenSSL's -CApath flag or the capath argument to - SSLContext.load_verify_locations(). - :param key_password: - Optional password if the keyfile is encrypted. - :param ca_cert_data: - Optional string containing CA certificates in PEM format suitable for - passing as the cadata parameter to SSLContext.load_verify_locations() - :param tls_in_tls: - Use SSLTransport to wrap the existing socket. - """ - context = ssl_context - if context is None: - # Note: This branch of code and all the variables in it are no longer - # used by urllib3 itself. We should consider deprecating and removing - # this code. - context = create_urllib3_context(ssl_version, cert_reqs, ciphers=ciphers) - - if ca_certs or ca_cert_dir or ca_cert_data: - try: - context.load_verify_locations(ca_certs, ca_cert_dir, ca_cert_data) - except (IOError, OSError) as e: - raise SSLError(e) - - elif ssl_context is None and hasattr(context, "load_default_certs"): - # try to load OS default certs; works well on Windows (require Python3.4+) - context.load_default_certs() - - # Attempt to detect if we get the goofy behavior of the - # keyfile being encrypted and OpenSSL asking for the - # passphrase via the terminal and instead error out. - if keyfile and key_password is None and _is_key_file_encrypted(keyfile): - raise SSLError("Client private key is encrypted, password is required") - - if certfile: - if key_password is None: - context.load_cert_chain(certfile, keyfile) - else: - context.load_cert_chain(certfile, keyfile, key_password) - - try: - if hasattr(context, "set_alpn_protocols"): - context.set_alpn_protocols(ALPN_PROTOCOLS) - except NotImplementedError: # Defensive: in CI, we always have set_alpn_protocols - pass - - # If we detect server_hostname is an IP address then the SNI - # extension should not be used according to RFC3546 Section 3.1 - use_sni_hostname = server_hostname and not is_ipaddress(server_hostname) - # SecureTransport uses server_hostname in certificate verification. - send_sni = (use_sni_hostname and HAS_SNI) or ( - IS_SECURETRANSPORT and server_hostname - ) - # Do not warn the user if server_hostname is an invalid SNI hostname. - if not HAS_SNI and use_sni_hostname: - warnings.warn( - "An HTTPS request has been made, but the SNI (Server Name " - "Indication) extension to TLS is not available on this platform. " - "This may cause the server to present an incorrect TLS " - "certificate, which can cause validation failures. You can upgrade to " - "a newer version of Python to solve this. For more information, see " - "https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html" - "#ssl-warnings", - SNIMissingWarning, - ) - - if send_sni: - ssl_sock = _ssl_wrap_socket_impl( - sock, context, tls_in_tls, server_hostname=server_hostname - ) - else: - ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls) - return ssl_sock - - -def is_ipaddress(hostname): - """Detects whether the hostname given is an IPv4 or IPv6 address. - Also detects IPv6 addresses with Zone IDs. - - :param str hostname: Hostname to examine. - :return: True if the hostname is an IP address, False otherwise. - """ - if not six.PY2 and isinstance(hostname, bytes): - # IDN A-label bytes are ASCII compatible. - hostname = hostname.decode("ascii") - return bool(IPV4_RE.match(hostname) or BRACELESS_IPV6_ADDRZ_RE.match(hostname)) - - -def _is_key_file_encrypted(key_file): - """Detects if a key file is encrypted or not.""" - with open(key_file, "r") as f: - for line in f: - # Look for Proc-Type: 4,ENCRYPTED - if "ENCRYPTED" in line: - return True - - return False - - -def _ssl_wrap_socket_impl(sock, ssl_context, tls_in_tls, server_hostname=None): - if tls_in_tls: - if not SSLTransport: - # Import error, ssl is not available. - raise ProxySchemeUnsupported( - "TLS in TLS requires support for the 'ssl' module" - ) - - SSLTransport._validate_ssl_context_for_tls_in_tls(ssl_context) - return SSLTransport(sock, ssl_context, server_hostname) - - if server_hostname: - return ssl_context.wrap_socket(sock, server_hostname=server_hostname) - else: - return ssl_context.wrap_socket(sock) diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/util/ssltransport.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/util/ssltransport.py deleted file mode 100644 index c2186bced9..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/util/ssltransport.py +++ /dev/null @@ -1,221 +0,0 @@ -import io -import socket -import ssl - -from urllib3.exceptions import ProxySchemeUnsupported -from urllib3.packages import six - -SSL_BLOCKSIZE = 16384 - - -class SSLTransport: - """ - The SSLTransport wraps an existing socket and establishes an SSL connection. - - Contrary to Python's implementation of SSLSocket, it allows you to chain - multiple TLS connections together. It's particularly useful if you need to - implement TLS within TLS. - - The class supports most of the socket API operations. - """ - - @staticmethod - def _validate_ssl_context_for_tls_in_tls(ssl_context): - """ - Raises a ProxySchemeUnsupported if the provided ssl_context can't be used - for TLS in TLS. - - The only requirement is that the ssl_context provides the 'wrap_bio' - methods. - """ - - if not hasattr(ssl_context, "wrap_bio"): - if six.PY2: - raise ProxySchemeUnsupported( - "TLS in TLS requires SSLContext.wrap_bio() which isn't " - "supported on Python 2" - ) - else: - raise ProxySchemeUnsupported( - "TLS in TLS requires SSLContext.wrap_bio() which isn't " - "available on non-native SSLContext" - ) - - def __init__( - self, socket, ssl_context, server_hostname=None, suppress_ragged_eofs=True - ): - """ - Create an SSLTransport around socket using the provided ssl_context. - """ - self.incoming = ssl.MemoryBIO() - self.outgoing = ssl.MemoryBIO() - - self.suppress_ragged_eofs = suppress_ragged_eofs - self.socket = socket - - self.sslobj = ssl_context.wrap_bio( - self.incoming, self.outgoing, server_hostname=server_hostname - ) - - # Perform initial handshake. - self._ssl_io_loop(self.sslobj.do_handshake) - - def __enter__(self): - return self - - def __exit__(self, *_): - self.close() - - def fileno(self): - return self.socket.fileno() - - def read(self, len=1024, buffer=None): - return self._wrap_ssl_read(len, buffer) - - def recv(self, len=1024, flags=0): - if flags != 0: - raise ValueError("non-zero flags not allowed in calls to recv") - return self._wrap_ssl_read(len) - - def recv_into(self, buffer, nbytes=None, flags=0): - if flags != 0: - raise ValueError("non-zero flags not allowed in calls to recv_into") - if buffer and (nbytes is None): - nbytes = len(buffer) - elif nbytes is None: - nbytes = 1024 - return self.read(nbytes, buffer) - - def sendall(self, data, flags=0): - if flags != 0: - raise ValueError("non-zero flags not allowed in calls to sendall") - count = 0 - with memoryview(data) as view, view.cast("B") as byte_view: - amount = len(byte_view) - while count < amount: - v = self.send(byte_view[count:]) - count += v - - def send(self, data, flags=0): - if flags != 0: - raise ValueError("non-zero flags not allowed in calls to send") - response = self._ssl_io_loop(self.sslobj.write, data) - return response - - def makefile( - self, mode="r", buffering=None, encoding=None, errors=None, newline=None - ): - """ - Python's httpclient uses makefile and buffered io when reading HTTP - messages and we need to support it. - - This is unfortunately a copy and paste of socket.py makefile with small - changes to point to the socket directly. - """ - if not set(mode) <= {"r", "w", "b"}: - raise ValueError("invalid mode %r (only r, w, b allowed)" % (mode,)) - - writing = "w" in mode - reading = "r" in mode or not writing - assert reading or writing - binary = "b" in mode - rawmode = "" - if reading: - rawmode += "r" - if writing: - rawmode += "w" - raw = socket.SocketIO(self, rawmode) - self.socket._io_refs += 1 - if buffering is None: - buffering = -1 - if buffering < 0: - buffering = io.DEFAULT_BUFFER_SIZE - if buffering == 0: - if not binary: - raise ValueError("unbuffered streams must be binary") - return raw - if reading and writing: - buffer = io.BufferedRWPair(raw, raw, buffering) - elif reading: - buffer = io.BufferedReader(raw, buffering) - else: - assert writing - buffer = io.BufferedWriter(raw, buffering) - if binary: - return buffer - text = io.TextIOWrapper(buffer, encoding, errors, newline) - text.mode = mode - return text - - def unwrap(self): - self._ssl_io_loop(self.sslobj.unwrap) - - def close(self): - self.socket.close() - - def getpeercert(self, binary_form=False): - return self.sslobj.getpeercert(binary_form) - - def version(self): - return self.sslobj.version() - - def cipher(self): - return self.sslobj.cipher() - - def selected_alpn_protocol(self): - return self.sslobj.selected_alpn_protocol() - - def selected_npn_protocol(self): - return self.sslobj.selected_npn_protocol() - - def shared_ciphers(self): - return self.sslobj.shared_ciphers() - - def compression(self): - return self.sslobj.compression() - - def settimeout(self, value): - self.socket.settimeout(value) - - def gettimeout(self): - return self.socket.gettimeout() - - def _decref_socketios(self): - self.socket._decref_socketios() - - def _wrap_ssl_read(self, len, buffer=None): - try: - return self._ssl_io_loop(self.sslobj.read, len, buffer) - except ssl.SSLError as e: - if e.errno == ssl.SSL_ERROR_EOF and self.suppress_ragged_eofs: - return 0 # eof, return 0. - else: - raise - - def _ssl_io_loop(self, func, *args): - """Performs an I/O loop between incoming/outgoing and the socket.""" - should_loop = True - ret = None - - while should_loop: - errno = None - try: - ret = func(*args) - except ssl.SSLError as e: - if e.errno not in (ssl.SSL_ERROR_WANT_READ, ssl.SSL_ERROR_WANT_WRITE): - # WANT_READ, and WANT_WRITE are expected, others are not. - raise e - errno = e.errno - - buf = self.outgoing.read() - self.socket.sendall(buf) - - if errno is None: - should_loop = False - elif errno == ssl.SSL_ERROR_WANT_READ: - buf = self.socket.recv(SSL_BLOCKSIZE) - if buf: - self.incoming.write(buf) - else: - self.incoming.write_eof() - return ret diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/util/timeout.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/util/timeout.py deleted file mode 100644 index ff69593b05..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/util/timeout.py +++ /dev/null @@ -1,268 +0,0 @@ -from __future__ import absolute_import - -import time - -# The default socket timeout, used by httplib to indicate that no timeout was -# specified by the user -from socket import _GLOBAL_DEFAULT_TIMEOUT - -from ..exceptions import TimeoutStateError - -# A sentinel value to indicate that no timeout was specified by the user in -# urllib3 -_Default = object() - - -# Use time.monotonic if available. -current_time = getattr(time, "monotonic", time.time) - - -class Timeout(object): - """Timeout configuration. - - Timeouts can be defined as a default for a pool: - - .. code-block:: python - - timeout = Timeout(connect=2.0, read=7.0) - http = PoolManager(timeout=timeout) - response = http.request('GET', 'http://example.com/') - - Or per-request (which overrides the default for the pool): - - .. code-block:: python - - response = http.request('GET', 'http://example.com/', timeout=Timeout(10)) - - Timeouts can be disabled by setting all the parameters to ``None``: - - .. code-block:: python - - no_timeout = Timeout(connect=None, read=None) - response = http.request('GET', 'http://example.com/, timeout=no_timeout) - - - :param total: - This combines the connect and read timeouts into one; the read timeout - will be set to the time leftover from the connect attempt. In the - event that both a connect timeout and a total are specified, or a read - timeout and a total are specified, the shorter timeout will be applied. - - Defaults to None. - - :type total: int, float, or None - - :param connect: - The maximum amount of time (in seconds) to wait for a connection - attempt to a server to succeed. Omitting the parameter will default the - connect timeout to the system default, probably `the global default - timeout in socket.py - `_. - None will set an infinite timeout for connection attempts. - - :type connect: int, float, or None - - :param read: - The maximum amount of time (in seconds) to wait between consecutive - read operations for a response from the server. Omitting the parameter - will default the read timeout to the system default, probably `the - global default timeout in socket.py - `_. - None will set an infinite timeout. - - :type read: int, float, or None - - .. note:: - - Many factors can affect the total amount of time for urllib3 to return - an HTTP response. - - For example, Python's DNS resolver does not obey the timeout specified - on the socket. Other factors that can affect total request time include - high CPU load, high swap, the program running at a low priority level, - or other behaviors. - - In addition, the read and total timeouts only measure the time between - read operations on the socket connecting the client and the server, - not the total amount of time for the request to return a complete - response. For most requests, the timeout is raised because the server - has not sent the first byte in the specified time. This is not always - the case; if a server streams one byte every fifteen seconds, a timeout - of 20 seconds will not trigger, even though the request will take - several minutes to complete. - - If your goal is to cut off any request after a set amount of wall clock - time, consider having a second "watcher" thread to cut off a slow - request. - """ - - #: A sentinel object representing the default timeout value - DEFAULT_TIMEOUT = _GLOBAL_DEFAULT_TIMEOUT - - def __init__(self, total=None, connect=_Default, read=_Default): - self._connect = self._validate_timeout(connect, "connect") - self._read = self._validate_timeout(read, "read") - self.total = self._validate_timeout(total, "total") - self._start_connect = None - - def __repr__(self): - return "%s(connect=%r, read=%r, total=%r)" % ( - type(self).__name__, - self._connect, - self._read, - self.total, - ) - - # __str__ provided for backwards compatibility - __str__ = __repr__ - - @classmethod - def _validate_timeout(cls, value, name): - """Check that a timeout attribute is valid. - - :param value: The timeout value to validate - :param name: The name of the timeout attribute to validate. This is - used to specify in error messages. - :return: The validated and casted version of the given value. - :raises ValueError: If it is a numeric value less than or equal to - zero, or the type is not an integer, float, or None. - """ - if value is _Default: - return cls.DEFAULT_TIMEOUT - - if value is None or value is cls.DEFAULT_TIMEOUT: - return value - - if isinstance(value, bool): - raise ValueError( - "Timeout cannot be a boolean value. It must " - "be an int, float or None." - ) - try: - float(value) - except (TypeError, ValueError): - raise ValueError( - "Timeout value %s was %s, but it must be an " - "int, float or None." % (name, value) - ) - - try: - if value <= 0: - raise ValueError( - "Attempted to set %s timeout to %s, but the " - "timeout cannot be set to a value less " - "than or equal to 0." % (name, value) - ) - except TypeError: - # Python 3 - raise ValueError( - "Timeout value %s was %s, but it must be an " - "int, float or None." % (name, value) - ) - - return value - - @classmethod - def from_float(cls, timeout): - """Create a new Timeout from a legacy timeout value. - - The timeout value used by httplib.py sets the same timeout on the - connect(), and recv() socket requests. This creates a :class:`Timeout` - object that sets the individual timeouts to the ``timeout`` value - passed to this function. - - :param timeout: The legacy timeout value. - :type timeout: integer, float, sentinel default object, or None - :return: Timeout object - :rtype: :class:`Timeout` - """ - return Timeout(read=timeout, connect=timeout) - - def clone(self): - """Create a copy of the timeout object - - Timeout properties are stored per-pool but each request needs a fresh - Timeout object to ensure each one has its own start/stop configured. - - :return: a copy of the timeout object - :rtype: :class:`Timeout` - """ - # We can't use copy.deepcopy because that will also create a new object - # for _GLOBAL_DEFAULT_TIMEOUT, which socket.py uses as a sentinel to - # detect the user default. - return Timeout(connect=self._connect, read=self._read, total=self.total) - - def start_connect(self): - """Start the timeout clock, used during a connect() attempt - - :raises urllib3.exceptions.TimeoutStateError: if you attempt - to start a timer that has been started already. - """ - if self._start_connect is not None: - raise TimeoutStateError("Timeout timer has already been started.") - self._start_connect = current_time() - return self._start_connect - - def get_connect_duration(self): - """Gets the time elapsed since the call to :meth:`start_connect`. - - :return: Elapsed time in seconds. - :rtype: float - :raises urllib3.exceptions.TimeoutStateError: if you attempt - to get duration for a timer that hasn't been started. - """ - if self._start_connect is None: - raise TimeoutStateError( - "Can't get connect duration for timer that has not started." - ) - return current_time() - self._start_connect - - @property - def connect_timeout(self): - """Get the value to use when setting a connection timeout. - - This will be a positive float or integer, the value None - (never timeout), or the default system timeout. - - :return: Connect timeout. - :rtype: int, float, :attr:`Timeout.DEFAULT_TIMEOUT` or None - """ - if self.total is None: - return self._connect - - if self._connect is None or self._connect is self.DEFAULT_TIMEOUT: - return self.total - - return min(self._connect, self.total) - - @property - def read_timeout(self): - """Get the value for the read timeout. - - This assumes some time has elapsed in the connection timeout and - computes the read timeout appropriately. - - If self.total is set, the read timeout is dependent on the amount of - time taken by the connect timeout. If the connection time has not been - established, a :exc:`~urllib3.exceptions.TimeoutStateError` will be - raised. - - :return: Value to use for the read timeout. - :rtype: int, float, :attr:`Timeout.DEFAULT_TIMEOUT` or None - :raises urllib3.exceptions.TimeoutStateError: If :meth:`start_connect` - has not yet been called on this object. - """ - if ( - self.total is not None - and self.total is not self.DEFAULT_TIMEOUT - and self._read is not None - and self._read is not self.DEFAULT_TIMEOUT - ): - # In case the connect timeout has not yet been established. - if self._start_connect is None: - return self._read - return max(0, min(self.total - self.get_connect_duration(), self._read)) - elif self.total is not None and self.total is not self.DEFAULT_TIMEOUT: - return max(0, self.total - self.get_connect_duration()) - else: - return self._read diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/util/url.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/util/url.py deleted file mode 100644 index 81a03da9e3..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/util/url.py +++ /dev/null @@ -1,432 +0,0 @@ -from __future__ import absolute_import - -import re -from collections import namedtuple - -from ..exceptions import LocationParseError -from ..packages import six - -url_attrs = ["scheme", "auth", "host", "port", "path", "query", "fragment"] - -# We only want to normalize urls with an HTTP(S) scheme. -# urllib3 infers URLs without a scheme (None) to be http. -NORMALIZABLE_SCHEMES = ("http", "https", None) - -# Almost all of these patterns were derived from the -# 'rfc3986' module: https://github.com/python-hyper/rfc3986 -PERCENT_RE = re.compile(r"%[a-fA-F0-9]{2}") -SCHEME_RE = re.compile(r"^(?:[a-zA-Z][a-zA-Z0-9+-]*:|/)") -URI_RE = re.compile( - r"^(?:([a-zA-Z][a-zA-Z0-9+.-]*):)?" - r"(?://([^\\/?#]*))?" - r"([^?#]*)" - r"(?:\?([^#]*))?" - r"(?:#(.*))?$", - re.UNICODE | re.DOTALL, -) - -IPV4_PAT = r"(?:[0-9]{1,3}\.){3}[0-9]{1,3}" -HEX_PAT = "[0-9A-Fa-f]{1,4}" -LS32_PAT = "(?:{hex}:{hex}|{ipv4})".format(hex=HEX_PAT, ipv4=IPV4_PAT) -_subs = {"hex": HEX_PAT, "ls32": LS32_PAT} -_variations = [ - # 6( h16 ":" ) ls32 - "(?:%(hex)s:){6}%(ls32)s", - # "::" 5( h16 ":" ) ls32 - "::(?:%(hex)s:){5}%(ls32)s", - # [ h16 ] "::" 4( h16 ":" ) ls32 - "(?:%(hex)s)?::(?:%(hex)s:){4}%(ls32)s", - # [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32 - "(?:(?:%(hex)s:)?%(hex)s)?::(?:%(hex)s:){3}%(ls32)s", - # [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32 - "(?:(?:%(hex)s:){0,2}%(hex)s)?::(?:%(hex)s:){2}%(ls32)s", - # [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32 - "(?:(?:%(hex)s:){0,3}%(hex)s)?::%(hex)s:%(ls32)s", - # [ *4( h16 ":" ) h16 ] "::" ls32 - "(?:(?:%(hex)s:){0,4}%(hex)s)?::%(ls32)s", - # [ *5( h16 ":" ) h16 ] "::" h16 - "(?:(?:%(hex)s:){0,5}%(hex)s)?::%(hex)s", - # [ *6( h16 ":" ) h16 ] "::" - "(?:(?:%(hex)s:){0,6}%(hex)s)?::", -] - -UNRESERVED_PAT = r"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._!\-~" -IPV6_PAT = "(?:" + "|".join([x % _subs for x in _variations]) + ")" -ZONE_ID_PAT = "(?:%25|%)(?:[" + UNRESERVED_PAT + "]|%[a-fA-F0-9]{2})+" -IPV6_ADDRZ_PAT = r"\[" + IPV6_PAT + r"(?:" + ZONE_ID_PAT + r")?\]" -REG_NAME_PAT = r"(?:[^\[\]%:/?#]|%[a-fA-F0-9]{2})*" -TARGET_RE = re.compile(r"^(/[^?#]*)(?:\?([^#]*))?(?:#.*)?$") - -IPV4_RE = re.compile("^" + IPV4_PAT + "$") -IPV6_RE = re.compile("^" + IPV6_PAT + "$") -IPV6_ADDRZ_RE = re.compile("^" + IPV6_ADDRZ_PAT + "$") -BRACELESS_IPV6_ADDRZ_RE = re.compile("^" + IPV6_ADDRZ_PAT[2:-2] + "$") -ZONE_ID_RE = re.compile("(" + ZONE_ID_PAT + r")\]$") - -_HOST_PORT_PAT = ("^(%s|%s|%s)(?::([0-9]{0,5}))?$") % ( - REG_NAME_PAT, - IPV4_PAT, - IPV6_ADDRZ_PAT, -) -_HOST_PORT_RE = re.compile(_HOST_PORT_PAT, re.UNICODE | re.DOTALL) - -UNRESERVED_CHARS = set( - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-~" -) -SUB_DELIM_CHARS = set("!$&'()*+,;=") -USERINFO_CHARS = UNRESERVED_CHARS | SUB_DELIM_CHARS | {":"} -PATH_CHARS = USERINFO_CHARS | {"@", "/"} -QUERY_CHARS = FRAGMENT_CHARS = PATH_CHARS | {"?"} - - -class Url(namedtuple("Url", url_attrs)): - """ - Data structure for representing an HTTP URL. Used as a return value for - :func:`parse_url`. Both the scheme and host are normalized as they are - both case-insensitive according to RFC 3986. - """ - - __slots__ = () - - def __new__( - cls, - scheme=None, - auth=None, - host=None, - port=None, - path=None, - query=None, - fragment=None, - ): - if path and not path.startswith("/"): - path = "/" + path - if scheme is not None: - scheme = scheme.lower() - return super(Url, cls).__new__( - cls, scheme, auth, host, port, path, query, fragment - ) - - @property - def hostname(self): - """For backwards-compatibility with urlparse. We're nice like that.""" - return self.host - - @property - def request_uri(self): - """Absolute path including the query string.""" - uri = self.path or "/" - - if self.query is not None: - uri += "?" + self.query - - return uri - - @property - def netloc(self): - """Network location including host and port""" - if self.port: - return "%s:%d" % (self.host, self.port) - return self.host - - @property - def url(self): - """ - Convert self into a url - - This function should more or less round-trip with :func:`.parse_url`. The - returned url may not be exactly the same as the url inputted to - :func:`.parse_url`, but it should be equivalent by the RFC (e.g., urls - with a blank port will have : removed). - - Example: :: - - >>> U = parse_url('http://google.com/mail/') - >>> U.url - 'http://google.com/mail/' - >>> Url('http', 'username:password', 'host.com', 80, - ... '/path', 'query', 'fragment').url - 'http://username:password@host.com:80/path?query#fragment' - """ - scheme, auth, host, port, path, query, fragment = self - url = u"" - - # We use "is not None" we want things to happen with empty strings (or 0 port) - if scheme is not None: - url += scheme + u"://" - if auth is not None: - url += auth + u"@" - if host is not None: - url += host - if port is not None: - url += u":" + str(port) - if path is not None: - url += path - if query is not None: - url += u"?" + query - if fragment is not None: - url += u"#" + fragment - - return url - - def __str__(self): - return self.url - - -def split_first(s, delims): - """ - .. deprecated:: 1.25 - - Given a string and an iterable of delimiters, split on the first found - delimiter. Return two split parts and the matched delimiter. - - If not found, then the first part is the full input string. - - Example:: - - >>> split_first('foo/bar?baz', '?/=') - ('foo', 'bar?baz', '/') - >>> split_first('foo/bar?baz', '123') - ('foo/bar?baz', '', None) - - Scales linearly with number of delims. Not ideal for large number of delims. - """ - min_idx = None - min_delim = None - for d in delims: - idx = s.find(d) - if idx < 0: - continue - - if min_idx is None or idx < min_idx: - min_idx = idx - min_delim = d - - if min_idx is None or min_idx < 0: - return s, "", None - - return s[:min_idx], s[min_idx + 1 :], min_delim - - -def _encode_invalid_chars(component, allowed_chars, encoding="utf-8"): - """Percent-encodes a URI component without reapplying - onto an already percent-encoded component. - """ - if component is None: - return component - - component = six.ensure_text(component) - - # Normalize existing percent-encoded bytes. - # Try to see if the component we're encoding is already percent-encoded - # so we can skip all '%' characters but still encode all others. - component, percent_encodings = PERCENT_RE.subn( - lambda match: match.group(0).upper(), component - ) - - uri_bytes = component.encode("utf-8", "surrogatepass") - is_percent_encoded = percent_encodings == uri_bytes.count(b"%") - encoded_component = bytearray() - - for i in range(0, len(uri_bytes)): - # Will return a single character bytestring on both Python 2 & 3 - byte = uri_bytes[i : i + 1] - byte_ord = ord(byte) - if (is_percent_encoded and byte == b"%") or ( - byte_ord < 128 and byte.decode() in allowed_chars - ): - encoded_component += byte - continue - encoded_component.extend(b"%" + (hex(byte_ord)[2:].encode().zfill(2).upper())) - - return encoded_component.decode(encoding) - - -def _remove_path_dot_segments(path): - # See http://tools.ietf.org/html/rfc3986#section-5.2.4 for pseudo-code - segments = path.split("/") # Turn the path into a list of segments - output = [] # Initialize the variable to use to store output - - for segment in segments: - # '.' is the current directory, so ignore it, it is superfluous - if segment == ".": - continue - # Anything other than '..', should be appended to the output - elif segment != "..": - output.append(segment) - # In this case segment == '..', if we can, we should pop the last - # element - elif output: - output.pop() - - # If the path starts with '/' and the output is empty or the first string - # is non-empty - if path.startswith("/") and (not output or output[0]): - output.insert(0, "") - - # If the path starts with '/.' or '/..' ensure we add one more empty - # string to add a trailing '/' - if path.endswith(("/.", "/..")): - output.append("") - - return "/".join(output) - - -def _normalize_host(host, scheme): - if host: - if isinstance(host, six.binary_type): - host = six.ensure_str(host) - - if scheme in NORMALIZABLE_SCHEMES: - is_ipv6 = IPV6_ADDRZ_RE.match(host) - if is_ipv6: - match = ZONE_ID_RE.search(host) - if match: - start, end = match.span(1) - zone_id = host[start:end] - - if zone_id.startswith("%25") and zone_id != "%25": - zone_id = zone_id[3:] - else: - zone_id = zone_id[1:] - zone_id = "%" + _encode_invalid_chars(zone_id, UNRESERVED_CHARS) - return host[:start].lower() + zone_id + host[end:] - else: - return host.lower() - elif not IPV4_RE.match(host): - return six.ensure_str( - b".".join([_idna_encode(label) for label in host.split(".")]) - ) - return host - - -def _idna_encode(name): - if name and any([ord(x) > 128 for x in name]): - try: - import idna - except ImportError: - six.raise_from( - LocationParseError("Unable to parse URL without the 'idna' module"), - None, - ) - try: - return idna.encode(name.lower(), strict=True, std3_rules=True) - except idna.IDNAError: - six.raise_from( - LocationParseError(u"Name '%s' is not a valid IDNA label" % name), None - ) - return name.lower().encode("ascii") - - -def _encode_target(target): - """Percent-encodes a request target so that there are no invalid characters""" - path, query = TARGET_RE.match(target).groups() - target = _encode_invalid_chars(path, PATH_CHARS) - query = _encode_invalid_chars(query, QUERY_CHARS) - if query is not None: - target += "?" + query - return target - - -def parse_url(url): - """ - Given a url, return a parsed :class:`.Url` namedtuple. Best-effort is - performed to parse incomplete urls. Fields not provided will be None. - This parser is RFC 3986 compliant. - - The parser logic and helper functions are based heavily on - work done in the ``rfc3986`` module. - - :param str url: URL to parse into a :class:`.Url` namedtuple. - - Partly backwards-compatible with :mod:`urlparse`. - - Example:: - - >>> parse_url('http://google.com/mail/') - Url(scheme='http', host='google.com', port=None, path='/mail/', ...) - >>> parse_url('google.com:80') - Url(scheme=None, host='google.com', port=80, path=None, ...) - >>> parse_url('/foo?bar') - Url(scheme=None, host=None, port=None, path='/foo', query='bar', ...) - """ - if not url: - # Empty - return Url() - - source_url = url - if not SCHEME_RE.search(url): - url = "//" + url - - try: - scheme, authority, path, query, fragment = URI_RE.match(url).groups() - normalize_uri = scheme is None or scheme.lower() in NORMALIZABLE_SCHEMES - - if scheme: - scheme = scheme.lower() - - if authority: - auth, _, host_port = authority.rpartition("@") - auth = auth or None - host, port = _HOST_PORT_RE.match(host_port).groups() - if auth and normalize_uri: - auth = _encode_invalid_chars(auth, USERINFO_CHARS) - if port == "": - port = None - else: - auth, host, port = None, None, None - - if port is not None: - port = int(port) - if not (0 <= port <= 65535): - raise LocationParseError(url) - - host = _normalize_host(host, scheme) - - if normalize_uri and path: - path = _remove_path_dot_segments(path) - path = _encode_invalid_chars(path, PATH_CHARS) - if normalize_uri and query: - query = _encode_invalid_chars(query, QUERY_CHARS) - if normalize_uri and fragment: - fragment = _encode_invalid_chars(fragment, FRAGMENT_CHARS) - - except (ValueError, AttributeError): - return six.raise_from(LocationParseError(source_url), None) - - # For the sake of backwards compatibility we put empty - # string values for path if there are any defined values - # beyond the path in the URL. - # TODO: Remove this when we break backwards compatibility. - if not path: - if query is not None or fragment is not None: - path = "" - else: - path = None - - # Ensure that each part of the URL is a `str` for - # backwards compatibility. - if isinstance(url, six.text_type): - ensure_func = six.ensure_text - else: - ensure_func = six.ensure_str - - def ensure_type(x): - return x if x is None else ensure_func(x) - - return Url( - scheme=ensure_type(scheme), - auth=ensure_type(auth), - host=ensure_type(host), - port=port, - path=ensure_type(path), - query=ensure_type(query), - fragment=ensure_type(fragment), - ) - - -def get_host(url): - """ - Deprecated. Use :func:`parse_url` instead. - """ - p = parse_url(url) - return p.scheme or "http", p.hostname, p.port diff --git a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/util/wait.py b/server_addon/fusion/client/ayon_fusion/vendor/urllib3/util/wait.py deleted file mode 100644 index c280646c7b..0000000000 --- a/server_addon/fusion/client/ayon_fusion/vendor/urllib3/util/wait.py +++ /dev/null @@ -1,153 +0,0 @@ -import errno -import select -import sys -from functools import partial - -try: - from time import monotonic -except ImportError: - from time import time as monotonic - -__all__ = ["NoWayToWaitForSocketError", "wait_for_read", "wait_for_write"] - - -class NoWayToWaitForSocketError(Exception): - pass - - -# How should we wait on sockets? -# -# There are two types of APIs you can use for waiting on sockets: the fancy -# modern stateful APIs like epoll/kqueue, and the older stateless APIs like -# select/poll. The stateful APIs are more efficient when you have a lots of -# sockets to keep track of, because you can set them up once and then use them -# lots of times. But we only ever want to wait on a single socket at a time -# and don't want to keep track of state, so the stateless APIs are actually -# more efficient. So we want to use select() or poll(). -# -# Now, how do we choose between select() and poll()? On traditional Unixes, -# select() has a strange calling convention that makes it slow, or fail -# altogether, for high-numbered file descriptors. The point of poll() is to fix -# that, so on Unixes, we prefer poll(). -# -# On Windows, there is no poll() (or at least Python doesn't provide a wrapper -# for it), but that's OK, because on Windows, select() doesn't have this -# strange calling convention; plain select() works fine. -# -# So: on Windows we use select(), and everywhere else we use poll(). We also -# fall back to select() in case poll() is somehow broken or missing. - -if sys.version_info >= (3, 5): - # Modern Python, that retries syscalls by default - def _retry_on_intr(fn, timeout): - return fn(timeout) - - -else: - # Old and broken Pythons. - def _retry_on_intr(fn, timeout): - if timeout is None: - deadline = float("inf") - else: - deadline = monotonic() + timeout - - while True: - try: - return fn(timeout) - # OSError for 3 <= pyver < 3.5, select.error for pyver <= 2.7 - except (OSError, select.error) as e: - # 'e.args[0]' incantation works for both OSError and select.error - if e.args[0] != errno.EINTR: - raise - else: - timeout = deadline - monotonic() - if timeout < 0: - timeout = 0 - if timeout == float("inf"): - timeout = None - continue - - -def select_wait_for_socket(sock, read=False, write=False, timeout=None): - if not read and not write: - raise RuntimeError("must specify at least one of read=True, write=True") - rcheck = [] - wcheck = [] - if read: - rcheck.append(sock) - if write: - wcheck.append(sock) - # When doing a non-blocking connect, most systems signal success by - # marking the socket writable. Windows, though, signals success by marked - # it as "exceptional". We paper over the difference by checking the write - # sockets for both conditions. (The stdlib selectors module does the same - # thing.) - fn = partial(select.select, rcheck, wcheck, wcheck) - rready, wready, xready = _retry_on_intr(fn, timeout) - return bool(rready or wready or xready) - - -def poll_wait_for_socket(sock, read=False, write=False, timeout=None): - if not read and not write: - raise RuntimeError("must specify at least one of read=True, write=True") - mask = 0 - if read: - mask |= select.POLLIN - if write: - mask |= select.POLLOUT - poll_obj = select.poll() - poll_obj.register(sock, mask) - - # For some reason, poll() takes timeout in milliseconds - def do_poll(t): - if t is not None: - t *= 1000 - return poll_obj.poll(t) - - return bool(_retry_on_intr(do_poll, timeout)) - - -def null_wait_for_socket(*args, **kwargs): - raise NoWayToWaitForSocketError("no select-equivalent available") - - -def _have_working_poll(): - # Apparently some systems have a select.poll that fails as soon as you try - # to use it, either due to strange configuration or broken monkeypatching - # from libraries like eventlet/greenlet. - try: - poll_obj = select.poll() - _retry_on_intr(poll_obj.poll, 0) - except (AttributeError, OSError): - return False - else: - return True - - -def wait_for_socket(*args, **kwargs): - # We delay choosing which implementation to use until the first time we're - # called. We could do it at import time, but then we might make the wrong - # decision if someone goes wild with monkeypatching select.poll after - # we're imported. - global wait_for_socket - if _have_working_poll(): - wait_for_socket = poll_wait_for_socket - elif hasattr(select, "select"): - wait_for_socket = select_wait_for_socket - else: # Platform-specific: Appengine. - wait_for_socket = null_wait_for_socket - return wait_for_socket(*args, **kwargs) - - -def wait_for_read(sock, timeout=None): - """Waits for reading to be available on a given socket. - Returns True if the socket is readable, or False if the timeout expired. - """ - return wait_for_socket(sock, read=True, timeout=timeout) - - -def wait_for_write(sock, timeout=None): - """Waits for writing to be available on a given socket. - Returns True if the socket is readable, or False if the timeout expired. - """ - return wait_for_socket(sock, write=True, timeout=timeout) diff --git a/server_addon/fusion/client/ayon_fusion/version.py b/server_addon/fusion/client/ayon_fusion/version.py deleted file mode 100644 index 209eddcdb6..0000000000 --- a/server_addon/fusion/client/ayon_fusion/version.py +++ /dev/null @@ -1,3 +0,0 @@ -# -*- coding: utf-8 -*- -"""Package declaring AYON addon 'fusion' version.""" -__version__ = "0.2.0" diff --git a/server_addon/fusion/package.py b/server_addon/fusion/package.py deleted file mode 100644 index e82e9bf0f6..0000000000 --- a/server_addon/fusion/package.py +++ /dev/null @@ -1,10 +0,0 @@ -name = "fusion" -title = "Fusion" -version = "0.2.0" - -client_dir = "ayon_fusion" - -ayon_required_addons = { - "core": ">0.3.2", -} -ayon_compatible_addons = {} diff --git a/server_addon/fusion/server/__init__.py b/server_addon/fusion/server/__init__.py deleted file mode 100644 index 0456cfd5ee..0000000000 --- a/server_addon/fusion/server/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -from typing import Type - -from ayon_server.addons import BaseServerAddon - -from .settings import FusionSettings, DEFAULT_VALUES - - -class FusionAddon(BaseServerAddon): - settings_model: Type[FusionSettings] = FusionSettings - - async def get_default_settings(self): - settings_model_cls = self.get_settings_model() - return settings_model_cls(**DEFAULT_VALUES) diff --git a/server_addon/fusion/server/imageio.py b/server_addon/fusion/server/imageio.py deleted file mode 100644 index 4d4688e269..0000000000 --- a/server_addon/fusion/server/imageio.py +++ /dev/null @@ -1,63 +0,0 @@ -from pydantic import validator -from ayon_server.settings import BaseSettingsModel, SettingsField -from ayon_server.settings.validators import ensure_unique_names - - -class ImageIOConfigModel(BaseSettingsModel): - """[DEPRECATED] Addon OCIO config settings. Please set the OCIO config - path in the Core addon profiles here - (ayon+settings://core/imageio/ocio_config_profiles). - """ - - override_global_config: bool = SettingsField( - False, - title="Override global OCIO config", - description=( - "DEPRECATED functionality. Please set the OCIO config path in the " - "Core addon profiles here (ayon+settings://core/imageio/" - "ocio_config_profiles)." - ), - ) - filepath: list[str] = SettingsField( - default_factory=list, - title="Config path", - description=( - "DEPRECATED functionality. Please set the OCIO config path in the " - "Core addon profiles here (ayon+settings://core/imageio/" - "ocio_config_profiles)." - ), - ) - - -class ImageIOFileRuleModel(BaseSettingsModel): - name: str = SettingsField("", title="Rule name") - pattern: str = SettingsField("", title="Regex pattern") - colorspace: str = SettingsField("", title="Colorspace name") - ext: str = SettingsField("", title="File extension") - - -class ImageIOFileRulesModel(BaseSettingsModel): - activate_host_rules: bool = SettingsField(False) - rules: list[ImageIOFileRuleModel] = SettingsField( - default_factory=list, - title="Rules" - ) - - @validator("rules") - def validate_unique_outputs(cls, value): - ensure_unique_names(value) - return value - - -class FusionImageIOModel(BaseSettingsModel): - activate_host_color_management: bool = SettingsField( - True, title="Enable Color Management" - ) - ocio_config: ImageIOConfigModel = SettingsField( - default_factory=ImageIOConfigModel, - title="OCIO config" - ) - file_rules: ImageIOFileRulesModel = SettingsField( - default_factory=ImageIOFileRulesModel, - title="File Rules" - ) diff --git a/server_addon/fusion/server/settings.py b/server_addon/fusion/server/settings.py deleted file mode 100644 index f16ae6e3e7..0000000000 --- a/server_addon/fusion/server/settings.py +++ /dev/null @@ -1,185 +0,0 @@ -from ayon_server.settings import ( - BaseSettingsModel, - SettingsField, -) - -from .imageio import FusionImageIOModel - - -class CopyFusionSettingsModel(BaseSettingsModel): - copy_path: str = SettingsField("", title="Local Fusion profile directory") - copy_status: bool = SettingsField(title="Copy profile on first launch") - force_sync: bool = SettingsField(title="Resync profile on each launch") - - -def _create_saver_instance_attributes_enum(): - return [ - { - "value": "reviewable", - "label": "Reviewable" - }, - { - "value": "farm_rendering", - "label": "Farm rendering" - } - ] - - -def _image_format_enum(): - return [ - {"value": "exr", "label": "exr"}, - {"value": "tga", "label": "tga"}, - {"value": "png", "label": "png"}, - {"value": "tif", "label": "tif"}, - {"value": "jpg", "label": "jpg"}, - ] - - -def _frame_range_options_enum(): - return [ - {"value": "asset_db", "label": "Current asset context"}, - {"value": "render_range", "label": "From render in/out"}, - {"value": "comp_range", "label": "From composition timeline"}, - ] - - -class CreateSaverPluginModel(BaseSettingsModel): - _isGroup = True - temp_rendering_path_template: str = SettingsField( - "", title="Temporary rendering path template" - ) - default_variants: list[str] = SettingsField( - default_factory=list, - title="Default variants" - ) - instance_attributes: list[str] = SettingsField( - default_factory=list, - enum_resolver=_create_saver_instance_attributes_enum, - title="Instance attributes" - ) - image_format: str = SettingsField( - enum_resolver=_image_format_enum, - title="Output Image Format" - ) - - -class HookOptionalModel(BaseSettingsModel): - enabled: bool = SettingsField( - True, - title="Enabled" - ) - - -class HooksModel(BaseSettingsModel): - InstallPySideToFusion: HookOptionalModel = SettingsField( - default_factory=HookOptionalModel, - title="Install PySide2" - ) - FusionLaunchMenuHook: HookOptionalModel = SettingsField( - default_factory=HookOptionalModel, - title="Launch AYON Menu on Fusion Start", - description="Launch the AYON menu on Fusion application startup. " - "This is only supported for Fusion 18+" - ) - - -class CreateSaverModel(CreateSaverPluginModel): - default_frame_range_option: str = SettingsField( - default="asset_db", - enum_resolver=_frame_range_options_enum, - title="Default frame range source" - ) - - -class CreateImageSaverModel(CreateSaverPluginModel): - default_frame: int = SettingsField( - 0, - title="Default rendered frame" - ) - - -class CreatPluginsModel(BaseSettingsModel): - CreateSaver: CreateSaverModel = SettingsField( - default_factory=CreateSaverModel, - title="Create Saver", - description="Creator for render product type (eg. sequence)" - ) - CreateImageSaver: CreateImageSaverModel = SettingsField( - default_factory=CreateImageSaverModel, - title="Create Image Saver", - description="Creator for image product type (eg. single)" - ) - - -class FusionSettings(BaseSettingsModel): - imageio: FusionImageIOModel = SettingsField( - default_factory=FusionImageIOModel, - title="Color Management (ImageIO)" - ) - copy_fusion_settings: CopyFusionSettingsModel = SettingsField( - default_factory=CopyFusionSettingsModel, - title="Local Fusion profile settings" - ) - hooks: HooksModel = SettingsField( - default_factory=HooksModel, - title="Hooks" - ) - create: CreatPluginsModel = SettingsField( - default_factory=CreatPluginsModel, - title="Creator plugins" - ) - - -DEFAULT_VALUES = { - "imageio": { - "ocio_config": { - "enabled": False, - "filepath": [] - }, - "file_rules": { - "enabled": False, - "rules": [] - } - }, - "copy_fusion_settings": { - "copy_path": "~/.openpype/hosts/fusion/profiles", - "copy_status": False, - "force_sync": False - }, - "hooks": { - "InstallPySideToFusion": { - "enabled": True - }, - "FusionLaunchMenuHook": { - "enabled": False - } - }, - "create": { - "CreateSaver": { - "temp_rendering_path_template": "{workdir}/renders/fusion/{product[name]}/{product[name]}.{frame}.{ext}", - "default_variants": [ - "Main", - "Mask" - ], - "instance_attributes": [ - "reviewable", - "farm_rendering" - ], - "image_format": "exr", - "default_frame_range_option": "asset_db" - }, - "CreateImageSaver": { - "temp_rendering_path_template": "{workdir}/renders/fusion/{product[name]}/{product[name]}.{ext}", - "default_variants": [ - "Main", - "Mask" - ], - "instance_attributes": [ - "reviewable", - "farm_rendering" - ], - "image_format": "exr", - "default_frame": 0 - } - } -} diff --git a/server_addon/harmony/LICENSE b/server_addon/harmony/LICENSE deleted file mode 100644 index d645695673..0000000000 --- a/server_addon/harmony/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/server_addon/harmony/README.md b/server_addon/harmony/README.md deleted file mode 100644 index d971fa39f9..0000000000 --- a/server_addon/harmony/README.md +++ /dev/null @@ -1,4 +0,0 @@ -ToonBoom Harmony Addon -=============== - -Integration with ToonBoom Harmony. diff --git a/server_addon/harmony/client/ayon_harmony/__init__.py b/server_addon/harmony/client/ayon_harmony/__init__.py deleted file mode 100644 index 425439a603..0000000000 --- a/server_addon/harmony/client/ayon_harmony/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -from .version import __version__ -from .addon import ( - HARMONY_ADDON_ROOT, - HarmonyAddon, - get_launch_script_path, -) - - -__all__ = ( - "__version__", - - "HARMONY_ADDON_ROOT", - "HarmonyAddon", - "get_launch_script_path", -) diff --git a/server_addon/harmony/client/ayon_harmony/addon.py b/server_addon/harmony/client/ayon_harmony/addon.py deleted file mode 100644 index ef96cf03f7..0000000000 --- a/server_addon/harmony/client/ayon_harmony/addon.py +++ /dev/null @@ -1,36 +0,0 @@ -import os -from ayon_core.addon import AYONAddon, IHostAddon - -from .version import __version__ - -HARMONY_ADDON_ROOT = os.path.dirname(os.path.abspath(__file__)) - - -class HarmonyAddon(AYONAddon, IHostAddon): - name = "harmony" - version = __version__ - host_name = "harmony" - - def add_implementation_envs(self, env, _app): - """Modify environments to contain all required for implementation.""" - openharmony_path = os.path.join( - HARMONY_ADDON_ROOT, "vendor", "OpenHarmony" - ) - # TODO check if is already set? What to do if is already set? - env["LIB_OPENHARMONY_PATH"] = openharmony_path - - def get_workfile_extensions(self): - return [".zip"] - - def get_launch_hook_paths(self, app): - if app.host_name != self.host_name: - return [] - return [ - os.path.join(HARMONY_ADDON_ROOT, "hooks") - ] - - -def get_launch_script_path(): - return os.path.join( - HARMONY_ADDON_ROOT, "api", "launch_script.py" - ) diff --git a/server_addon/harmony/client/ayon_harmony/api/README.md b/server_addon/harmony/client/ayon_harmony/api/README.md deleted file mode 100644 index 6666ede83c..0000000000 --- a/server_addon/harmony/client/ayon_harmony/api/README.md +++ /dev/null @@ -1,668 +0,0 @@ -# Harmony Integration - -## Setup - -The easiest way to setup for using Toon Boom Harmony is to use the built-in launch: - -``` -python -c "import ayon_harmony.api as harmony;harmony.launch("path/to/harmony/executable")" -``` - -Communication with Harmony happens with a server/client relationship where the server is in the Python process and the client is in the Harmony process. Messages between Python and Harmony are required to be dictionaries, which are serialized to strings: -``` -+------------+ -| | -| Python | -| Process | -| | -| +--------+ | -| | | | -| | Main | | -| | Thread | | -| | | | -| +----^---+ | -| || | -| || | -| +---v----+ | +---------+ -| | | | | | -| | Server +-------> Harmony | -| | Thread <-------+ Process | -| | | | | | -| +--------+ | +---------+ -+------------+ -``` - -Server/client now uses stricter protocol to handle communication. This is necessary because of precise control over data passed between server/client. Each message is prepended with 6 bytes: -``` -| A | H | 0x00 | 0x00 | 0x00 | 0x00 | ... - -``` -First two bytes are *magic* bytes stands for **A**valon **H**armony. Next four bytes hold length of the message `...` encoded as 32bit unsigned integer. This way we know how many bytes to read from the socket and if we need more or we need to parse multiple messages. - - -## Usage - -The integration creates an `Openpype` menu entry where all related tools are located. - -**NOTE: Menu creation can be temperamental. The best way is to launch Harmony and do nothing else until Harmony is fully launched.** - -### Work files - -Because Harmony projects are directories, this integration uses `.zip` as work file extension. Internally the project directories are stored under `[User]/.avalon/harmony`. Whenever the user saves the `.xstage` file, the integration zips up the project directory and moves it to the Avalon project path. Zipping and moving happens in the background. - -### Show Workfiles on launch - -You can show the Workfiles app when Harmony launches by setting environment variable `AYON_HARMONY_WORKFILES_ON_LAUNCH=1`. - -## Developing - -### Low level messaging -To send from Python to Harmony you can use the exposed method: -```python -import ayon_harmony.api as harmony -from uuid import uuid4 - - -func = """function %s_hello(person) -{ - return ("Hello " + person + "!"); -} -%s_hello -""" % (uuid4(), uuid4()) -print(harmony.send({"function": func, "args": ["Python"]})["result"]) -``` -**NOTE:** Its important to declare the function at the end of the function string. You can have multiple functions within your function string, but the function declared at the end is what gets executed. - -To send a function with multiple arguments its best to declare the arguments within the function: -```python -import ayon_harmony.api as harmony -from uuid import uuid4 - -signature = str(uuid4()).replace("-", "_") -func = """function %s_hello(args) -{ - var greeting = args[0]; - var person = args[1]; - return (greeting + " " + person + "!"); -} -%s_hello -""" % (signature, signature) -print(harmony.send({"function": func, "args": ["Hello", "Python"]})["result"]) -``` - -### Caution - -When naming your functions be aware that they are executed in global scope. They can potentially clash with Harmony own function and object names. -For example `func` is already existing Harmony object. When you call your function `func` it will overwrite in global scope the one from Harmony, causing -erratic behavior of Harmony. Openpype is prefixing those function names with [UUID4](https://docs.python.org/3/library/uuid.html) making chance of such clash minimal. -See above examples how that works. This will result in function named `38dfcef0_a6d7_4064_8069_51fe99ab276e_hello()`. -You can find list of Harmony object and function in Harmony documentation. - -### Higher level (recommended) - -Instead of sending functions directly to Harmony, it is more efficient and safe to just add your code to `js/PypeHarmony.js` or utilize `{"script": "..."}` method. - -#### Extending PypeHarmony.js - -Add your function to `PypeHarmony.js`. For example: - -```javascript -PypeHarmony.myAwesomeFunction = function() { - someCoolStuff(); -}; -``` -Then you can call that javascript code from your Python like: - -```Python -import ayon_harmony.api as harmony - -harmony.send({"function": "PypeHarmony.myAwesomeFunction"}); - -``` - -#### Using Script method - -You can also pass whole scripts into harmony and call their functions later as needed. - -For example, you have bunch of javascript files: - -```javascript -/* Master.js */ - -var Master = { - Foo = {}; - Boo = {}; -}; - -/* FileA.js */ -var Foo = function() {}; - -Foo.prototype.A = function() { - someAStuff(); -} - -// This will construct object Foo and add it to Master namespace. -Master.Foo = new Foo(); - -/* FileB.js */ -var Boo = function() {}; - -Boo.prototype.B = function() { - someBStuff(); -} - -// This will construct object Boo and add it to Master namespace. -Master.Boo = new Boo(); -``` - -Now in python, just read all those files and send them to Harmony. - -```python -from pathlib import Path -import ayon_harmony.api as harmony - -path_to_js = Path('/path/to/my/js') -script_to_send = "" - -for file in path_to_js.iterdir(): - if file.suffix == ".js": - script_to_send += file.read_text() - -harmony.send({"script": script_to_send}) - -# and use your code in Harmony -harmony.send({"function": "Master.Boo.B"}) - -``` - -### Scene Save -Instead of sending a request to Harmony with `scene.saveAll` please use: -```python -import ayon_harmony.api as harmony -harmony.save_scene() -``` - -
- Click to expand for details on scene save. - - Because Openpype tools does not deal well with folders for a single entity like a Harmony scene, this integration has implemented to use zip files to encapsulate the Harmony scene folders. Saving scene in Harmony via menu or CTRL+S will not result in producing zip file, only saving it from Workfiles will. This is because - zipping process can take some time in which we cannot block user from saving again. If xstage file is changed during zipping process it will produce corrupted zip - archive. -
- -### Plugin Examples -These plugins were made with the [polly config](https://github.com/mindbender-studio/config). - -#### Creator Plugin -```python -import ayon_harmony.api as harmony -from uuid import uuid4 - - -class CreateComposite(harmony.Creator): - """Composite node for publish.""" - - name = "compositeDefault" - label = "Composite" - product_type = "template" - - def __init__(self, *args, **kwargs): - super(CreateComposite, self).__init__(*args, **kwargs) -``` - -The creator plugin can be configured to use other node types. For example here is a write node creator: -```python -from uuid import uuid4 -import ayon_harmony.api as harmony - - -class CreateRender(harmony.Creator): - """Composite node for publishing renders.""" - - name = "writeDefault" - label = "Write" - product_type = "render" - node_type = "WRITE" - - def __init__(self, *args, **kwargs): - super(CreateRender, self).__init__(*args, **kwargs) - - def setup_node(self, node): - signature = str(uuid4()).replace("-", "_") - func = """function %s_func(args) - { - node.setTextAttr(args[0], "DRAWING_TYPE", 1, "PNG4"); - } - %s_func - """ % (signature, signature) - harmony.send( - {"function": func, "args": [node]} - ) -``` - -#### Collector Plugin -```python -import pyblish.api -from ayon_core.pipeline import AYON_INSTANCE_ID, AVALON_INSTANCE_ID -import ayon_harmony.api as harmony - - -class CollectInstances(pyblish.api.ContextPlugin): - """Gather instances by nodes metadata. - - This collector takes into account assets that are associated with - a composite node and marked with a unique identifier; - - Identifier: - id (str): "ayon.create.instance" - """ - - label = "Instances" - order = pyblish.api.CollectorOrder - hosts = ["harmony"] - - def process(self, context): - nodes = harmony.send( - {"function": "node.getNodes", "args": [["COMPOSITE"]]} - )["result"] - - for node in nodes: - data = harmony.read(node) - - # Skip non-tagged nodes. - if not data: - continue - - # Skip containers. - if data["id"] not in {AYON_INSTANCE_ID, AVALON_INSTANCE_ID}: - continue - - instance = context.create_instance(node.split("/")[-1]) - instance.append(node) - instance.data.update(data) - - # Produce diagnostic message for any graphical - # user interface interested in visualising it. - self.log.info("Found: \"%s\" " % instance.data["name"]) -``` - -#### Extractor Plugin -```python -import os -from uuid import uuid4 - -import pyblish.api -import ayon_harmony.api as harmony - -import clique - - -class ExtractImage(pyblish.api.InstancePlugin): - """Produce a flattened image file from instance. - This plug-in only takes into account the nodes connected to the composite. - """ - label = "Extract Image Sequence" - order = pyblish.api.ExtractorOrder - hosts = ["harmony"] - families = ["render"] - - def process(self, instance): - project_path = harmony.send( - {"function": "scene.currentProjectPath"} - )["result"] - - # Store reference for integration - if "files" not in instance.data: - instance.data["files"] = list() - - # Store display source node for later. - display_node = "Top/Display" - signature = str(uuid4()).replace("-", "_") - func = """function %s_func(display_node) - { - var source_node = null; - if (node.isLinked(display_node, 0)) - { - source_node = node.srcNode(display_node, 0); - node.unlink(display_node, 0); - } - return source_node - } - %s_func - """ % (signature, signature) - display_source_node = harmony.send( - {"function": func, "args": [display_node]} - )["result"] - - # Perform extraction - path = os.path.join( - os.path.normpath( - project_path - ).replace("\\", "/"), - instance.data["name"] - ) - if not os.path.exists(path): - os.makedirs(path) - - render_func = """function frameReady(frame, celImage) - {{ - var path = "{path}/{filename}" + frame + ".png"; - celImage.imageFileAs(path, "", "PNG4"); - }} - function %s_func(composite_node) - {{ - node.link(composite_node, 0, "{display_node}", 0); - render.frameReady.connect(frameReady); - render.setRenderDisplay("{display_node}"); - render.renderSceneAll(); - render.frameReady.disconnect(frameReady); - }} - %s_func - """ % (signature, signature) - restore_func = """function %s_func(args) - { - var display_node = args[0]; - var display_source_node = args[1]; - if (node.isLinked(display_node, 0)) - { - node.unlink(display_node, 0); - } - node.link(display_source_node, 0, display_node, 0); - } - %s_func - """ % (signature, signature) - - with harmony.maintained_selection(): - self.log.info("Extracting %s" % str(list(instance))) - - harmony.send( - { - "function": render_func.format( - path=path.replace("\\", "/"), - filename=os.path.basename(path), - display_node=display_node - ), - "args": [instance[0]] - } - ) - - # Restore display. - if display_source_node: - harmony.send( - { - "function": restore_func, - "args": [display_node, display_source_node] - } - ) - - files = os.listdir(path) - collections, remainder = clique.assemble(files, minimum_items=1) - assert not remainder, ( - "There shouldn't have been a remainder for '%s': " - "%s" % (instance[0], remainder) - ) - assert len(collections) == 1, ( - "There should only be one image sequence in {}. Found: {}".format( - path, len(collections) - ) - ) - - data = { - "subset": collections[0].head, - "isSeries": True, - "stagingDir": path, - "files": list(collections[0]), - } - instance.data.update(data) - - self.log.info("Extracted {instance} to {path}".format(**locals())) -``` - -#### Loader Plugin -```python -import os -from uuid import uuid4 - -import ayon_harmony.api as harmony - -signature = str(uuid4()).replace("-", "_") -copy_files = """function copyFile(srcFilename, dstFilename) -{ - var srcFile = new PermanentFile(srcFilename); - var dstFile = new PermanentFile(dstFilename); - srcFile.copy(dstFile); -} -""" - -import_files = """function %s_import_files() -{ - var PNGTransparencyMode = 0; // Premultiplied with Black - var TGATransparencyMode = 0; // Premultiplied with Black - var SGITransparencyMode = 0; // Premultiplied with Black - var LayeredPSDTransparencyMode = 1; // Straight - var FlatPSDTransparencyMode = 2; // Premultiplied with White - - function getUniqueColumnName( column_prefix ) - { - var suffix = 0; - // finds if unique name for a column - var column_name = column_prefix; - while(suffix < 2000) - { - if(!column.type(column_name)) - break; - - suffix = suffix + 1; - column_name = column_prefix + "_" + suffix; - } - return column_name; - } - - function import_files(args) - { - var root = args[0]; - var files = args[1]; - var name = args[2]; - var start_frame = args[3]; - - var vectorFormat = null; - var extension = null; - var filename = files[0]; - - var pos = filename.lastIndexOf("."); - if( pos < 0 ) - return null; - - extension = filename.substr(pos+1).toLowerCase(); - - if(extension == "jpeg") - extension = "jpg"; - if(extension == "tvg") - { - vectorFormat = "TVG" - extension ="SCAN"; // element.add() will use this. - } - - var elemId = element.add( - name, - "BW", - scene.numberOfUnitsZ(), - extension.toUpperCase(), - vectorFormat - ); - if (elemId == -1) - { - // hum, unknown file type most likely -- let's skip it. - return null; // no read to add. - } - - var uniqueColumnName = getUniqueColumnName(name); - column.add(uniqueColumnName , "DRAWING"); - column.setElementIdOfDrawing(uniqueColumnName, elemId); - - var read = node.add(root, name, "READ", 0, 0, 0); - var transparencyAttr = node.getAttr( - read, frame.current(), "READ_TRANSPARENCY" - ); - var opacityAttr = node.getAttr(read, frame.current(), "OPACITY"); - transparencyAttr.setValue(true); - opacityAttr.setValue(true); - - var alignmentAttr = node.getAttr(read, frame.current(), "ALIGNMENT_RULE"); - alignmentAttr.setValue("ASIS"); - - var transparencyModeAttr = node.getAttr( - read, frame.current(), "applyMatteToColor" - ); - if (extension == "png") - transparencyModeAttr.setValue(PNGTransparencyMode); - if (extension == "tga") - transparencyModeAttr.setValue(TGATransparencyMode); - if (extension == "sgi") - transparencyModeAttr.setValue(SGITransparencyMode); - if (extension == "psd") - transparencyModeAttr.setValue(FlatPSDTransparencyMode); - - node.linkAttr(read, "DRAWING.ELEMENT", uniqueColumnName); - - // Create a drawing for each file. - for( var i =0; i <= files.length - 1; ++i) - { - timing = start_frame + i - // Create a drawing drawing, 'true' indicate that the file exists. - Drawing.create(elemId, timing, true); - // Get the actual path, in tmp folder. - var drawingFilePath = Drawing.filename(elemId, timing.toString()); - copyFile( files[i], drawingFilePath ); - - column.setEntry(uniqueColumnName, 1, timing, timing.toString()); - } - return read; - } - import_files(); -} -%s_import_files -""" % (signature, signature) - -replace_files = """function %s_replace_files(args) -{ - var files = args[0]; - var _node = args[1]; - var start_frame = args[2]; - - var _column = node.linkedColumn(_node, "DRAWING.ELEMENT"); - - // Delete existing drawings. - var timings = column.getDrawingTimings(_column); - for( var i =0; i <= timings.length - 1; ++i) - { - column.deleteDrawingAt(_column, parseInt(timings[i])); - } - - // Create new drawings. - for( var i =0; i <= files.length - 1; ++i) - { - timing = start_frame + i - // Create a drawing drawing, 'true' indicate that the file exists. - Drawing.create(node.getElementId(_node), timing, true); - // Get the actual path, in tmp folder. - var drawingFilePath = Drawing.filename( - node.getElementId(_node), timing.toString() - ); - copyFile( files[i], drawingFilePath ); - - column.setEntry(_column, 1, timing, timing.toString()); - } -} -%s_replace_files -""" % (signature, signature) - - -class ImageSequenceLoader(load.LoaderPlugin): - """Load images - Stores the imported asset in a container named after the asset. - """ - product_types = { - "shot", - "render", - "image", - "plate", - "reference", - "review", - } - representations = {"*"} - extensions = {"jpeg", "png", "jpg"} - - def load(self, context, name=None, namespace=None, data=None): - files = [] - for f in context["version"]["data"]["files"]: - files.append( - os.path.join( - context["version"]["data"]["stagingDir"], f - ).replace("\\", "/") - ) - - read_node = harmony.send( - { - "function": copy_files + import_files, - "args": ["Top", files, context["product"]["name"], 1] - } - )["result"] - - self[:] = [read_node] - - return harmony.containerise( - name, - namespace, - read_node, - context, - self.__class__.__name__ - ) - - def update(self, container, context): - node = container.pop("node") - - repre_entity = context["representation"] - project_name = get_current_project_name() - version = get_version_by_id(project_name, repre_entity["versionId"]) - files = [] - for f in version["data"]["files"]: - files.append( - os.path.join( - version["data"]["stagingDir"], f - ).replace("\\", "/") - ) - - harmony.send( - { - "function": copy_files + replace_files, - "args": [files, node, 1] - } - ) - - harmony.imprint( - node, {"representation": repre_entity["id"]} - ) - - def remove(self, container): - node = container.pop("node") - signature = str(uuid4()).replace("-", "_") - func = """function %s_deleteNode(_node) - { - node.deleteNode(_node, true, true); - } - %_deleteNode - """ % (signature, signature) - harmony.send( - {"function": func, "args": [node]} - ) - - def switch(self, container, context): - self.update(container, context) -``` - -## Resources -- https://github.com/diegogarciahuerta/tk-harmony -- https://github.com/cfourney/OpenHarmony -- [Toon Boom Discord](https://discord.gg/syAjy4H) -- [Toon Boom TD](https://discord.gg/yAjyQtZ) diff --git a/server_addon/harmony/client/ayon_harmony/api/TB_sceneOpened.js b/server_addon/harmony/client/ayon_harmony/api/TB_sceneOpened.js deleted file mode 100644 index 00858b6de1..0000000000 --- a/server_addon/harmony/client/ayon_harmony/api/TB_sceneOpened.js +++ /dev/null @@ -1,564 +0,0 @@ -/* global QTcpSocket, QByteArray, QDataStream, QTimer, QTextCodec, QIODevice, QApplication, include */ -/* global QTcpSocket, QByteArray, QDataStream, QTimer, QTextCodec, QIODevice, QApplication, include */ -/* -Avalon Harmony Integration - Client ------------------------------------ - -This script implements client communication with Avalon server to bridge -gap between Python and QtScript. - -*/ -/* jshint proto: true */ -var LD_OPENHARMONY_PATH = System.getenv('LIB_OPENHARMONY_PATH'); -LD_OPENHARMONY_PATH = LD_OPENHARMONY_PATH + '/openHarmony.js'; -LD_OPENHARMONY_PATH = LD_OPENHARMONY_PATH.replace(/\\/g, "/"); -include(LD_OPENHARMONY_PATH); -//this.__proto__['$'] = $; - -function Client() { - var self = this; - /** socket */ - self.socket = new QTcpSocket(this); - /** receiving data buffer */ - self.received = ''; - self.messageId = 1; - self.buffer = new QByteArray(); - self.waitingForData = 0; - - - /** - * pack number into bytes. - * @function - * @param {int} num 32 bit integer - * @return {string} - */ - self.pack = function(num) { - var ascii=''; - for (var i = 3; i >= 0; i--) { - var hex = ((num >> (8 * i)) & 255).toString(16); - if (hex.length < 2){ - ascii += "0"; - } - ascii += hex; - } - return ascii; - }; - - /** - * unpack number from string. - * @function - * @param {string} numString bytes to unpack - * @return {int} 32bit unsigned integer. - */ - self.unpack = function(numString) { - var result=0; - for (var i = 3; i >= 0; i--) { - result += numString.charCodeAt(3 - i) << (8 * i); - } - return result; - }; - - /** - * prettify json for easier debugging - * @function - * @param {object} json json to process - * @return {string} prettified json string - */ - self.prettifyJson = function(json) { - var jsonString = JSON.stringify(json); - return JSON.stringify(JSON.parse(jsonString), null, 2); - }; - - /** - * Log message in debug level. - * @function - * @param {string} data - message - */ - self.logDebug = function(data) { - var message = typeof(data.message) != 'undefined' ? data.message : data; - MessageLog.trace('(DEBUG): ' + message.toString()); - }; - - /** - * Log message in info level. - * @function - * @param {string} data - message - */ - self.logInfo = function(data) { - var message = typeof(data.message) != 'undefined' ? data.message : data; - MessageLog.trace('(DEBUG): ' + message.toString()); - }; - - /** - * Log message in warning level. - * @function - * @param {string} data - message - */ - self.logWarning = function(data) { - var message = typeof(data.message) != 'undefined' ? data.message : data; - MessageLog.trace('(INFO): ' + message.toString()); - }; - - /** - * Log message in error level. - * @function - * @param {string} data - message - */ - self.logError = function(data) { - var message = typeof(data.message) != 'undefined' ? data.message : data; - MessageLog.trace('(ERROR): ' +message.toString()); - }; - - /** - * Show message in Harmony GUI as popup window. - * @function - * @param {string} msg - message - */ - self.showMessage = function(msg) { - MessageBox.information(msg); - }; - - /** - * Implement missing setTimeout() in Harmony. - * This calls once given function after some interval in milliseconds. - * @function - * @param {function} fc function to call. - * @param {int} interval interval in milliseconds. - * @param {boolean} single behave as setTimeout or setInterval. - */ - self.setTimeout = function(fc, interval, single) { - var timer = new QTimer(); - if (!single) { - timer.singleShot = true; // in-case if setTimout and false in-case of setInterval - } else { - timer.singleShot = single; - } - timer.interval = interval; // set the time in milliseconds - timer.singleShot = true; // in-case if setTimout and false in-case of setInterval - timer.timeout.connect(this, function(){ - fc.call(); - }); - timer.start(); - }; - - /** - * Process received request. This will eval received function and produce - * results. - * @function - * @param {object} request - received request JSON - * @return {object} result of evaled function. - */ - self.processRequest = function(request) { - var mid = request.message_id; - if (typeof request.reply !== 'undefined') { - self.logDebug('['+ mid +'] *** received reply.'); - return; - } - self.logDebug('['+ mid +'] - Processing: ' + self.prettifyJson(request)); - var result = null; - - if (typeof request.script !== 'undefined') { - self.logDebug('[' + mid + '] Injecting script.'); - try { - eval.call(null, request.script); - } catch (error) { - self.logError(error); - } - } else if (typeof request["function"] !== 'undefined') { - try { - var _func = eval.call(null, request["function"]); - - if (request.args == null) { - result = _func(); - } else { - result = _func(request.args); - } - } catch (error) { - result = 'Error processing request.\n' + - 'Request:\n' + - self.prettifyJson(request) + '\n' + - 'Error:\n' + error; - } - } else { - self.logError('Command type not implemented.'); - } - - return result; - }; - - /** - * This gets called when socket received new data. - * @function - */ - self.onReadyRead = function() { - var currentSize = self.buffer.size(); - self.logDebug('--- Receiving data ( '+ currentSize + ' )...'); - var newData = self.socket.readAll(); - var newSize = newData.size(); - self.buffer.append(newData); - self.logDebug(' - got ' + newSize + ' bytes of new data.'); - self.processBuffer(); - }; - - /** - * Process data received in buffer. - * This detects messages by looking for header and message length. - * @function - */ - self.processBuffer = function() { - var length = self.waitingForData; - if (self.waitingForData == 0) { - // read header from the buffer and remove it - var header_data = self.buffer.mid(0, 6); - self.buffer = self.buffer.remove(0, 6); - - // convert header to string - var header = ''; - for (var i = 0; i < header_data.size(); ++i) { - // data in QByteArray come out as signed bytes. - var unsigned = header_data.at(i) & 0xff; - header = header.concat(String.fromCharCode(unsigned)); - } - - // skip 'AH' and read only length, unpack it to integer - header = header.substr(2); - length = self.unpack(header); - } - - var data = self.buffer.mid(0, length); - self.logDebug('--- Expected: ' + length + ' | Got: ' + data.size()); - if (length > data.size()) { - // we didn't received whole message. - self.waitingForData = length; - self.logDebug('... waiting for more data (' + length + ') ...'); - return; - } - self.waitingForData = 0; - self.buffer.remove(0, length); - - for (var j = 0; j < data.size(); ++j) { - self.received = self.received.concat(String.fromCharCode(data.at(j))); - } - - // self.logDebug('--- Received: ' + self.received); - var to_parse = self.received; - var request = JSON.parse(to_parse); - var mid = request.message_id; - // self.logDebug('[' + mid + '] - Request: ' + '\n' + JSON.stringify(request)); - self.logDebug('[' + mid + '] Received.'); - - request.result = self.processRequest(request); - self.logDebug('[' + mid + '] Processing done.'); - self.received = ''; - - if (request.reply !== true) { - request.reply = true; - self.logDebug('[' + mid + '] Replying.'); - self._send(JSON.stringify(request)); - } - - if ((length < data.size()) || (length < self.buffer.size())) { - // we've received more data. - self.logDebug('--- Got more data to process ...'); - self.processBuffer(); - } - }; - - /** - * Run when Harmony connects to server. - * @function - */ - self.onConnected = function() { - self.logDebug('Connected to server ...'); - self.lock = false; - self.socket.readyRead.connect(self.onReadyRead); - var app = QCoreApplication.instance(); - - app.avalonClient.send( - { - 'module': 'ayon_core.lib', - 'method': 'emit_event', - 'args': ['application.launched'] - }, false); - }; - - self._send = function(message) { - /** Harmony 21.1 doesn't have QDataStream anymore. - - This means we aren't able to write bytes into QByteArray so we had - modify how content length is sent do the server. - Content length is sent as string of 8 char convertible into integer - (instead of 0x00000001[4 bytes] > "000000001"[8 bytes]) */ - var codec_name = new QByteArray().append("UTF-8"); - - var codec = QTextCodec.codecForName(codec_name); - var msg = codec.fromUnicode(message); - var l = msg.size(); - var header = new QByteArray().append('AH').append(self.pack(l)); - var coded = msg.prepend(header); - - self.socket.write(coded); - self.logDebug('Sent.'); - }; - - self.waitForLock = function() { - if (self._lock === false) { - self.logDebug('>>> Unlocking ...'); - return; - } else { - self.logDebug('Setting timer.'); - self.setTimeout(self.waitForLock, 300); - } - }; - - /** - * Send request to server. - * @param {object} request - json encoded request. - */ - self.send = function(request) { - request.message_id = self.messageId; - if (typeof request.reply == 'undefined') { - self.logDebug("[" + self.messageId + "] sending:\n" + self.prettifyJson(request)); - } - self._send(JSON.stringify(request)); - }; - - /** - * Executed on disconnection. - */ - self.onDisconnected = function() { - self.socket.close(); - }; - - /** - * Disconnect from server. - */ - self.disconnect = function() { - self.socket.close(); - }; - - self.socket.connected.connect(self.onConnected); - self.socket.disconnected.connect(self.onDisconnected); -} - -/** - * Entry point, creating Avalon Client. - */ -function start() { - var self = this; - /** hostname or ip of server - should be localhost */ - var host = '127.0.0.1'; - /** port of the server */ - var port = parseInt(System.getenv('AYON_HARMONY_PORT')); - - // Attach the client to the QApplication to preserve. - var app = QCoreApplication.instance(); - - if (app.avalonClient == null) { - app.avalonClient = new Client(); - app.avalonClient.socket.connectToHost(host, port); - } - var mainWindow = null; - var widgets = QApplication.topLevelWidgets(); - for (var i = 0 ; i < widgets.length; i++) { - if (widgets[i] instanceof QMainWindow){ - mainWindow = widgets[i]; - } - } - var menuBar = mainWindow.menuBar(); - var actions = menuBar.actions(); - app.avalonMenu = null; - - for (var i = 0 ; i < actions.length; i++) { - label = System.getenv('AYON_MENU_LABEL'); - if (actions[i].text == label) { - app.avalonMenu = true; - } - } - - var menu = null; - if (app.avalonMenu == null) { - menu = menuBar.addMenu(System.getenv('AYON_MENU_LABEL')); - } - // menu = menuBar.addMenu('Avalon'); - - /** - * Show creator - */ - self.onCreator = function() { - app.avalonClient.send({ - 'module': 'ayon_harmony.api.lib', - 'method': 'show', - 'args': ['creator'] - }, false); - }; - - var action = menu.addAction('Create...'); - action.triggered.connect(self.onCreator); - - - /** - * Show Workfiles - */ - self.onWorkfiles = function() { - app.avalonClient.send({ - 'module': 'ayon_harmony.api.lib', - 'method': 'show', - 'args': ['workfiles'] - }, false); - }; - if (app.avalonMenu == null) { - action = menu.addAction('Workfiles...'); - action.triggered.connect(self.onWorkfiles); - } - - /** - * Show Loader - */ - self.onLoad = function() { - app.avalonClient.send({ - 'module': 'ayon_harmony.api.lib', - 'method': 'show', - 'args': ['loader'] - }, false); - }; - // add Loader item to menu - if (app.avalonMenu == null) { - action = menu.addAction('Load...'); - action.triggered.connect(self.onLoad); - } - - /** - * Show Publisher - */ - self.onPublish = function() { - app.avalonClient.send({ - 'module': 'ayon_harmony.api.lib', - 'method': 'show', - 'args': ['publish'] - }, false); - }; - // add Publisher item to menu - if (app.avalonMenu == null) { - action = menu.addAction('Publish...'); - action.triggered.connect(self.onPublish); - } - - /** - * Show Scene Manager - */ - self.onManage = function() { - app.avalonClient.send({ - 'module': 'ayon_harmony.api.lib', - 'method': 'show', - 'args': ['sceneinventory'] - }, false); - }; - // add Scene Manager item to menu - if (app.avalonMenu == null) { - action = menu.addAction('Manage...'); - action.triggered.connect(self.onManage); - } - - /** - * Show Subset Manager - */ - self.onSubsetManage = function() { - app.avalonClient.send({ - 'module': 'ayon_harmony.api.lib', - 'method': 'show', - 'args': ['subsetmanager'] - }, false); - }; - // add Subset Manager item to menu - if (app.avalonMenu == null) { - action = menu.addAction('Subset Manager...'); - action.triggered.connect(self.onSubsetManage); - } - - /** - * Set scene settings from DB to the scene - */ - self.onSetSceneSettings = function() { - app.avalonClient.send( - { - "module": "ayon_harmony.api", - "method": "ensure_scene_settings", - "args": [] - }, - false - ); - }; - // add Set Scene Settings - if (app.avalonMenu == null) { - action = menu.addAction('Set Scene Settings...'); - action.triggered.connect(self.onSetSceneSettings); - } - - /** - * Show Experimental dialog - */ - self.onExperimentalTools = function() { - app.avalonClient.send({ - 'module': 'ayon_harmony.api.lib', - 'method': 'show', - 'args': ['experimental_tools'] - }, false); - }; - // add Subset Manager item to menu - if (app.avalonMenu == null) { - action = menu.addAction('Experimental Tools...'); - action.triggered.connect(self.onExperimentalTools); - } - - // FIXME(antirotor): We need to disable `on_file_changed` now as is wreak - // havoc when "Save" is called multiple times and zipping didn't finished yet - /* - - // Watch scene file for changes. - app.onFileChanged = function(path) - { - var app = QCoreApplication.instance(); - if (app.avalonOnFileChanged){ - app.avalonClient.send( - { - 'module': 'avalon.harmony.lib', - 'method': 'on_file_changed', - 'args': [path] - }, - false - ); - } - - app.watcher.addPath(path); - }; - - - app.watcher = new QFileSystemWatcher(); - scene_path = scene.currentProjectPath() +"/" + scene.currentVersionName() + ".xstage"; - app.watcher.addPath(scenePath); - app.watcher.fileChanged.connect(app.onFileChanged); - app.avalonOnFileChanged = true; - */ - app.onFileChanged = function(path) { - // empty stub - return path; - }; -} - -function ensureSceneSettings() { - var app = QCoreApplication.instance(); - app.avalonClient.send( - { - "module": "ayon_harmony.api", - "method": "ensure_scene_settings", - "args": [] - }, - false - ); -} - -function TB_sceneOpened() -{ - start(); -} diff --git a/server_addon/harmony/client/ayon_harmony/api/__init__.py b/server_addon/harmony/client/ayon_harmony/api/__init__.py deleted file mode 100644 index bdcc43ea2f..0000000000 --- a/server_addon/harmony/client/ayon_harmony/api/__init__.py +++ /dev/null @@ -1,90 +0,0 @@ -"""Public API - -Anything that isn't defined here is INTERNAL and unreliable for external use. - -""" -from .pipeline import ( - ls, - install, - list_instances, - remove_instance, - select_instance, - containerise, - set_scene_settings, - get_current_context_settings, - ensure_scene_settings, - check_inventory, - application_launch, - export_template, - on_pyblish_instance_toggled, - inject_avalon_js, -) - -from .lib import ( - launch, - maintained_selection, - imprint, - read, - send, - maintained_nodes_state, - save_scene, - save_scene_as, - remove, - delete_node, - find_node_by_name, - signature, - select_nodes, - get_scene_data -) - -from .workio import ( - open_file, - save_file, - current_file, - has_unsaved_changes, - file_extensions, - work_root -) - -__all__ = [ - # pipeline - "ls", - "install", - "list_instances", - "remove_instance", - "select_instance", - "containerise", - "set_scene_settings", - "get_current_context_settings", - "ensure_scene_settings", - "check_inventory", - "application_launch", - "export_template", - "on_pyblish_instance_toggled", - "inject_avalon_js", - - # lib - "launch", - "maintained_selection", - "imprint", - "read", - "send", - "maintained_nodes_state", - "save_scene", - "save_scene_as", - "remove", - "delete_node", - "find_node_by_name", - "signature", - "select_nodes", - "get_scene_data", - - # Workfiles API - "open_file", - "save_file", - "current_file", - "has_unsaved_changes", - "file_extensions", - "work_root", -] - diff --git a/server_addon/harmony/client/ayon_harmony/api/js/.eslintrc.json b/server_addon/harmony/client/ayon_harmony/api/js/.eslintrc.json deleted file mode 100644 index d6a6661271..0000000000 --- a/server_addon/harmony/client/ayon_harmony/api/js/.eslintrc.json +++ /dev/null @@ -1,117 +0,0 @@ -{ - "env": { - "browser": true - }, - "extends": "eslint:recommended", - "parserOptions": { - "ecmaVersion": 3 - }, - "rules": { - "indent": [ - "error", - 4 - ], - "linebreak-style": [ - "error", - "unix" - ], - "quotes": [ - "error", - "single" - ], - "semi": [ - "error", - "always" - ] - }, - "globals": { - "Action": "readonly", - "Backdrop": "readonly", - "Button": "readonly", - "Cel": "readonly", - "Cel3d": "readonly", - "CheckBox": "readonly", - "ColorRGBA": "readonly", - "ComboBox": "readonly", - "DateEdit": "readonly", - "DateEditEnum": "readonly", - "Dialog": "readonly", - "Dir": "readonly", - "DirSpec": "readonly", - "Drawing": "readonly", - "DrawingToolParams": "readonly", - "DrawingTools": "readonly", - "EnvelopeCreator": "readonly", - "ExportVideoDlg": "readonly", - "File": "readonly", - "FileAccess": "readonly", - "FileDialog": "readonly", - "GroupBox": "readonly", - "ImportDrawingDlg": "readonly", - "Input": "readonly", - "KeyModifiers": "readonly", - "Label": "readonly", - "LayoutExports": "readonly", - "LayoutExportsParams": "readonly", - "LineEdit": "readonly", - "Matrix4x4": "readonly", - "MessageBox": "readonly", - "MessageLog": "readonly", - "Model3d": "readonly", - "MovieImport": "readonly", - "NumberEdit": "readonly", - "PaletteManager": "readonly", - "PaletteObjectManager": "readonly", - "PermanentFile": "readonly", - "Point2d": "readonly", - "Point3d": "readonly", - "Process": "readonly", - "Process2": "readonly", - "Quaternion": "readonly", - "QuicktimeExporter": "readonly", - "RadioButton": "readonly", - "RemoteCmd": "readonly", - "Scene": "readonly", - "Settings": "readonly", - "Slider": "readonly", - "SpinBox": "readonly", - "SubnodeData": "readonly", - "System": "readonly", - "TemporaryFile": "readonly", - "TextEdit": "readonly", - "TimeEdit": "readonly", - "Timeline": "readonly", - "ToolProperties": "readonly", - "UiLoader": "readonly", - "Vector2d": "readonly", - "Vector3d": "readonly", - "WebCCExporter": "readonly", - "Workspaces": "readonly", - "__scriptManager__": "readonly", - "__temporaryFileContext__": "readonly", - "about": "readonly", - "column": "readonly", - "compositionOrder": "readonly", - "copyPaste": "readonly", - "deformation": "readonly", - "drawingExport": "readonly", - "element": "readonly", - "exporter": "readonly", - "fileMapper": "readonly", - "frame": "readonly", - "func": "readonly", - "library": "readonly", - "node": "readonly", - "preferences": "readonly", - "render": "readonly", - "scene": "readonly", - "selection": "readonly", - "sound": "readonly", - "specialFolders": "readonly", - "translator": "readonly", - "view": "readonly", - "waypoint": "readonly", - "xsheet": "readonly", - "QCoreApplication": "readonly" - } -} diff --git a/server_addon/harmony/client/ayon_harmony/api/js/AvalonHarmony.js b/server_addon/harmony/client/ayon_harmony/api/js/AvalonHarmony.js deleted file mode 100644 index a536a07590..0000000000 --- a/server_addon/harmony/client/ayon_harmony/api/js/AvalonHarmony.js +++ /dev/null @@ -1,226 +0,0 @@ -// *************************************************************************** -// * Avalon Harmony Host * -// *************************************************************************** - - -/** - * @namespace - * @classdesc AvalonHarmony encapsulate all Avalon related functions. - */ -var AvalonHarmony = {}; - - -/** - * Get scene metadata from Harmony. - * @function - * @return {object} Scene metadata. - */ -AvalonHarmony.getSceneData = function() { - var metadata = scene.metadata('avalon'); - if (metadata){ - return JSON.parse(metadata.value); - }else { - return {}; - } -}; - - -/** - * Set scene metadata to Harmony. - * @function - * @param {object} metadata Object containing metadata. - */ -AvalonHarmony.setSceneData = function(metadata) { - scene.setMetadata({ - 'name' : 'avalon', - 'type' : 'string', - 'creator' : 'Avalon', - 'version' : '1.0', - 'value' : JSON.stringify(metadata) - }); -}; - - -/** - * Get selected nodes in Harmony. - * @function - * @return {array} Selected nodes paths. - */ -AvalonHarmony.getSelectedNodes = function () { - var selectionLength = selection.numberOfNodesSelected(); - var selectedNodes = []; - for (var i = 0 ; i < selectionLength; i++) { - selectedNodes.push(selection.selectedNode(i)); - } - return selectedNodes; -}; - - -/** - * Set selection of nodes. - * @function - * @param {array} nodes Arrya containing node paths to add to selection. - */ -AvalonHarmony.selectNodes = function(nodes) { - selection.clearSelection(); - for (var i = 0 ; i < nodes.length; i++) { - selection.addNodeToSelection(nodes[i]); - } -}; - - -/** - * Is node enabled? - * @function - * @param {string} node Node path. - * @return {boolean} state - */ -AvalonHarmony.isEnabled = function(node) { - return node.getEnable(node); -}; - - -/** - * Are nodes enabled? - * @function - * @param {array} nodes Array of node paths. - * @return {array} array of boolean states. - */ -AvalonHarmony.areEnabled = function(nodes) { - var states = []; - for (var i = 0 ; i < nodes.length; i++) { - states.push(node.getEnable(nodes[i])); - } - return states; -}; - - -/** - * Set state on nodes. - * @function - * @param {array} args Array of nodes array and states array. - */ -AvalonHarmony.setState = function(args) { - var nodes = args[0]; - var states = args[1]; - // length of both arrays must be equal. - if (nodes.length !== states.length) { - return false; - } - for (var i = 0 ; i < nodes.length; i++) { - node.setEnable(nodes[i], states[i]); - } - return true; -}; - - -/** - * Disable specified nodes. - * @function - * @param {array} nodes Array of nodes. - */ -AvalonHarmony.disableNodes = function(nodes) { - for (var i = 0 ; i < nodes.length; i++) - { - node.setEnable(nodes[i], false); - } -}; - - -/** - * Save scene in Harmony. - * @function - * @return {string} Scene path. - */ -AvalonHarmony.saveScene = function() { - var app = QCoreApplication.instance(); - app.avalon_on_file_changed = false; - scene.saveAll(); - return ( - scene.currentProjectPath() + '/' + - scene.currentVersionName() + '.xstage' - ); -}; - - -/** - * Enable Harmony file-watcher. - * @function - */ -AvalonHarmony.enableFileWather = function() { - var app = QCoreApplication.instance(); - app.avalon_on_file_changed = true; -}; - - -/** - * Add path to file-watcher. - * @function - * @param {string} path Path to watch. - */ -AvalonHarmony.addPathToWatcher = function(path) { - var app = QCoreApplication.instance(); - app.watcher.addPath(path); -}; - - -/** - * Setup node for Creator. - * @function - * @param {string} node Node path. - */ -AvalonHarmony.setupNodeForCreator = function(node) { - node.setTextAttr(node, 'COMPOSITE_MODE', 1, 'Pass Through'); -}; - - -/** - * Get node names for specified node type. - * @function - * @param {string} nodeType Node type. - * @return {array} Node names. - */ -AvalonHarmony.getNodesNamesByType = function(nodeType) { - var nodes = node.getNodes(nodeType); - var nodeNames = []; - for (var i = 0; i < nodes.length; ++i) { - nodeNames.push(node.getName(nodes[i])); - } - return nodeNames; -}; - - -/** - * Create container node in Harmony. - * @function - * @param {array} args Arguments, see example. - * @return {string} Resulting node. - * - * @example - * // arguments are in following order: - * var args = [ - * nodeName, - * nodeType, - * selection - * ]; - */ -AvalonHarmony.createContainer = function(args) { - var resultNode = node.add('Top', args[0], args[1], 0, 0, 0); - if (args.length > 2) { - node.link(args[2], 0, resultNode, 0, false, true); - node.setCoord(resultNode, - node.coordX(args[2]), - node.coordY(args[2]) + 70); - } - return resultNode; -}; - - -/** - * Delete node. - * @function - * @param {string} node Node path. - */ -AvalonHarmony.deleteNode = function(_node) { - node.deleteNode(_node, true, true); -}; \ No newline at end of file diff --git a/server_addon/harmony/client/ayon_harmony/api/js/package.json b/server_addon/harmony/client/ayon_harmony/api/js/package.json deleted file mode 100644 index 9456895cf3..0000000000 --- a/server_addon/harmony/client/ayon_harmony/api/js/package.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "avalon-harmony", - "version": "1.0.0", - "description": "Avalon Harmony Host integration", - "keywords": [ - "Avalon", - "Harmony", - "pipeline" - ], - "license": "MIT", - "main": "AvalonHarmony.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "devDependencies": { - "eslint": "^7.11.0" - } -} diff --git a/server_addon/harmony/client/ayon_harmony/api/launch_script.py b/server_addon/harmony/client/ayon_harmony/api/launch_script.py deleted file mode 100644 index 6327682a43..0000000000 --- a/server_addon/harmony/client/ayon_harmony/api/launch_script.py +++ /dev/null @@ -1,93 +0,0 @@ -"""Script wraps launch mechanism of Harmony implementations. - -Arguments passed to the script are passed to launch function in host -implementation. In all cases requires host app executable and may contain -workfile or others. -""" - -import os -import sys - -from ayon_harmony.api.lib import main as host_main - -# Get current file to locate start point of sys.argv -CURRENT_FILE = os.path.abspath(__file__) - - -def show_error_messagebox(title, message, detail_message=None): - """Function will show message and process ends after closing it.""" - from qtpy import QtWidgets, QtCore - from ayon_core import style - - app = QtWidgets.QApplication([]) - app.setStyleSheet(style.load_stylesheet()) - - msgbox = QtWidgets.QMessageBox() - msgbox.setWindowTitle(title) - msgbox.setText(message) - - if detail_message: - msgbox.setDetailedText(detail_message) - - msgbox.setWindowModality(QtCore.Qt.ApplicationModal) - msgbox.show() - - sys.exit(app.exec_()) - - -def on_invalid_args(script_not_found): - """Show to user message box saying that something went wrong. - - Tell user that arguments to launch implementation are invalid with - arguments details. - - Args: - script_not_found (bool): Use different message based on this value. - """ - - title = "Invalid arguments" - joined_args = ", ".join("\"{}\"".format(arg) for arg in sys.argv) - if script_not_found: - submsg = "Where couldn't find script path:\n\"{}\"" - else: - submsg = "Expected Host executable after script path:\n\"{}\"" - - message = "BUG: Got invalid arguments so can't launch Host application." - detail_message = "Process was launched with arguments:\n{}\n\n{}".format( - joined_args, - submsg.format(CURRENT_FILE) - ) - - show_error_messagebox(title, message, detail_message) - - -def main(argv): - # Modify current file path to find match in sys.argv which may be different - # on windows (different letter cases and slashes). - modified_current_file = CURRENT_FILE.replace("\\", "/").lower() - - # Create a copy of sys argv - sys_args = list(argv) - after_script_idx = None - # Find script path in sys.argv to know index of argv where host - # executable should be. - for idx, item in enumerate(sys_args): - if item.replace("\\", "/").lower() == modified_current_file: - after_script_idx = idx + 1 - break - - # Validate that there is at least one argument after script path - launch_args = None - if after_script_idx is not None: - launch_args = sys_args[after_script_idx:] - - if launch_args: - # Launch host implementation - host_main(*launch_args) - else: - # Show message box - on_invalid_args(after_script_idx is None) - - -if __name__ == "__main__": - main(sys.argv) diff --git a/server_addon/harmony/client/ayon_harmony/api/lib.py b/server_addon/harmony/client/ayon_harmony/api/lib.py deleted file mode 100644 index 46a5318430..0000000000 --- a/server_addon/harmony/client/ayon_harmony/api/lib.py +++ /dev/null @@ -1,638 +0,0 @@ -# -*- coding: utf-8 -*- -"""Utility functions used for Avalon - Harmony integration.""" -import platform -import subprocess -import threading -import os -import random -import zipfile -import sys -import filecmp -import shutil -import logging -import contextlib -import json -import signal -import time -from uuid import uuid4 -import collections - -from qtpy import QtWidgets, QtCore, QtGui - -from ayon_core.lib import is_using_ayon_console -from ayon_core.tools.stdout_broker import StdOutBroker -from ayon_core.tools.utils import host_tools -from ayon_core import style - -from .server import Server - -# Setup logging. -log = logging.getLogger(__name__) -log.setLevel(logging.DEBUG) - - -class ProcessContext: - server = None - pid = None - process = None - application_path = None - callback_queue = collections.deque() - workfile_path = None - port = None - stdout_broker = None - workfile_tool = None - - @classmethod - def execute_in_main_thread(cls, func_to_call_from_main_thread): - cls.callback_queue.append(func_to_call_from_main_thread) - - @classmethod - def main_thread_listen(cls): - if cls.callback_queue: - callback = cls.callback_queue.popleft() - callback() - if cls.process is not None and cls.process.poll() is not None: - log.info("Server is not running, closing") - ProcessContext.stdout_broker.stop() - QtWidgets.QApplication.quit() - - -def signature(postfix="func") -> str: - """Return random ECMA6 compatible function name. - - Args: - postfix (str): name to append to random string. - Returns: - str: random function name. - - """ - return "f{}_{}".format(str(uuid4()).replace("-", "_"), postfix) - - -class _ZipFile(zipfile.ZipFile): - """Extended check for windows invalid characters.""" - - # this is extending default zipfile table for few invalid characters - # that can come from Mac - _windows_illegal_characters = ":<>|\"?*\r\n\x00" - _windows_illegal_name_trans_table = str.maketrans( - _windows_illegal_characters, - "_" * len(_windows_illegal_characters) - ) - - -def main(*subprocess_args): - # coloring in StdOutBroker - os.environ["AYON_LOG_NO_COLORS"] = "0" - app = QtWidgets.QApplication([]) - app.setQuitOnLastWindowClosed(False) - icon = QtGui.QIcon(style.get_app_icon_path()) - app.setWindowIcon(icon) - - ProcessContext.stdout_broker = StdOutBroker('harmony') - ProcessContext.stdout_broker.start() - launch(*subprocess_args) - - loop_timer = QtCore.QTimer() - loop_timer.setInterval(20) - - loop_timer.timeout.connect(ProcessContext.main_thread_listen) - loop_timer.start() - - sys.exit(app.exec_()) - - -def setup_startup_scripts(): - """Manages installation of avalon's TB_sceneOpened.js for Harmony launch. - - If a studio already has defined "TOONBOOM_GLOBAL_SCRIPT_LOCATION", copies - the TB_sceneOpened.js to that location if the file is different. - Otherwise, will set the env var to point to the avalon/harmony folder. - - Admins should be aware that this will overwrite TB_sceneOpened in the - "TOONBOOM_GLOBAL_SCRIPT_LOCATION", and that if they want to have additional - logic, they will need to one of the following: - * Create a Harmony package to manage startup logic - * Use TB_sceneOpenedUI.js instead to manage startup logic - * Add their startup logic to avalon/harmony/TB_sceneOpened.js - """ - avalon_dcc_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), - "api") - startup_js = "TB_sceneOpened.js" - - if os.getenv("TOONBOOM_GLOBAL_SCRIPT_LOCATION"): - - avalon_harmony_startup = os.path.join(avalon_dcc_dir, startup_js) - - env_harmony_startup = os.path.join( - os.getenv("TOONBOOM_GLOBAL_SCRIPT_LOCATION"), startup_js) - - if not filecmp.cmp(avalon_harmony_startup, env_harmony_startup): - try: - shutil.copy(avalon_harmony_startup, env_harmony_startup) - except Exception as e: - log.error(e) - log.warning( - "Failed to copy {0} to {1}! " - "Defaulting to Avalon TOONBOOM_GLOBAL_SCRIPT_LOCATION." - .format(avalon_harmony_startup, env_harmony_startup)) - - os.environ["TOONBOOM_GLOBAL_SCRIPT_LOCATION"] = avalon_dcc_dir - else: - os.environ["TOONBOOM_GLOBAL_SCRIPT_LOCATION"] = avalon_dcc_dir - - -def check_libs(): - """Check if `OpenHarmony`_ is available. - - Avalon expects either path in `LIB_OPENHARMONY_PATH` or `openHarmony.js` - present in `TOONBOOM_GLOBAL_SCRIPT_LOCATION`. - - Throws: - RuntimeError: If openHarmony is not found. - - .. _OpenHarmony: - https://github.com/cfourney/OpenHarmony - - """ - if not os.getenv("LIB_OPENHARMONY_PATH"): - - if os.getenv("TOONBOOM_GLOBAL_SCRIPT_LOCATION"): - if os.path.exists( - os.path.join( - os.getenv("TOONBOOM_GLOBAL_SCRIPT_LOCATION"), - "openHarmony.js")): - - os.environ["LIB_OPENHARMONY_PATH"] = \ - os.getenv("TOONBOOM_GLOBAL_SCRIPT_LOCATION") - return - - else: - log.error(("Cannot find OpenHarmony library. " - "Please set path to it in LIB_OPENHARMONY_PATH " - "environment variable.")) - raise RuntimeError("Missing OpenHarmony library.") - - -def launch(application_path, *args): - """Set Harmony for launch. - - Launches Harmony and the server, then starts listening on the main thread - for callbacks from the server. This is to have Qt applications run in the - main thread. - - Args: - application_path (str): Path to Harmony. - - """ - from ayon_core.pipeline import install_host - from ayon_harmony import api as harmony - - install_host(harmony) - - ProcessContext.port = random.randrange(49152, 65535) - os.environ["AYON_HARMONY_PORT"] = str(ProcessContext.port) - ProcessContext.application_path = application_path - - # Launch Harmony. - setup_startup_scripts() - check_libs() - - if not os.environ.get("AYON_HARMONY_WORKFILES_ON_LAUNCH", False): - open_empty_workfile() - return - - ProcessContext.workfile_tool = host_tools.get_tool_by_name("workfiles") - host_tools.show_workfiles(save=False) - ProcessContext.execute_in_main_thread(check_workfiles_tool) - - -def check_workfiles_tool(): - if ProcessContext.workfile_tool.isVisible(): - ProcessContext.execute_in_main_thread(check_workfiles_tool) - elif not ProcessContext.workfile_path: - open_empty_workfile() - - -def open_empty_workfile(): - zip_file = os.path.join(os.path.dirname(__file__), "temp.zip") - temp_path = get_local_harmony_path(zip_file) - if os.path.exists(temp_path): - log.info(f"removing existing {temp_path}") - try: - shutil.rmtree(temp_path) - except Exception as e: - log.critical(f"cannot clear {temp_path}") - raise Exception(f"cannot clear {temp_path}") from e - - launch_zip_file(zip_file) - - -def get_local_harmony_path(filepath): - """From the provided path get the equivalent local Harmony path.""" - basename = os.path.splitext(os.path.basename(filepath))[0] - harmony_path = os.path.join(os.path.expanduser("~"), ".avalon", "harmony") - return os.path.join(harmony_path, basename) - - -def launch_zip_file(filepath): - """Launch a Harmony application instance with the provided zip file. - - Args: - filepath (str): Path to file. - """ - print(f"Localizing {filepath}") - - temp_path = get_local_harmony_path(filepath) - scene_name = os.path.basename(temp_path) - if os.path.exists(os.path.join(temp_path, scene_name)): - # unzipped with duplicated scene_name - temp_path = os.path.join(temp_path, scene_name) - - scene_path = os.path.join( - temp_path, scene_name + ".xstage" - ) - - unzip = False - if os.path.exists(scene_path): - # Check remote scene is newer than local. - if os.path.getmtime(scene_path) < os.path.getmtime(filepath): - try: - shutil.rmtree(temp_path) - except Exception as e: - log.error(e) - raise Exception("Cannot delete working folder") from e - unzip = True - else: - unzip = True - - if unzip: - with _ZipFile(filepath, "r") as zip_ref: - zip_ref.extractall(temp_path) - - if os.path.exists(os.path.join(temp_path, scene_name)): - # unzipped with duplicated scene_name - temp_path = os.path.join(temp_path, scene_name) - - # Close existing scene. - if ProcessContext.pid: - os.kill(ProcessContext.pid, signal.SIGTERM) - - # Stop server. - if ProcessContext.server: - ProcessContext.server.stop() - - # Launch Avalon server. - ProcessContext.server = Server(ProcessContext.port) - ProcessContext.server.start() - # thread = threading.Thread(target=self.server.start) - # thread.daemon = True - # thread.start() - - # Save workfile path for later. - ProcessContext.workfile_path = filepath - - # find any xstage files is directory, prefer the one with the same name - # as directory (plus extension) - xstage_files = [] - for _, _, files in os.walk(temp_path): - for file in files: - if os.path.splitext(file)[1] == ".xstage": - xstage_files.append(file) - - if not os.path.basename("temp.zip"): - if not xstage_files: - ProcessContext.server.stop() - print("no xstage file was found") - return - - # try to use first available - scene_path = os.path.join( - temp_path, xstage_files[0] - ) - - # prefer the one named as zip file - zip_based_name = "{}.xstage".format( - os.path.splitext(os.path.basename(filepath))[0]) - - if zip_based_name in xstage_files: - scene_path = os.path.join( - temp_path, zip_based_name - ) - - if not os.path.exists(scene_path): - print("error: cannot determine scene file {}".format(scene_path)) - ProcessContext.server.stop() - return - - print("Launching {}".format(scene_path)) - # QUESTION Could we use 'run_detached_process' from 'ayon_core.lib'? - kwargs = {} - if ( - platform.system().lower() == "windows" - and not is_using_ayon_console() - ): - kwargs.update({ - "creationflags": subprocess.CREATE_NO_WINDOW, - "stdout": subprocess.DEVNULL, - "stderr": subprocess.DEVNULL - }) - - process = subprocess.Popen( - [ProcessContext.application_path, scene_path], - **kwargs - ) - ProcessContext.pid = process.pid - ProcessContext.process = process - ProcessContext.stdout_broker.host_connected() - - -def on_file_changed(path, threaded=True): - """Threaded zipping and move of the project directory. - - This method is called when the `.xstage` file is changed. - """ - log.debug("File changed: " + path) - - if ProcessContext.workfile_path is None: - return - - if threaded: - thread = threading.Thread( - target=zip_and_move, - args=(os.path.dirname(path), ProcessContext.workfile_path) - ) - thread.start() - else: - zip_and_move(os.path.dirname(path), ProcessContext.workfile_path) - - -def zip_and_move(source, destination): - """Zip a directory and move to `destination`. - - Args: - source (str): Directory to zip and move to destination. - destination (str): Destination file path to zip file. - - """ - os.chdir(os.path.dirname(source)) - shutil.make_archive(os.path.basename(source), "zip", source) - with _ZipFile(os.path.basename(source) + ".zip") as zr: - if zr.testzip() is not None: - raise Exception("File archive is corrupted.") - shutil.move(os.path.basename(source) + ".zip", destination) - log.debug(f"Saved '{source}' to '{destination}'") - - -def show(tool_name): - """Call show on "module_name". - - This allows to make a QApplication ahead of time and always "exec_" to - prevent crashing. - - Args: - module_name (str): Name of module to call "show" on. - - """ - # Requests often get doubled up when showing tools, so we wait a second for - # requests to be received properly. - time.sleep(1) - - kwargs = {} - if tool_name == "loader": - kwargs["use_context"] = True - - ProcessContext.execute_in_main_thread( - lambda: host_tools.show_tool_by_name(tool_name, **kwargs) - ) - - # Required return statement. - return "nothing" - - -def get_scene_data(): - try: - return send( - { - "function": "AvalonHarmony.getSceneData" - })["result"] - except json.decoder.JSONDecodeError: - # Means no scene metadata has been made before. - return {} - except KeyError: - # Means no existing scene metadata has been made. - return {} - - -def set_scene_data(data): - """Write scene data to metadata. - - Args: - data (dict): Data to write. - - """ - # Write scene data. - send( - { - "function": "AvalonHarmony.setSceneData", - "args": data - }) - - -def read(node_id): - """Read object metadata in to a dictionary. - - Args: - node_id (str): Path to node or id of object. - - Returns: - dict - """ - scene_data = get_scene_data() - if node_id in scene_data: - return scene_data[node_id] - - return {} - - -def remove(node_id): - """ - Remove node data from scene metadata. - - Args: - node_id (str): full name (eg. 'Top/renderAnimation') - """ - data = get_scene_data() - del data[node_id] - set_scene_data(data) - - -def delete_node(node): - """ Physically delete node from scene. """ - send( - { - "function": "AvalonHarmony.deleteNode", - "args": node - } - ) - - -def imprint(node_id, data, remove=False): - """Write `data` to the `node` as json. - - Arguments: - node_id (str): Path to node or id of object. - data (dict): Dictionary of key/value pairs. - remove (bool): Removes the data from the scene. - - Example: - >>> from ayon_harmony.api import lib - >>> node = "Top/Display" - >>> data = {"str": "something", "int": 1, "float": 0.32, "bool": True} - >>> lib.imprint(layer, data) - """ - scene_data = get_scene_data() - - if remove and (node_id in scene_data): - scene_data.pop(node_id, None) - else: - if node_id in scene_data: - scene_data[node_id].update(data) - else: - scene_data[node_id] = data - - set_scene_data(scene_data) - - -@contextlib.contextmanager -def maintained_selection(): - """Maintain selection during context.""" - - selected_nodes = send( - { - "function": "AvalonHarmony.getSelectedNodes" - })["result"] - - try: - yield selected_nodes - finally: - selected_nodes = send( - { - "function": "AvalonHarmony.selectNodes", - "args": selected_nodes - } - ) - - -def send(request): - """Public method for sending requests to Harmony.""" - return ProcessContext.server.send(request) - - -def select_nodes(nodes): - """ Selects nodes in Node View """ - _ = send( - { - "function": "AvalonHarmony.selectNodes", - "args": nodes - } - ) - - -@contextlib.contextmanager -def maintained_nodes_state(nodes): - """Maintain nodes states during context.""" - # Collect current state. - states = send( - { - "function": "AvalonHarmony.areEnabled", "args": nodes - })["result"] - - # Disable all nodes. - send( - { - "function": "AvalonHarmony.disableNodes", "args": nodes - }) - - try: - yield - finally: - send( - { - "function": "AvalonHarmony.setState", - "args": [nodes, states] - }) - - -def save_scene(): - """Save the Harmony scene safely. - - The built-in (to Avalon) background zip and moving of the Harmony scene - folder, interferes with server/client communication by sending two requests - at the same time. This only happens when sending "scene.saveAll()". This - method prevents this double request and safely saves the scene. - - """ - # Need to turn off the background watcher else the communication with - # the server gets spammed with two requests at the same time. - scene_path = send( - {"function": "AvalonHarmony.saveScene"})["result"] - - # Manually update the remote file. - on_file_changed(scene_path, threaded=False) - - # Re-enable the background watcher. - send({"function": "AvalonHarmony.enableFileWather"}) - - -def save_scene_as(filepath): - """Save Harmony scene as `filepath`.""" - scene_dir = os.path.dirname(filepath) - destination = os.path.join( - os.path.dirname(ProcessContext.workfile_path), - os.path.splitext(os.path.basename(filepath))[0] + ".zip" - ) - - if os.path.exists(scene_dir): - try: - shutil.rmtree(scene_dir) - except Exception as e: - log.error(f"Cannot remove {scene_dir}") - raise Exception(f"Cannot remove {scene_dir}") from e - - send( - {"function": "scene.saveAs", "args": [scene_dir]} - )["result"] - - zip_and_move(scene_dir, destination) - - ProcessContext.workfile_path = destination - - send( - {"function": "AvalonHarmony.addPathToWatcher", "args": filepath} - ) - - -def find_node_by_name(name, node_type): - """Find node by its name. - - Args: - name (str): Name of the Node. (without part before '/') - node_type (str): Type of the Node. - 'READ' - for loaded data with Loaders (background) - 'GROUP' - for loaded data with Loaders (templates) - 'WRITE' - render nodes - - Returns: - str: FQ Node name. - - """ - nodes = send( - {"function": "node.getNodes", "args": [[node_type]]} - )["result"] - for node in nodes: - node_name = node.split("/")[-1] - if name == node_name: - return node - - return None diff --git a/server_addon/harmony/client/ayon_harmony/api/pipeline.py b/server_addon/harmony/client/ayon_harmony/api/pipeline.py deleted file mode 100644 index 229dcf307e..0000000000 --- a/server_addon/harmony/client/ayon_harmony/api/pipeline.py +++ /dev/null @@ -1,346 +0,0 @@ -import os -from pathlib import Path -import logging - -import pyblish.api - -from ayon_core.lib import register_event_callback -from ayon_core.pipeline import ( - register_loader_plugin_path, - register_creator_plugin_path, - deregister_loader_plugin_path, - deregister_creator_plugin_path, - AVALON_CONTAINER_ID, -) -from ayon_core.pipeline.load import get_outdated_containers -from ayon_core.pipeline.context_tools import get_current_folder_entity - -from ayon_harmony import HARMONY_ADDON_ROOT -import ayon_harmony.api as harmony - - -log = logging.getLogger("ayon_harmony") - -PLUGINS_DIR = os.path.join(HARMONY_ADDON_ROOT, "plugins") -PUBLISH_PATH = os.path.join(PLUGINS_DIR, "publish") -LOAD_PATH = os.path.join(PLUGINS_DIR, "load") -CREATE_PATH = os.path.join(PLUGINS_DIR, "create") -INVENTORY_PATH = os.path.join(PLUGINS_DIR, "inventory") - - -def set_scene_settings(settings): - """Set correct scene settings in Harmony. - - Args: - settings (dict): Scene settings. - - Returns: - dict: Dictionary of settings to set. - - """ - harmony.send( - {"function": "PypeHarmony.setSceneSettings", "args": settings}) - - -def get_current_context_settings(): - """Get settings on current folder from server. - - Returns: - dict: Scene data. - - """ - - folder_entity = get_current_folder_entity() - folder_attributes = folder_entity["attrib"] - - fps = folder_attributes.get("fps") - frame_start = folder_attributes.get("frameStart") - frame_end = folder_attributes.get("frameEnd") - handle_start = folder_attributes.get("handleStart") - handle_end = folder_attributes.get("handleEnd") - resolution_width = folder_attributes.get("resolutionWidth") - resolution_height = folder_attributes.get("resolutionHeight") - entity_type = folder_attributes.get("entityType") - - scene_data = { - "fps": fps, - "frameStart": frame_start, - "frameEnd": frame_end, - "handleStart": handle_start, - "handleEnd": handle_end, - "resolutionWidth": resolution_width, - "resolutionHeight": resolution_height, - "entityType": entity_type - } - - return scene_data - - -def ensure_scene_settings(): - """Validate if Harmony scene has valid settings.""" - settings = get_current_context_settings() - - invalid_settings = [] - valid_settings = {} - for key, value in settings.items(): - if value is None: - invalid_settings.append(key) - else: - valid_settings[key] = value - - # Warn about missing attributes. - if invalid_settings: - msg = "Missing attributes:" - for item in invalid_settings: - msg += f"\n{item}" - - harmony.send( - {"function": "PypeHarmony.message", "args": msg}) - - set_scene_settings(valid_settings) - - -def check_inventory(): - """Check is scene contains outdated containers. - - If it does it will colorize outdated nodes and display warning message - in Harmony. - """ - - outdated_containers = get_outdated_containers() - if not outdated_containers: - return - - # Colour nodes. - outdated_nodes = [] - for container in outdated_containers: - if container["loader"] == "ImageSequenceLoader": - outdated_nodes.append( - harmony.find_node_by_name(container["name"], "READ") - ) - harmony.send({"function": "PypeHarmony.setColor", "args": outdated_nodes}) - - # Warn about outdated containers. - msg = "There are outdated containers in the scene." - harmony.send({"function": "PypeHarmony.message", "args": msg}) - - -def application_launch(event): - """Event that is executed after Harmony is launched.""" - # fills AYON_HARMONY_JS - pype_harmony_path = Path(__file__).parent.parent / "js" / "PypeHarmony.js" - pype_harmony_js = pype_harmony_path.read_text() - - # go through js/creators, loaders and publish folders and load all scripts - script = "" - for item in ["creators", "loaders", "publish"]: - dir_to_scan = Path(__file__).parent.parent / "js" / item - for child in dir_to_scan.iterdir(): - script += child.read_text() - - # send scripts to Harmony - harmony.send({"script": pype_harmony_js}) - harmony.send({"script": script}) - inject_avalon_js() - - # ensure_scene_settings() - check_inventory() - - -def export_template(backdrops, nodes, filepath): - """Export Template to file. - - Args: - backdrops (list): List of backdrops to export. - nodes (list): List of nodes to export. - filepath (str): Path where to save Template. - - """ - harmony.send({ - "function": "PypeHarmony.exportTemplate", - "args": [ - backdrops, - nodes, - os.path.basename(filepath), - os.path.dirname(filepath) - ] - }) - - -def install(): - """Install Pype as host config.""" - print("Installing Pype config ...") - - pyblish.api.register_host("harmony") - pyblish.api.register_plugin_path(PUBLISH_PATH) - register_loader_plugin_path(LOAD_PATH) - register_creator_plugin_path(CREATE_PATH) - log.info(PUBLISH_PATH) - - # Register callbacks. - pyblish.api.register_callback( - "instanceToggled", on_pyblish_instance_toggled - ) - - register_event_callback("application.launched", application_launch) - - -def uninstall(): - pyblish.api.deregister_plugin_path(PUBLISH_PATH) - deregister_loader_plugin_path(LOAD_PATH) - deregister_creator_plugin_path(CREATE_PATH) - - -def on_pyblish_instance_toggled(instance, old_value, new_value): - """Toggle node enabling on instance toggles.""" - node = None - if instance.data.get("setMembers"): - node = instance.data["setMembers"][0] - - if node: - harmony.send( - { - "function": "PypeHarmony.toggleInstance", - "args": [node, new_value] - } - ) - - -def inject_avalon_js(): - """Inject AvalonHarmony.js into Harmony.""" - avalon_harmony_js = Path(__file__).parent.joinpath("js/AvalonHarmony.js") - script = avalon_harmony_js.read_text() - # send AvalonHarmony.js to Harmony - harmony.send({"script": script}) - - -def ls(): - """Yields containers from Harmony scene. - - This is the host-equivalent of api.ls(), but instead of listing - assets on disk, it lists assets already loaded in Harmony; once loaded - they are called 'containers'. - - Yields: - dict: container - """ - objects = harmony.get_scene_data() or {} - for _, data in objects.items(): - # Skip non-tagged objects. - if not data: - continue - - # Filter to only containers. - if "container" not in data.get("id"): - continue - - if not data.get("objectName"): # backward compatibility - data["objectName"] = data["name"] - yield data - - -def list_instances(remove_orphaned=True): - """ - List all created instances from current workfile which - will be published. - - Pulls from File > File Info - - For SubsetManager, by default it check if instance has matching node - in the scene, if not, instance gets deleted from metadata. - - Returns: - (list) of dictionaries matching instances format - """ - objects = harmony.get_scene_data() or {} - instances = [] - for key, data in objects.items(): - # Skip non-tagged objects. - if not data: - continue - - # Filter out containers. - if "container" in data.get("id"): - continue - - data['uuid'] = key - - if remove_orphaned: - node_name = key.split("/")[-1] - located_node = harmony.find_node_by_name(node_name, 'WRITE') - if not located_node: - print("Removing orphaned instance {}".format(key)) - harmony.remove(key) - continue - - instances.append(data) - - return instances - - -def remove_instance(instance): - """ - Remove instance from current workfile metadata and from scene! - - Updates metadata of current file in File > File Info and removes - icon highlight on group layer. - - For SubsetManager - - Args: - instance (dict): instance representation from subsetmanager model - """ - node = instance.get("uuid") - harmony.remove(node) - harmony.delete_node(node) - - -def select_instance(instance): - """ - Select instance in Node View - - Args: - instance (dict): instance representation from subsetmanager model - """ - harmony.select_nodes([instance.get("uuid")]) - - -def containerise(name, - namespace, - node, - context, - loader=None, - suffix=None, - nodes=None): - """Imprint node with metadata. - - Containerisation enables a tracking of version, author and origin - for loaded assets. - - Arguments: - name (str): Name of resulting assembly. - namespace (str): Namespace under which to host container. - node (str): Node to containerise. - context (dict): Asset information. - loader (str, optional): Name of loader used to produce this container. - suffix (str, optional): Suffix of container, defaults to `_CON`. - - Returns: - container (str): Path of container assembly. - """ - if not nodes: - nodes = [] - - data = { - "schema": "openpype:container-2.0", - "id": AVALON_CONTAINER_ID, - "name": name, - "namespace": namespace, - "loader": str(loader), - "representation": context["representation"]["id"], - "nodes": nodes - } - - harmony.imprint(node, data) - - return node diff --git a/server_addon/harmony/client/ayon_harmony/api/plugin.py b/server_addon/harmony/client/ayon_harmony/api/plugin.py deleted file mode 100644 index 6ec876af62..0000000000 --- a/server_addon/harmony/client/ayon_harmony/api/plugin.py +++ /dev/null @@ -1,70 +0,0 @@ -from ayon_core.pipeline import LegacyCreator -import ayon_harmony.api as harmony - - -class Creator(LegacyCreator): - """Creator plugin to create instances in Harmony. - - By default a Composite node is created to support any number of nodes in - an instance, but any node type is supported. - If the selection is used, the selected nodes will be connected to the - created node. - """ - - defaults = ["Main"] - node_type = "COMPOSITE" - - def setup_node(self, node): - """Prepare node as container. - - Args: - node (str): Path to node. - """ - harmony.send( - { - "function": "AvalonHarmony.setupNodeForCreator", - "args": node - } - ) - - def process(self): - """Plugin entry point.""" - existing_node_names = harmony.send( - { - "function": "AvalonHarmony.getNodesNamesByType", - "args": self.node_type - })["result"] - - # Dont allow instances with the same name. - msg = "Instance with name \"{}\" already exists.".format(self.name) - for name in existing_node_names: - if self.name.lower() == name.lower(): - harmony.send( - { - "function": "AvalonHarmony.message", "args": msg - } - ) - return False - - with harmony.maintained_selection() as selection: - node = None - - if (self.options or {}).get("useSelection") and selection: - node = harmony.send( - { - "function": "AvalonHarmony.createContainer", - "args": [self.name, self.node_type, selection[-1]] - } - )["result"] - else: - node = harmony.send( - { - "function": "AvalonHarmony.createContainer", - "args": [self.name, self.node_type] - } - )["result"] - - harmony.imprint(node, self.data) - self.setup_node(node) - - return node diff --git a/server_addon/harmony/client/ayon_harmony/api/server.py b/server_addon/harmony/client/ayon_harmony/api/server.py deleted file mode 100644 index 7e1e36c2ed..0000000000 --- a/server_addon/harmony/client/ayon_harmony/api/server.py +++ /dev/null @@ -1,280 +0,0 @@ -# -*- coding: utf-8 -*- -"""Server-side implementation of Toon Boon Harmony communication.""" -import socket -import logging -import json -import traceback -import importlib -import functools -import time -import struct -from datetime import datetime -import threading -from . import lib - - -class Server(threading.Thread): - """Class for communication with Toon Boon Harmony. - - Attributes: - connection (Socket): connection holding object. - received (str): received data buffer.any(iterable) - port (int): port number. - message_id (int): index of last message going out. - queue (dict): dictionary holding queue of incoming messages. - - """ - - def __init__(self, port): - """Constructor.""" - super(Server, self).__init__() - self.daemon = True - self.connection = None - self.received = "" - self.port = port - self.message_id = 1 - - # Setup logging. - self.log = logging.getLogger(__name__) - self.log.setLevel(logging.DEBUG) - - # Create a TCP/IP socket - self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - - # Bind the socket to the port - server_address = ("127.0.0.1", port) - self.log.debug( - f"[{self.timestamp()}] Starting up on " - f"{server_address[0]}:{server_address[1]}") - self.socket.bind(server_address) - - # Listen for incoming connections - self.socket.listen(1) - self.queue = {} - - def process_request(self, request): - """Process incoming request. - - Args: - request (dict): { - "module": (str), # Module of method. - "method" (str), # Name of method in module. - "args" (list), # Arguments to pass to method. - "kwargs" (dict), # Keyword arguments to pass to method. - "reply" (bool), # Optional wait for method completion. - } - """ - pretty = self._pretty(request) - self.log.debug( - f"[{self.timestamp()}] Processing request:\n{pretty}") - - # TODO javascript should not define which module is imported and - # which function is called. It should send predefined requests. - try: - module = importlib.import_module(request["module"]) - method = getattr(module, request["method"]) - - args = request.get("args", []) - kwargs = request.get("kwargs", {}) - partial_method = functools.partial(method, *args, **kwargs) - - lib.ProcessContext.execute_in_main_thread(partial_method) - except Exception: - self.log.error(traceback.format_exc()) - - def receive(self): - """Receives data from `self.connection`. - - When the data is a json serializable string, a reply is sent then - processing of the request. - """ - current_time = time.time() - while True: - self.log.info("wait ttt") - # Receive the data in small chunks and retransmit it - request = None - try: - header = self.connection.recv(10) - except OSError: - # could happen on MacOS - self.log.info("") - break - - if len(header) == 0: - # null data received, socket is closing. - self.log.info(f"[{self.timestamp()}] Connection closing.") - break - - if header[0:2] != b"AH": - self.log.error("INVALID HEADER") - content_length_str = header[2:].decode() - - length = int(content_length_str, 16) - data = self.connection.recv(length) - while (len(data) < length): - # we didn't received everything in first try, lets wait for - # all data. - self.log.info("loop") - time.sleep(0.1) - if self.connection is None: - self.log.error(f"[{self.timestamp()}] " - "Connection is broken") - break - if time.time() > current_time + 30: - self.log.error(f"[{self.timestamp()}] Connection timeout.") - break - - data += self.connection.recv(length - len(data)) - self.log.debug("data:: {} {}".format(data, type(data))) - self.received += data.decode("utf-8") - pretty = self._pretty(self.received) - self.log.debug( - f"[{self.timestamp()}] Received:\n{pretty}") - - try: - request = json.loads(self.received) - except json.decoder.JSONDecodeError as e: - self.log.error(f"[{self.timestamp()}] " - f"Invalid message received.\n{e}", - exc_info=True) - - self.received = "" - if request is None: - continue - - if "message_id" in request.keys(): - message_id = request["message_id"] - self.message_id = message_id + 1 - self.log.debug(f"--- storing request as {message_id}") - self.queue[message_id] = request - if "reply" not in request.keys(): - request["reply"] = True - self.send(request) - self.process_request(request) - - if "message_id" in request.keys(): - try: - self.log.debug(f"[{self.timestamp()}] " - f"Removing from the queue {message_id}") - del self.queue[message_id] - except IndexError: - self.log.debug(f"[{self.timestamp()}] " - f"{message_id} is no longer in queue") - else: - self.log.debug(f"[{self.timestamp()}] " - "received data was just a reply.") - - def run(self): - """Entry method for server. - - Waits for a connection on `self.port` before going into listen mode. - """ - # Wait for a connection - timestamp = datetime.now().strftime("%H:%M:%S.%f") - self.log.debug(f"[{timestamp}] Waiting for a connection.") - self.connection, client_address = self.socket.accept() - - timestamp = datetime.now().strftime("%H:%M:%S.%f") - self.log.debug(f"[{timestamp}] Connection from: {client_address}") - - self.receive() - - def stop(self): - """Shutdown socket server gracefully.""" - timestamp = datetime.now().strftime("%H:%M:%S.%f") - self.log.debug(f"[{timestamp}] Shutting down server.") - if self.connection is None: - self.log.debug("Connect to shutdown.") - socket.socket( - socket.AF_INET, socket.SOCK_STREAM - ).connect(("localhost", self.port)) - - self.connection.close() - self.connection = None - - self.socket.close() - - def _send(self, message): - """Send a message to Harmony. - - Args: - message (str): Data to send to Harmony. - """ - # Wait for a connection. - while not self.connection: - pass - - timestamp = datetime.now().strftime("%H:%M:%S.%f") - encoded = message.encode("utf-8") - coded_message = b"AH" + struct.pack('>I', len(encoded)) + encoded - pretty = self._pretty(coded_message) - self.log.debug( - f"[{timestamp}] Sending [{self.message_id}]:\n{pretty}") - self.log.debug(f"--- Message length: {len(encoded)}") - self.connection.sendall(coded_message) - self.message_id += 1 - - def send(self, request): - """Send a request in dictionary to Harmony. - - Waits for a reply from Harmony. - - Args: - request (dict): Data to send to Harmony. - """ - request["message_id"] = self.message_id - self._send(json.dumps(request)) - if request.get("reply"): - timestamp = datetime.now().strftime("%H:%M:%S.%f") - self.log.debug( - f"[{timestamp}] sent reply, not waiting for anything.") - return None - result = None - current_time = time.time() - try_index = 1 - while True: - time.sleep(0.1) - if time.time() > current_time + 30: - timestamp = datetime.now().strftime("%H:%M:%S.%f") - self.log.error((f"[{timestamp}][{self.message_id}] " - "No reply from Harmony in 30s. " - f"Retrying {try_index}")) - try_index += 1 - current_time = time.time() - if try_index > 30: - break - try: - result = self.queue[request["message_id"]] - timestamp = datetime.now().strftime("%H:%M:%S.%f") - self.log.debug((f"[{timestamp}] Got request " - f"id {self.message_id}, " - "removing from queue")) - del self.queue[request["message_id"]] - break - except KeyError: - # response not in received queue yey - pass - try: - result = json.loads(self.received) - break - except json.decoder.JSONDecodeError: - pass - - self.received = "" - - return result - - def _pretty(self, message) -> str: - # result = pformat(message, indent=2) - # return result.replace("\\n", "\n") - return "{}{}".format(4 * " ", message) - - def timestamp(self): - """Return current timestamp as a string. - - Returns: - str: current timestamp. - - """ - return datetime.now().strftime("%H:%M:%S.%f") diff --git a/server_addon/harmony/client/ayon_harmony/api/temp.zip b/server_addon/harmony/client/ayon_harmony/api/temp.zip deleted file mode 100644 index eab165afe4..0000000000 Binary files a/server_addon/harmony/client/ayon_harmony/api/temp.zip and /dev/null differ diff --git a/server_addon/harmony/client/ayon_harmony/api/workio.py b/server_addon/harmony/client/ayon_harmony/api/workio.py deleted file mode 100644 index 1f95148e75..0000000000 --- a/server_addon/harmony/client/ayon_harmony/api/workio.py +++ /dev/null @@ -1,77 +0,0 @@ -"""Host API required Work Files tool""" -import os -import shutil - -from .lib import ( - ProcessContext, - get_local_harmony_path, - zip_and_move, - launch_zip_file -) - -# used to lock saving until previous save is done. -save_disabled = False - - -def file_extensions(): - return [".zip"] - - -def has_unsaved_changes(): - if ProcessContext.server: - return ProcessContext.server.send( - {"function": "scene.isDirty"})["result"] - - return False - - -def save_file(filepath): - global save_disabled - if save_disabled: - return ProcessContext.server.send( - { - "function": "show_message", - "args": "Saving in progress, please wait until it finishes." - })["result"] - - save_disabled = True - temp_path = get_local_harmony_path(filepath) - - if ProcessContext.server: - if os.path.exists(temp_path): - try: - shutil.rmtree(temp_path) - except Exception as e: - raise Exception(f"cannot delete {temp_path}") from e - - ProcessContext.server.send( - {"function": "scene.saveAs", "args": [temp_path]} - )["result"] - - zip_and_move(temp_path, filepath) - - ProcessContext.workfile_path = filepath - - scene_path = os.path.join( - temp_path, os.path.basename(temp_path) + ".xstage" - ) - ProcessContext.server.send( - {"function": "AvalonHarmony.addPathToWatcher", "args": scene_path} - ) - else: - os.environ["HARMONY_NEW_WORKFILE_PATH"] = filepath.replace("\\", "/") - - save_disabled = False - - -def open_file(filepath): - launch_zip_file(filepath) - - -def current_file(): - """Returning None to make Workfiles app look at first file extension.""" - return None - - -def work_root(session): - return os.path.normpath(session["AYON_WORKDIR"]).replace("\\", "/") diff --git a/server_addon/harmony/client/ayon_harmony/hooks/pre_launch_args.py b/server_addon/harmony/client/ayon_harmony/hooks/pre_launch_args.py deleted file mode 100644 index 2fdb5ae620..0000000000 --- a/server_addon/harmony/client/ayon_harmony/hooks/pre_launch_args.py +++ /dev/null @@ -1,88 +0,0 @@ -import os -import platform -import subprocess - -from ayon_core.lib import ( - get_ayon_launcher_args, - is_using_ayon_console, -) -from ayon_applications import PreLaunchHook, LaunchTypes -from ayon_harmony import get_launch_script_path - - -def get_launch_kwargs(kwargs): - """Explicit setting of kwargs for Popen for Harmony. - - Expected behavior - - ayon_console opens window with logs - - ayon has stdout/stderr available for capturing - - Args: - kwargs (Union[dict, None]): Current kwargs or None. - - """ - if kwargs is None: - kwargs = {} - - if platform.system().lower() != "windows": - return kwargs - - if is_using_ayon_console(): - kwargs.update({ - "creationflags": subprocess.CREATE_NEW_CONSOLE - }) - else: - kwargs.update({ - "creationflags": subprocess.CREATE_NO_WINDOW, - "stdout": subprocess.DEVNULL, - "stderr": subprocess.DEVNULL - }) - return kwargs - - -class HarmonyPrelaunchHook(PreLaunchHook): - """Launch arguments preparation. - - Hook add python executable and script path to Harmony implementation - before Harmony executable and add last workfile path to launch arguments. - - Existence of last workfile is checked. If workfile does not exists tries - to copy templated workfile from predefined path. - """ - app_groups = {"harmony"} - - order = 20 - launch_types = {LaunchTypes.local} - - def execute(self): - # Pop executable - executable_path = self.launch_context.launch_args.pop(0) - - # Pop rest of launch arguments - There should not be other arguments! - remainders = [] - while self.launch_context.launch_args: - remainders.append(self.launch_context.launch_args.pop(0)) - - script_path = get_launch_script_path() - - new_launch_args = get_ayon_launcher_args( - "run", script_path, executable_path - ) - # Add workfile path if exists - workfile_path = self.data["last_workfile_path"] - if ( - self.data.get("start_last_workfile") - and workfile_path - and os.path.exists(workfile_path) - ): - new_launch_args.append(workfile_path) - - # Append as whole list as these arguments should not be separated - self.launch_context.launch_args.append(new_launch_args) - - if remainders: - self.launch_context.launch_args.extend(remainders) - - self.launch_context.kwargs = get_launch_kwargs( - self.launch_context.kwargs - ) diff --git a/server_addon/harmony/client/ayon_harmony/js/.eslintrc.json b/server_addon/harmony/client/ayon_harmony/js/.eslintrc.json deleted file mode 100644 index 16e7a6c95e..0000000000 --- a/server_addon/harmony/client/ayon_harmony/js/.eslintrc.json +++ /dev/null @@ -1,117 +0,0 @@ -{ - "env": { - "browser": true - }, - "extends": "eslint:recommended", - "parserOptions": { - "ecmaVersion": 3 - }, - "rules": { - "indent": [ - "error", - 4 - ], - "linebreak-style": [ - "error", - "unix" - ], - "quotes": [ - "error", - "single" - ], - "semi": [ - "error", - "always" - ] - }, - "globals": { - "$": "readonly", - "Action": "readonly", - "Backdrop": "readonly", - "Button": "readonly", - "Cel": "readonly", - "Cel3d": "readonly", - "CheckBox": "readonly", - "ColorRGBA": "readonly", - "ComboBox": "readonly", - "DateEdit": "readonly", - "DateEditEnum": "readonly", - "Dialog": "readonly", - "Dir": "readonly", - "DirSpec": "readonly", - "Drawing": "readonly", - "DrawingToolParams": "readonly", - "DrawingTools": "readonly", - "EnvelopeCreator": "readonly", - "ExportVideoDlg": "readonly", - "File": "readonly", - "FileAccess": "readonly", - "FileDialog": "readonly", - "GroupBox": "readonly", - "ImportDrawingDlg": "readonly", - "Input": "readonly", - "KeyModifiers": "readonly", - "Label": "readonly", - "LayoutExports": "readonly", - "LayoutExportsParams": "readonly", - "LineEdit": "readonly", - "Matrix4x4": "readonly", - "MessageBox": "readonly", - "MessageLog": "readonly", - "Model3d": "readonly", - "MovieImport": "readonly", - "NumberEdit": "readonly", - "PaletteManager": "readonly", - "PaletteObjectManager": "readonly", - "PermanentFile": "readonly", - "Point2d": "readonly", - "Point3d": "readonly", - "Process": "readonly", - "Process2": "readonly", - "Quaternion": "readonly", - "QuicktimeExporter": "readonly", - "RadioButton": "readonly", - "RemoteCmd": "readonly", - "Scene": "readonly", - "Settings": "readonly", - "Slider": "readonly", - "SpinBox": "readonly", - "SubnodeData": "readonly", - "System": "readonly", - "TemporaryFile": "readonly", - "TextEdit": "readonly", - "TimeEdit": "readonly", - "Timeline": "readonly", - "ToolProperties": "readonly", - "UiLoader": "readonly", - "Vector2d": "readonly", - "Vector3d": "readonly", - "WebCCExporter": "readonly", - "Workspaces": "readonly", - "__scriptManager__": "readonly", - "__temporaryFileContext__": "readonly", - "about": "readonly", - "column": "readonly", - "compositionOrder": "readonly", - "copyPaste": "readonly", - "deformation": "readonly", - "drawingExport": "readonly", - "element": "readonly", - "exporter": "readonly", - "fileMapper": "readonly", - "frame": "readonly", - "func": "readonly", - "library": "readonly", - "node": "readonly", - "preferences": "readonly", - "render": "readonly", - "scene": "readonly", - "selection": "readonly", - "sound": "readonly", - "specialFolders": "readonly", - "translator": "readonly", - "view": "readonly", - "waypoint": "readonly", - "xsheet": "readonly" - } -} diff --git a/server_addon/harmony/client/ayon_harmony/js/PypeHarmony.js b/server_addon/harmony/client/ayon_harmony/js/PypeHarmony.js deleted file mode 100644 index cf6a5e3763..0000000000 --- a/server_addon/harmony/client/ayon_harmony/js/PypeHarmony.js +++ /dev/null @@ -1,217 +0,0 @@ -/* global include */ -// *************************************************************************** -// * Pype Harmony Host * -// *************************************************************************** - -var LD_OPENHARMONY_PATH = System.getenv('LIB_OPENHARMONY_PATH'); -LD_OPENHARMONY_PATH = LD_OPENHARMONY_PATH + '/openHarmony.js'; -LD_OPENHARMONY_PATH = LD_OPENHARMONY_PATH.replace(/\\/g, "/"); - - - -/** - * @namespace - * @classdesc PypeHarmony encapsulate all Pype related functions. - * @property {Object} loaders Namespace for Loaders JS code. - * @property {Object} Creators Namespace for Creators JS code. - * @property {Object} Publish Namespace for Publish plugins JS code. - */ -var PypeHarmony = { - Loaders: {}, - Creators: {}, - Publish: {} -}; - - -/** - * Show message in Harmony. - * @function - * @param {string} message Argument containing message. - */ -PypeHarmony.message = function(message) { - MessageBox.information(message); -}; - - -/** - * Set scene setting based on folder settngs. - * @function - * @param {obj} settings Scene settings. - */ -PypeHarmony.setSceneSettings = function(settings) { - if (settings.fps) { - scene.setFrameRate(settings.fps); - } - - if (settings.frameStart && settings.frameEnd) { - var duration = settings.frameEnd - settings.frameStart + 1; - - if (frame.numberOf() > duration) { - frame.remove(duration, frame.numberOf() - duration); - } - - if (frame.numberOf() < duration) { - frame.insert(duration, duration - frame.numberOf()); - } - - scene.setStartFrame(1); - scene.setStopFrame(duration); - } - if (settings.resolutionWidth && settings.resolutionHeight) { - scene.setDefaultResolution( - settings.resolutionWidth, settings.resolutionHeight, 41.112 - ); - } -}; - - -/** - * Get scene settings. - * @function - * @return {array} Scene settings. - */ -PypeHarmony.getSceneSettings = function() { - return [ - about.getApplicationPath(), - scene.currentProjectPath(), - scene.currentScene(), - scene.getFrameRate(), - scene.getStartFrame(), - scene.getStopFrame(), - sound.getSoundtrackAll().path(), - scene.defaultResolutionX(), - scene.defaultResolutionY(), - scene.defaultResolutionFOV() - ]; -}; - - -/** - * Set color of nodes. - * @function - * @param {array} nodes List of nodes. - * @param {array} rgba array of RGBA components of color. - */ -PypeHarmony.setColor = function(nodes, rgba) { - for (var i =0; i <= nodes.length - 1; ++i) { - var color = PypeHarmony.color(rgba); - node.setColor(nodes[i], color); - } -}; - - -/** - * Extract Template into file. - * @function - * @param {array} args Arguments for template extraction. - * - * @example - * // arguments are in this order: - * var args = [backdrops, nodes, templateFilename, templateDir]; - * - */ -PypeHarmony.exportTemplate = function(args) { - var tempNode = node.add('Top', 'temp_note', 'NOTE', 0, 0, 0); - var templateGroup = node.createGroup(tempNode, 'temp_group'); - node.deleteNode( templateGroup + '/temp_note' ); - - selection.clearSelection(); - for (var f = 0; f < args[1].length; f++) { - selection.addNodeToSelection(args[1][f]); - } - - Action.perform('copy()', 'Node View'); - - selection.clearSelection(); - selection.addNodeToSelection(templateGroup); - Action.perform('onActionEnterGroup()', 'Node View'); - Action.perform('paste()', 'Node View'); - - // Recreate backdrops in group. - for (var i = 0; i < args[0].length; i++) { - MessageLog.trace(args[0][i]); - Backdrop.addBackdrop(templateGroup, args[0][i]); - } - - Action.perform('selectAll()', 'Node View' ); - copyPaste.createTemplateFromSelection(args[2], args[3]); - - // Unfocus the group in Node view, delete all nodes and backdrops - // created during the process. - Action.perform('onActionUpToParent()', 'Node View'); - node.deleteNode(templateGroup, true, true); -}; - - -/** - * Toggle instance in Harmony. - * @function - * @param {array} args Instance name and value. - */ -PypeHarmony.toggleInstance = function(args) { - node.setEnable(args[0], args[1]); -}; - - -/** - * Delete node in Harmony. - * @function - * @param {string} _node Node name. - */ -PypeHarmony.deleteNode = function(_node) { - node.deleteNode(_node, true, true); -}; - - -/** - * Copy file. - * @function - * @param {string} src Source file name. - * @param {string} dst Destination file name. - */ -PypeHarmony.copyFile = function(src, dst) { - var srcFile = new PermanentFile(src); - var dstFile = new PermanentFile(dst); - srcFile.copy(dstFile); -}; - - -/** - * create RGBA color from array. - * @function - * @param {array} rgba array of rgba values. - * @return {ColorRGBA} ColorRGBA Harmony class. - */ -PypeHarmony.color = function(rgba) { - return new ColorRGBA(rgba[0], rgba[1], rgba[2], rgba[3]); -}; - - -/** - * get all dependencies for given node. - * @function - * @param {string} _node node path. - * @return {array} List of dependent nodes. - */ -PypeHarmony.getDependencies = function(_node) { - var target_node = _node; - var numInput = node.numberOfInputPorts(target_node); - var dependencies = []; - for (var i = 0 ; i < numInput; i++) { - dependencies.push(node.srcNode(target_node, i)); - } - return dependencies; -}; - - -/** - * return version of running Harmony instance. - * @function - * @return {array} [major_version, minor_version] - */ -PypeHarmony.getVersion = function() { - return [ - about.getMajorVersion(), - about.getMinorVersion() - ]; -}; diff --git a/server_addon/harmony/client/ayon_harmony/js/README.md b/server_addon/harmony/client/ayon_harmony/js/README.md deleted file mode 100644 index 1265a38305..0000000000 --- a/server_addon/harmony/client/ayon_harmony/js/README.md +++ /dev/null @@ -1,15 +0,0 @@ -## Pype - ToonBoom Harmony integration - -### Development - -#### Setting up ESLint as linter for javascript code - -You nee [node.js](https://nodejs.org/en/) installed. All you need to do then -is to run: - -```sh -npm install -``` -in **js** directory. This will install eslint and all requirements locally. - -In [Atom](https://atom.io/) it is enough to install [linter-eslint](https://atom.io/packages/lintecr-eslint) and set global *npm* prefix in its settings. diff --git a/server_addon/harmony/client/ayon_harmony/js/creators/CreateRender.js b/server_addon/harmony/client/ayon_harmony/js/creators/CreateRender.js deleted file mode 100644 index 1a2b606eb9..0000000000 --- a/server_addon/harmony/client/ayon_harmony/js/creators/CreateRender.js +++ /dev/null @@ -1,33 +0,0 @@ -/* global PypeHarmony:writable, include */ -// *************************************************************************** -// * CreateRender * -// *************************************************************************** - - -// check if PypeHarmony is defined and if not, load it. -if (typeof PypeHarmony === 'undefined') { - var AYON_HARMONY_JS = System.getenv('AYON_HARMONY_JS') + '/PypeHarmony.js'; - include(AYON_HARMONY_JS.replace(/\\/g, "/")); -} - - -/** - * @namespace - * @classdesc Code creating render containers in Harmony. - */ -var CreateRender = function() {}; - - -/** - * Create render instance. - * @function - * @param {array} args Arguments for instance. - */ -CreateRender.prototype.create = function(args) { - node.setTextAttr(args[0], 'DRAWING_TYPE', 1, 'PNG4'); - node.setTextAttr(args[0], 'DRAWING_NAME', 1, args[1]); - node.setTextAttr(args[0], 'MOVIE_PATH', 1, args[1]); -}; - -// add self to Pype Loaders -PypeHarmony.Creators.CreateRender = new CreateRender(); diff --git a/server_addon/harmony/client/ayon_harmony/js/loaders/ImageSequenceLoader.js b/server_addon/harmony/client/ayon_harmony/js/loaders/ImageSequenceLoader.js deleted file mode 100644 index a2ca5f9a99..0000000000 --- a/server_addon/harmony/client/ayon_harmony/js/loaders/ImageSequenceLoader.js +++ /dev/null @@ -1,308 +0,0 @@ -/* global PypeHarmony:writable, include */ -// *************************************************************************** -// * ImageSequenceLoader * -// *************************************************************************** - -// check if PypeHarmony is defined and if not, load it. -if (typeof PypeHarmony === 'undefined') { - var AYON_HARMONY_JS = System.getenv('AYON_HARMONY_JS') + '/PypeHarmony.js'; - include(AYON_HARMONY_JS.replace(/\\/g, "/")); -} - -if (typeof $ === 'undefined'){ - $ = this.__proto__['$']; -} - -/** - * @namespace - * @classdesc Image Sequence loader JS code. - */ -var ImageSequenceLoader = function() { - this.PNGTransparencyMode = 0; // Premultiplied with Black - this.TGATransparencyMode = 0; // Premultiplied with Black - this.SGITransparencyMode = 0; // Premultiplied with Black - this.LayeredPSDTransparencyMode = 1; // Straight - this.FlatPSDTransparencyMode = 2; // Premultiplied with White -}; - - -ImageSequenceLoader.getCurrentGroup = function () { - var doc = $.scn; - var nodeView = ''; - for (var i = 0; i < 200; i++) { - nodeView = 'View' + (i); - if (view.type(nodeView) == 'Node View') { - break; - } - } - - if (!nodeView) { - $.alert('You must have a Node View open!', - 'No Node View is currently open!\n' + - 'Open a Node View and Try Again.', - 'OK!'); - return; - } - - var currentGroup; - if (!nodeView) { - currentGroup = doc.root; - } else { - currentGroup = doc.$node(view.group(nodeView)); - } - - return currentGroup.path; -}; - - -/** - * Get unique column name. - * @function - * @param {string} columnPrefix Column name. - * @return {string} Unique column name. - */ -ImageSequenceLoader.getUniqueColumnName = function(columnPrefix) { - var suffix = 0; - // finds if unique name for a column - var columnName = columnPrefix; - while (suffix < 2000) { - if (!column.type(columnName)) { - break; - } - - suffix = suffix + 1; - columnName = columnPrefix + '_' + suffix; - } - return columnName; -}; - - -/** - * Import file sequences into Harmony. - * @function - * @param {object} args Arguments for import, see Example. - * @return {string} Read node name - * - * @example - * // Arguments are in following order: - * var args = [ - * files, // Files in file sequences. - * folderName, // Folder name. - * productName, // Product name. - * startFrame, // Sequence starting frame. - * groupId // Unique group ID (uuid4). - * ]; - */ -ImageSequenceLoader.prototype.importFiles = function(args) { - MessageLog.trace("ImageSequence:: " + typeof PypeHarmony); - MessageLog.trace("ImageSequence $:: " + typeof $); - MessageLog.trace("ImageSequence OH:: " + typeof PypeHarmony.OpenHarmony); - var PNGTransparencyMode = 0; // Premultiplied with Black - var TGATransparencyMode = 0; // Premultiplied with Black - var SGITransparencyMode = 0; // Premultiplied with Black - var LayeredPSDTransparencyMode = 1; // Straight - var FlatPSDTransparencyMode = 2; // Premultiplied with White - - var doc = $.scn; - var files = args[0]; - var folderName = args[1]; - var productName = args[2]; - var startFrame = args[3]; - var groupId = args[4]; - var vectorFormat = null; - var extension = null; - var filename = files[0]; - var pos = filename.lastIndexOf('.'); - if (pos < 0) { - return null; - } - - // Get the current group - var currentGroup = doc.$node(ImageSequenceLoader.getCurrentGroup()); - - // Get a unique iterative name for the container read node - var num = 0; - var name = ''; - do { - name = folderName + '_' + (num++) + '_' + productName; - } while (currentGroup.getNodeByName(name) != null); - - extension = filename.substr(pos+1).toLowerCase(); - if (extension == 'jpeg') { - extension = 'jpg'; - } - - if (extension == 'tvg') { - vectorFormat = 'TVG'; - extension ='SCAN'; // element.add() will use this. - } - - var elemId = element.add( - name, - 'BW', - scene.numberOfUnitsZ(), - extension.toUpperCase(), - vectorFormat - ); - - if (elemId == -1) { - // hum, unknown file type most likely -- let's skip it. - return null; // no read to add. - } - - var uniqueColumnName = ImageSequenceLoader.getUniqueColumnName(name); - column.add(uniqueColumnName, 'DRAWING'); - column.setElementIdOfDrawing(uniqueColumnName, elemId); - var read = node.add(currentGroup, name, 'READ', 0, 0, 0); - var transparencyAttr = node.getAttr( - read, frame.current(), 'READ_TRANSPARENCY' - ); - var opacityAttr = node.getAttr(read, frame.current(), 'OPACITY'); - transparencyAttr.setValue(true); - opacityAttr.setValue(true); - var alignmentAttr = node.getAttr(read, frame.current(), 'ALIGNMENT_RULE'); - alignmentAttr.setValue('ASIS'); - var transparencyModeAttr = node.getAttr( - read, frame.current(), 'applyMatteToColor' - ); - if (extension === 'png') { - transparencyModeAttr.setValue(PNGTransparencyMode); - } - if (extension === 'tga') { - transparencyModeAttr.setValue(TGATransparencyMode); - } - if (extension === 'sgi') { - transparencyModeAttr.setValue(SGITransparencyMode); - } - if (extension === 'psd') { - transparencyModeAttr.setValue(FlatPSDTransparencyMode); - } - if (extension === 'jpg') { - transparencyModeAttr.setValue(LayeredPSDTransparencyMode); - } - - var drawingFilePath; - var timing; - node.linkAttr(read, 'DRAWING.ELEMENT', uniqueColumnName); - if (files.length === 1) { - // Create a drawing drawing, 'true' indicate that the file exists. - Drawing.create(elemId, 1, true); - // Get the actual path, in tmp folder. - drawingFilePath = Drawing.filename(elemId, '1'); - PypeHarmony.copyFile(files[0], drawingFilePath); - // Expose the image for the entire frame range. - for (var i =0; i <= frame.numberOf() - 1; ++i) { - timing = startFrame + i; - column.setEntry(uniqueColumnName, 1, timing, '1'); - } - } else { - // Create a drawing for each file. - for (var j =0; j <= files.length - 1; ++j) { - timing = startFrame + j; - // Create a drawing drawing, 'true' indicate that the file exists. - Drawing.create(elemId, timing, true); - // Get the actual path, in tmp folder. - drawingFilePath = Drawing.filename(elemId, timing.toString()); - PypeHarmony.copyFile(files[j], drawingFilePath); - column.setEntry(uniqueColumnName, 1, timing, timing.toString()); - } - } - var greenColor = new ColorRGBA(0, 255, 0, 255); - node.setColor(read, greenColor); - - // Add uuid to attribute of the container read node - node.createDynamicAttr(read, 'STRING', 'uuid', 'uuid', false); - node.setTextAttr(read, 'uuid', 1.0, groupId); - return read; -}; - - -/** - * Replace files sequences in Harmony. - * @function - * @param {object} args Arguments for import, see Example. - * @return {string} Read node name - * - * @example - * // Arguments are in following order: - * var args = [ - * files, // Files in file sequences - * name, // Node name - * startFrame // Sequence starting frame - * ]; - */ -ImageSequenceLoader.prototype.replaceFiles = function(args) { - var files = args[0]; - MessageLog.trace(files); - MessageLog.trace(files.length); - var _node = args[1]; - var startFrame = args[2]; - var _column = node.linkedColumn(_node, 'DRAWING.ELEMENT'); - var elemId = column.getElementIdOfDrawing(_column); - // Delete existing drawings. - var timings = column.getDrawingTimings(_column); - for ( var i =0; i <= timings.length - 1; ++i) { - column.deleteDrawingAt(_column, parseInt(timings[i])); - } - var filename = files[0]; - var pos = filename.lastIndexOf('.'); - if (pos < 0) { - return null; - } - var extension = filename.substr(pos+1).toLowerCase(); - if (extension === 'jpeg') { - extension = 'jpg'; - } - - var transparencyModeAttr = node.getAttr( - _node, frame.current(), 'applyMatteToColor' - ); - if (extension === 'png') { - transparencyModeAttr.setValue(this.PNGTransparencyMode); - } - if (extension === 'tga') { - transparencyModeAttr.setValue(this.TGATransparencyMode); - } - if (extension === 'sgi') { - transparencyModeAttr.setValue(this.SGITransparencyMode); - } - if (extension == 'psd') { - transparencyModeAttr.setValue(this.FlatPSDTransparencyMode); - } - if (extension === 'jpg') { - transparencyModeAttr.setValue(this.LayeredPSDTransparencyMode); - } - - var drawingFilePath; - var timing; - if (files.length == 1) { - // Create a drawing drawing, 'true' indicate that the file exists. - Drawing.create(elemId, 1, true); - // Get the actual path, in tmp folder. - drawingFilePath = Drawing.filename(elemId, '1'); - PypeHarmony.copyFile(files[0], drawingFilePath); - MessageLog.trace(files[0]); - MessageLog.trace(drawingFilePath); - // Expose the image for the entire frame range. - for (var k =0; k <= frame.numberOf() - 1; ++k) { - timing = startFrame + k; - column.setEntry(_column, 1, timing, '1'); - } - } else { - // Create a drawing for each file. - for (var l =0; l <= files.length - 1; ++l) { - timing = startFrame + l; - // Create a drawing drawing, 'true' indicate that the file exists. - Drawing.create(elemId, timing, true); - // Get the actual path, in tmp folder. - drawingFilePath = Drawing.filename(elemId, timing.toString()); - PypeHarmony.copyFile( files[l], drawingFilePath ); - column.setEntry(_column, 1, timing, timing.toString()); - } - } - var greenColor = new ColorRGBA(0, 255, 0, 255); - node.setColor(_node, greenColor); -}; - -// add self to Pype Loaders -PypeHarmony.Loaders.ImageSequenceLoader = new ImageSequenceLoader(); diff --git a/server_addon/harmony/client/ayon_harmony/js/loaders/TemplateLoader.js b/server_addon/harmony/client/ayon_harmony/js/loaders/TemplateLoader.js deleted file mode 100644 index c29e12c43b..0000000000 --- a/server_addon/harmony/client/ayon_harmony/js/loaders/TemplateLoader.js +++ /dev/null @@ -1,179 +0,0 @@ -/* global PypeHarmony:writable, include */ -// *************************************************************************** -// * TemplateLoader * -// *************************************************************************** - - -// check if PypeHarmony is defined and if not, load it. -if (typeof PypeHarmony === 'undefined') { - var AYON_HARMONY_JS = System.getenv('AYON_HARMONY_JS') + '/PypeHarmony.js'; - include(AYON_HARMONY_JS.replace(/\\/g, "/")); -} - -if (typeof $ === 'undefined'){ - $ = this.__proto__['$']; -} -/** - * @namespace - * @classdesc Image Sequence loader JS code. - */ -var TemplateLoader = function() {}; - - -/** - * Load template as container. - * @function - * @param {array} args Arguments, see example. - * @return {string} Name of container. - * - * @example - * // arguments are in following order: - * var args = [ - * templatePath, // Path to tpl file. - * folderName, // Folder name. - * productName, // Product name. - * groupId // unique ID (uuid4) - * ]; - */ -TemplateLoader.prototype.loadContainer = function(args) { - var doc = $.scn; - var templatePath = args[0]; - var folderName = args[1]; - var productName = args[2]; - var groupId = args[3]; - - // Get the current group - var nodeViewWidget = $.app.getWidgetByName('Node View'); - if (!nodeViewWidget) { - $.alert('You must have a Node View open!', 'No Node View!', 'OK!'); - return; - } - - nodeViewWidget.setFocus(); - var currentGroup; - var nodeView = view.currentView(); - if (!nodeView) { - currentGroup = doc.root; - } else { - currentGroup = doc.$node(view.group(nodeView)); - } - - // Get a unique iterative name for the container group - var num = 0; - var containerGroupName = ''; - do { - containerGroupName = folderName + '_' + (num++) + '_' + productName; - } while (currentGroup.getNodeByName(containerGroupName) != null); - - // import the template - var tplNodes = currentGroup.importTemplate(templatePath); - MessageLog.trace(tplNodes); - // Create the container group - var groupNode = currentGroup.addGroup( - containerGroupName, false, false, tplNodes); - - // Add uuid to attribute of the container group - node.createDynamicAttr(groupNode, 'STRING', 'uuid', 'uuid', false); - node.setTextAttr(groupNode, 'uuid', 1.0, groupId); - - return String(groupNode); -}; - - -/** - * Replace existing node container. - * @function - * @param {string} dstNodePath Harmony path to destination Node. - * @param {string} srcNodePath Harmony path to source Node. - * @param {string} renameSrc ... - * @param {boolean} cloneSrc ... - * @return {boolean} Success - * @todo This is work in progress. - */ -TemplateLoader.prototype.replaceNode = function( - dstNodePath, srcNodePath, renameSrc, cloneSrc) { - var doc = $.scn; - var srcNode = doc.$node(srcNodePath); - var dstNode = doc.$node(dstNodePath); - // var dstNodeName = dstNode.name; - var replacementNode = srcNode; - // var dstGroup = dstNode.group; - $.beginUndo(); - if (cloneSrc) { - replacementNode = doc.$node( - $.nodeTools.copy_paste_node( - srcNodePath, dstNode.name + '_CLONE', dstNode.group.path)); - } else { - if (replacementNode.group.path != srcNode.group.path) { - replacementNode.moveToGroup(dstNode); - } - } - var inLinks = dstNode.getInLinks(); - var link, inNode, inPort, outPort, outNode, success; - for (var l in inLinks) { - if (Object.prototype.hasOwnProperty.call(inLinks, l)) { - link = inLinks[l]; - inPort = Number(link.inPort); - outPort = Number(link.outPort); - outNode = link.outNode; - success = replacementNode.linkInNode(outNode, inPort, outPort); - if (success) { - $.log('Successfully connected ' + outNode + ' : ' + - outPort + ' -> ' + replacementNode + ' : ' + inPort); - } else { - $.alert('Failed to connect ' + outNode + ' : ' + - outPort + ' -> ' + replacementNode + ' : ' + inPort); - } - } - } - - var outLinks = dstNode.getOutLinks(); - for (l in outLinks) { - if (Object.prototype.hasOwnProperty.call(outLinks, l)) { - link = outLinks[l]; - inPort = Number(link.inPort); - outPort = Number(link.outPort); - inNode = link.inNode; - // first we must disconnect the port from the node being - // replaced to this links inNode port - inNode.unlinkInPort(inPort); - success = replacementNode.linkOutNode(inNode, outPort, inPort); - if (success) { - $.log('Successfully connected ' + inNode + ' : ' + - inPort + ' <- ' + replacementNode + ' : ' + outPort); - } else { - if (inNode.type == 'MultiLayerWrite') { - $.log('Attempting standard api to connect the nodes...'); - success = node.link( - replacementNode, outPort, inNode, - inPort, node.numberOfInputPorts(inNode) + 1); - if (success) { - $.log('Successfully connected ' + inNode + ' : ' + - inPort + ' <- ' + replacementNode + ' : ' + outPort); - } - } - } - if (!success) { - $.alert('Failed to connect ' + inNode + ' : ' + - inPort + ' <- ' + replacementNode + ' : ' + outPort); - return false; - } - } - } -}; - - -TemplateLoader.prototype.askForColumnsUpdate = function() { - // Ask user if they want to also update columns and - // linked attributes here - return ($.confirm( - 'Would you like to update in place and reconnect all \n' + - 'ins/outs, attributes, and columns?', - 'Update & Replace?\n' + - 'If you choose No, the version will only be loaded.', - 'Yes', - 'No')); -}; - -// add self to Pype Loaders -PypeHarmony.Loaders.TemplateLoader = new TemplateLoader(); diff --git a/server_addon/harmony/client/ayon_harmony/js/package.json b/server_addon/harmony/client/ayon_harmony/js/package.json deleted file mode 100644 index 4415b14393..0000000000 --- a/server_addon/harmony/client/ayon_harmony/js/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "pype-harmony", - "version": "1.0.0", - "description": "Avalon Harmony Host integration", - "keywords": [ - "Pype", - "Avalon", - "Harmony", - "pipeline" - ], - "license": "MIT", - "main": "PypeHarmony.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "devDependencies": { - "eslint": "^7.11.0" - } -} diff --git a/server_addon/harmony/client/ayon_harmony/js/publish/CollectCurrentFile.js b/server_addon/harmony/client/ayon_harmony/js/publish/CollectCurrentFile.js deleted file mode 100644 index b9863d4b29..0000000000 --- a/server_addon/harmony/client/ayon_harmony/js/publish/CollectCurrentFile.js +++ /dev/null @@ -1,28 +0,0 @@ -/* global PypeHarmony:writable, include */ -// *************************************************************************** -// * CollectCurrentFile * -// *************************************************************************** - - -// check if PypeHarmony is defined and if not, load it. -if (typeof PypeHarmony === 'undefined') { - var AYON_HARMONY_JS = System.getenv('AYON_HARMONY_JS') + '/PypeHarmony.js'; - include(AYON_HARMONY_JS.replace(/\\/g, "/")); -} - - -/** - * @namespace - * @classdesc Collect Current file - */ -var CollectCurrentFile = function() {}; - -CollectCurrentFile.prototype.collect = function() { - return ( - scene.currentProjectPath() + '/' + - scene.currentVersionName() + '.xstage' - ); -}; - -// add self to Pype Loaders -PypeHarmony.Publish.CollectCurrentFile = new CollectCurrentFile(); diff --git a/server_addon/harmony/client/ayon_harmony/js/publish/CollectFarmRender.js b/server_addon/harmony/client/ayon_harmony/js/publish/CollectFarmRender.js deleted file mode 100644 index 3d9f69ebde..0000000000 --- a/server_addon/harmony/client/ayon_harmony/js/publish/CollectFarmRender.js +++ /dev/null @@ -1,53 +0,0 @@ -/* global PypeHarmony:writable, include */ -// *************************************************************************** -// * CollectFarmRender * -// *************************************************************************** - - -// check if PypeHarmony is defined and if not, load it. -if (typeof PypeHarmony === 'undefined') { - var AYON_HARMONY_JS = System.getenv('AYON_HARMONY_JS') + '/PypeHarmony.js'; - include(AYON_HARMONY_JS.replace(/\\/g, "/")); -} - - -/** - * @namespace - * @classdesc Image Sequence loader JS code. - */ -var CollectFarmRender = function() {}; - - -/** - * Get information important for render output. - * @function - * @param node {String} node name. - * @return {array} array of render info. - * - * @example - * - * var ret = [ - * file_prefix, // like foo/bar- - * type, // PNG4, ... - * leading_zeros, // 3 - for 0001 - * start // start frame - * ] - */ -CollectFarmRender.prototype.getRenderNodeSettings = function(n) { - // this will return - var output = [ - node.getTextAttr( - n, frame.current(), 'DRAWING_NAME'), - node.getTextAttr( - n, frame.current(), 'DRAWING_TYPE'), - node.getTextAttr( - n, frame.current(), 'LEADING_ZEROS'), - node.getTextAttr(n, frame.current(), 'START'), - node.getEnable(n) - ]; - - return output; -}; - -// add self to Pype Loaders -PypeHarmony.Publish.CollectFarmRender = new CollectFarmRender(); diff --git a/server_addon/harmony/client/ayon_harmony/js/publish/CollectPalettes.js b/server_addon/harmony/client/ayon_harmony/js/publish/CollectPalettes.js deleted file mode 100644 index 0b119c3118..0000000000 --- a/server_addon/harmony/client/ayon_harmony/js/publish/CollectPalettes.js +++ /dev/null @@ -1,33 +0,0 @@ -/* global PypeHarmony:writable, include */ -// *************************************************************************** -// * CollectPalettes * -// *************************************************************************** - - -// check if PypeHarmony is defined and if not, load it. -if (typeof PypeHarmony === 'undefined') { - var AYON_HARMONY_JS = System.getenv('AYON_HARMONY_JS') + '/PypeHarmony.js'; - include(AYON_HARMONY_JS.replace(/\\/g, "/")); -} - - -/** - * @namespace - * @classdesc Image Sequence loader JS code. - */ -var CollectPalettes = function() {}; - -CollectPalettes.prototype.getPalettes = function() { - var palette_list = PaletteObjectManager.getScenePaletteList(); - - var palettes = {}; - for(var i=0; i < palette_list.numPalettes; ++i) { - var palette = palette_list.getPaletteByIndex(i); - palettes[palette.getName()] = palette.id; - } - - return palettes; -}; - -// add self to Pype Loaders -PypeHarmony.Publish.CollectPalettes = new CollectPalettes(); diff --git a/server_addon/harmony/client/ayon_harmony/js/publish/ExtractPalette.js b/server_addon/harmony/client/ayon_harmony/js/publish/ExtractPalette.js deleted file mode 100644 index fd96de518d..0000000000 --- a/server_addon/harmony/client/ayon_harmony/js/publish/ExtractPalette.js +++ /dev/null @@ -1,37 +0,0 @@ -/* global PypeHarmony:writable, include */ -// *************************************************************************** -// * ExtractPalette * -// *************************************************************************** - - -// check if PypeHarmony is defined and if not, load it. -if (typeof PypeHarmony === 'undefined') { - var AYON_HARMONY_JS = System.getenv('AYON_HARMONY_JS') + '/PypeHarmony.js'; - include(AYON_HARMONY_JS.replace(/\\/g, "/")); -} - -/** - * @namespace - * @classdesc Code for extracting palettes. - */ -var ExtractPalette = function() {}; - - -/** - * Get palette from Harmony. - * @function - * @param {string} paletteId ID of palette to get. - * @return {array} [paletteName, palettePath] - */ -ExtractPalette.prototype.getPalette = function(paletteId) { - var palette_list = PaletteObjectManager.getScenePaletteList(); - var palette = palette_list.getPaletteById(paletteId); - var palette_name = palette.getName(); - return [ - palette_name, - (palette.getPath() + '/' + palette.getName() + '.plt') - ]; -}; - -// add self to Pype Loaders -PypeHarmony.Publish.ExtractPalette = new ExtractPalette(); diff --git a/server_addon/harmony/client/ayon_harmony/js/publish/ExtractTemplate.js b/server_addon/harmony/client/ayon_harmony/js/publish/ExtractTemplate.js deleted file mode 100644 index 3ddad39117..0000000000 --- a/server_addon/harmony/client/ayon_harmony/js/publish/ExtractTemplate.js +++ /dev/null @@ -1,54 +0,0 @@ -/* global PypeHarmony:writable, include */ -// *************************************************************************** -// * ExtractTemplate * -// *************************************************************************** - - -// check if PypeHarmony is defined and if not, load it. -if (typeof PypeHarmony === 'undefined') { - var AYON_HARMONY_JS = System.getenv('AYON_HARMONY_JS') + '/PypeHarmony.js'; - include(AYON_HARMONY_JS.replace(/\\/g, "/")); -} - - -/** - * @namespace - * @classdesc Code for extracting palettes. - */ -var ExtractTemplate = function() {}; - - -/** - * Get backdrops for given node. - * @function - * @param {string} probeNode Node path to probe for backdrops. - * @return {array} list of backdrops. - */ -ExtractTemplate.prototype.getBackdropsByNode = function(probeNode) { - var backdrops = Backdrop.backdrops('Top'); - var valid_backdrops = []; - for(var i=0; i> 1 - 10 - # frameStart, frameEnd already collected by global plugin - offset = context.data["frameStart"] - 1 - frame_start = context.data["frameStart"] - offset - frames_count = context.data["frameEnd"] - \ - context.data["frameStart"] + 1 - - # increase by handleStart - real frame range - # frameStart != frameStartHandle with handle presence - context.data["frameStart"] = int(frame_start) + \ - context.data["handleStart"] - context.data["frameEnd"] = int(frames_count) + \ - context.data["frameStart"] - 1 - - all_nodes = harmony.send( - {"function": "node.subNodes", "args": ["Top"]} - )["result"] - - context.data["allNodes"] = all_nodes - - # collect all write nodes to be able disable them in Deadline - all_write_nodes = harmony.send( - {"function": "node.getNodes", "args": ["WRITE"]} - )["result"] - - context.data["all_write_nodes"] = all_write_nodes - - result = harmony.send( - { - "function": "PypeHarmony.getVersion", - "args": []} - )["result"] - context.data["harmonyVersion"] = "{}.{}".format(result[0], result[1]) diff --git a/server_addon/harmony/client/ayon_harmony/plugins/publish/collect_workfile.py b/server_addon/harmony/client/ayon_harmony/plugins/publish/collect_workfile.py deleted file mode 100644 index 488a7c4c71..0000000000 --- a/server_addon/harmony/client/ayon_harmony/plugins/publish/collect_workfile.py +++ /dev/null @@ -1,46 +0,0 @@ -# -*- coding: utf-8 -*- -"""Collect current workfile from Harmony.""" -import os -import pyblish.api - -from ayon_core.pipeline.create import get_product_name - - -class CollectWorkfile(pyblish.api.ContextPlugin): - """Collect current script for publish.""" - - order = pyblish.api.CollectorOrder + 0.1 - label = "Collect Workfile" - hosts = ["harmony"] - - def process(self, context): - """Plugin entry point.""" - product_type = "workfile" - basename = os.path.basename(context.data["currentFile"]) - task_entity = context.data["taskEntity"] - task_name = task_type = None - if task_entity: - task_name = task_entity["name"] - task_type = task_entity["taskType"] - product_name = get_product_name( - context.data["projectName"], - task_name, - task_type, - context.data["hostName"], - product_type, - "", - project_settings=context.data["project_settings"] - ) - - # Create instance - instance = context.create_instance(product_name) - instance.data.update({ - "productName": product_name, - "label": basename, - "name": basename, - "productType": product_type, - "family": product_type, - "families": [product_type], - "representations": [], - "folderPath": context.data["folderPath"] - }) diff --git a/server_addon/harmony/client/ayon_harmony/plugins/publish/extract_palette.py b/server_addon/harmony/client/ayon_harmony/plugins/publish/extract_palette.py deleted file mode 100644 index ad1d38e862..0000000000 --- a/server_addon/harmony/client/ayon_harmony/plugins/publish/extract_palette.py +++ /dev/null @@ -1,205 +0,0 @@ -# -*- coding: utf-8 -*- -"""Extract palette from Harmony.""" -import os -import csv - -from PIL import Image, ImageDraw, ImageFont - -import ayon_harmony.api as harmony -from ayon_core.pipeline import publish - - -class ExtractPalette(publish.Extractor): - """Extract palette.""" - - label = "Extract Palette" - hosts = ["harmony"] - families = ["harmony.palette"] - - def process(self, instance): - """Plugin entry point.""" - self_name = self.__class__.__name__ - result = harmony.send( - { - "function": f"PypeHarmony.Publish.{self_name}.getPalette", - "args": instance.data["id"] - })["result"] - - if not isinstance(result, list): - self.log.error(f"Invalid reply: {result}") - raise AssertionError("Invalid reply from server.") - palette_name = result[0] - palette_file = result[1] - self.log.info(f"Got palette named {palette_name} " - f"and file {palette_file}.") - - tmp_thumb_path = os.path.join(os.path.dirname(palette_file), - os.path.basename(palette_file) - .split(".plt")[0] + "_swatches.png" - ) - self.log.info(f"Temporary thumbnail path {tmp_thumb_path}") - - palette_version = str(instance.data.get("version")).zfill(3) - - self.log.info(f"Palette version {palette_version}") - - if not instance.data.get("representations"): - instance.data["representations"] = [] - - try: - thumbnail_path = self.create_palette_thumbnail(palette_name, - palette_version, - palette_file, - tmp_thumb_path) - except OSError as e: - # FIXME: this happens on Mac where PIL cannot access fonts - # for some reason. - self.log.warning("Thumbnail generation failed") - self.log.warning(e) - except ValueError: - self.log.error("Unsupported palette type for thumbnail.") - - else: - thumbnail = { - "name": "thumbnail", - "ext": "png", - "files": os.path.basename(thumbnail_path), - "stagingDir": os.path.dirname(thumbnail_path), - "tags": ["thumbnail"] - } - - instance.data["representations"].append(thumbnail) - - representation = { - "name": "plt", - "ext": "plt", - "files": os.path.basename(palette_file), - "stagingDir": os.path.dirname(palette_file) - } - - instance.data["representations"].append(representation) - - def create_palette_thumbnail(self, - palette_name, - palette_version, - palette_path, - dst_path): - """Create thumbnail for palette file. - - Args: - palette_name (str): Name of palette. - palette_version (str): Version of palette. - palette_path (str): Path to palette file. - dst_path (str): Thumbnail path. - - Returns: - str: Thumbnail path. - - """ - colors = {} - - with open(palette_path, newline='') as plt: - plt_parser = csv.reader(plt, delimiter=" ") - for i, line in enumerate(plt_parser): - if i == 0: - continue - while ("" in line): - line.remove("") - # self.log.debug(line) - if line[0] not in ["Solid"]: - raise ValueError("Unsupported palette type.") - color_name = line[1].strip('"') - colors[color_name] = {"type": line[0], - "uuid": line[2], - "rgba": (int(line[3]), - int(line[4]), - int(line[5]), - int(line[6])), - } - plt.close() - - img_pad_top = 80 - label_pad_name = 30 - label_pad_rgb = 580 - swatch_pad_left = 300 - swatch_pad_top = 10 - swatch_w = 120 - swatch_h = 50 - - image_w = 800 - image_h = (img_pad_top + - (len(colors.keys()) * - swatch_h) + - (swatch_pad_top * - len(colors.keys())) - ) - - img = Image.new("RGBA", (image_w, image_h), "white") - - # For bg of colors with alpha, create checkerboard image - checkers = Image.new("RGB", (swatch_w, swatch_h)) - pixels = checkers.load() - - # Make pixels white where (row+col) is odd - for i in range(swatch_w): - for j in range(swatch_h): - if (i + j) % 2: - pixels[i, j] = (255, 255, 255) - - draw = ImageDraw.Draw(img) - # TODO: This needs to be font included with Pype because - # arial is not available on other platforms then Windows. - title_font = ImageFont.truetype("arial.ttf", 28) - label_font = ImageFont.truetype("arial.ttf", 20) - - draw.text((label_pad_name, 20), - "{} (v{})".format(palette_name, palette_version), - "black", - font=title_font) - - for i, name in enumerate(colors): - rgba = colors[name]["rgba"] - # @TODO: Fix this so alpha colors are displayed with checkboard - # if not rgba[3] == "255": - # img.paste(checkers, - # (swatch_pad_left, - # img_pad_top + swatch_pad_top + (i * swatch_h)) - # ) - # - # half_y = (img_pad_top + swatch_pad_top + (i * swatch_h))/2 - # - # draw.rectangle(( - # swatch_pad_left, # upper LX - # img_pad_top + swatch_pad_top + (i * swatch_h), # upper LY - # swatch_pad_left + (swatch_w * 2), # lower RX - # half_y), # lower RY - # fill=rgba[:-1], outline=(0, 0, 0), width=2) - # draw.rectangle(( - # swatch_pad_left, # upper LX - # half_y, # upper LY - # swatch_pad_left + (swatch_w * 2), # lower RX - # img_pad_top + swatch_h + (i * swatch_h)), # lower RY - # fill=rgba, outline=(0, 0, 0), width=2) - # else: - - draw.rectangle(( - swatch_pad_left, # upper left x - img_pad_top + swatch_pad_top + (i * swatch_h), # upper left y - swatch_pad_left + (swatch_w * 2), # lower right x - img_pad_top + swatch_h + (i * swatch_h)), # lower right y - fill=rgba, outline=(0, 0, 0), width=2) - - draw.text((label_pad_name, img_pad_top + (i * swatch_h) + swatch_pad_top + (swatch_h / 4)), # noqa: E501 - name, - "black", - font=label_font) - - draw.text((label_pad_rgb, img_pad_top + (i * swatch_h) + swatch_pad_top + (swatch_h / 4)), # noqa: E501 - str(rgba), - "black", - font=label_font) - - draw = ImageDraw.Draw(img) - - img.save(dst_path) - return dst_path diff --git a/server_addon/harmony/client/ayon_harmony/plugins/publish/extract_render.py b/server_addon/harmony/client/ayon_harmony/plugins/publish/extract_render.py deleted file mode 100644 index 407a44c81a..0000000000 --- a/server_addon/harmony/client/ayon_harmony/plugins/publish/extract_render.py +++ /dev/null @@ -1,147 +0,0 @@ -import os -import tempfile -import subprocess - -import pyblish.api -import ayon_harmony.api as harmony -import ayon_core.lib - -import clique - - -class ExtractRender(pyblish.api.InstancePlugin): - """Produce a flattened image file from instance. - This plug-in only takes into account the nodes connected to the composite. - """ - - label = "Extract Render" - order = pyblish.api.ExtractorOrder - hosts = ["harmony"] - families = ["render"] - - def process(self, instance): - # Collect scene data. - - application_path = instance.context.data.get("applicationPath") - scene_path = instance.context.data.get("scenePath") - frame_rate = instance.context.data.get("frameRate") - # real value from timeline - frame_start = instance.context.data.get("frameStartHandle") - frame_end = instance.context.data.get("frameEndHandle") - audio_path = instance.context.data.get("audioPath") - - if audio_path and os.path.exists(audio_path): - self.log.info(f"Using audio from {audio_path}") - instance.data["audio"] = [{"filename": audio_path}] - - instance.data["fps"] = frame_rate - - # Set output path to temp folder. - path = tempfile.mkdtemp() - sig = harmony.signature() - func = """function %s(args) - { - node.setTextAttr(args[0], "DRAWING_NAME", 1, args[1]); - } - %s - """ % (sig, sig) - harmony.send( - { - "function": func, - "args": [instance.data["setMembers"][0], - path + "/" + instance.data["name"]] - } - ) - harmony.save_scene() - - # Execute rendering. Ignoring error cause Harmony returns error code - # always. - - args = [application_path, "-batch", - "-frames", str(frame_start), str(frame_end), - scene_path] - self.log.info(f"running: {' '.join(args)}") - proc = subprocess.Popen( - args, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - stdin=subprocess.PIPE - ) - output, error = proc.communicate() - self.log.info("Click on the line below to see more details.") - self.log.info(output.decode("utf-8")) - - # Collect rendered files. - self.log.debug(f"collecting from: {path}") - files = os.listdir(path) - assert files, ( - "No rendered files found, render failed." - ) - self.log.debug(f"files there: {files}") - collections, remainder = clique.assemble(files, minimum_items=1) - assert not remainder, ( - "There should not be a remainder for {0}: {1}".format( - instance.data["setMembers"][0], remainder - ) - ) - self.log.debug(collections) - if len(collections) > 1: - for col in collections: - if len(list(col)) > 1: - collection = col - else: - collection = collections[0] - - # Generate thumbnail. - thumbnail_path = os.path.join(path, "thumbnail.png") - args = ayon_core.lib.get_ffmpeg_tool_args( - "ffmpeg", - "-y", - "-i", os.path.join(path, list(collections[0])[0]), - "-vf", "scale=300:-1", - "-vframes", "1", - thumbnail_path - ) - process = subprocess.Popen( - args, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - stdin=subprocess.PIPE - ) - - output = process.communicate()[0] - - if process.returncode != 0: - raise ValueError(output.decode("utf-8", errors="backslashreplace")) - - self.log.debug(output.decode("utf-8", errors="backslashreplace")) - - # Generate representations. - extension = collection.tail[1:] - representation = { - "name": extension, - "ext": extension, - "files": list(collection), - "stagingDir": path, - "tags": ["review"], - "fps": frame_rate - } - - thumbnail = { - "name": "thumbnail", - "ext": "png", - "files": os.path.basename(thumbnail_path), - "stagingDir": path, - "tags": ["thumbnail"] - } - instance.data["representations"] = [representation, thumbnail] - - if audio_path and os.path.exists(audio_path): - instance.data["audio"] = [{"filename": audio_path}] - - # Required for extract_review plugin (L222 onwards). - instance.data["frameStart"] = frame_start - instance.data["frameEnd"] = frame_end - instance.data["fps"] = frame_rate - - self.log.info(f"Extracted {instance} to {path}") diff --git a/server_addon/harmony/client/ayon_harmony/plugins/publish/extract_save_scene.py b/server_addon/harmony/client/ayon_harmony/plugins/publish/extract_save_scene.py deleted file mode 100644 index 77ebc5b5a6..0000000000 --- a/server_addon/harmony/client/ayon_harmony/plugins/publish/extract_save_scene.py +++ /dev/null @@ -1,13 +0,0 @@ -import pyblish.api -import ayon_harmony.api as harmony - - -class ExtractSaveScene(pyblish.api.ContextPlugin): - """Save scene for extraction.""" - - label = "Extract Save Scene" - order = pyblish.api.ExtractorOrder - 0.49 - hosts = ["harmony"] - - def process(self, context): - harmony.save_scene() diff --git a/server_addon/harmony/client/ayon_harmony/plugins/publish/extract_template.py b/server_addon/harmony/client/ayon_harmony/plugins/publish/extract_template.py deleted file mode 100644 index 650765771c..0000000000 --- a/server_addon/harmony/client/ayon_harmony/plugins/publish/extract_template.py +++ /dev/null @@ -1,126 +0,0 @@ -# -*- coding: utf-8 -*- -"""Extract template.""" -import os -import shutil - -from ayon_core.pipeline import publish -import ayon_harmony.api as harmony - - -class ExtractTemplate(publish.Extractor): - """Extract the connected nodes to the composite instance.""" - - label = "Extract Template" - hosts = ["harmony"] - families = ["harmony.template"] - - def process(self, instance): - """Plugin entry point.""" - staging_dir = self.staging_dir(instance) - filepath = os.path.join(staging_dir, f"{instance.name}.tpl") - - self.log.info(f"Outputting template to {staging_dir}") - - dependencies = [] - self.get_dependencies(instance.data["setMembers"][0], dependencies) - - # Get backdrops. - backdrops = {} - for dependency in dependencies: - for backdrop in self.get_backdrops(dependency): - backdrops[backdrop["title"]["text"]] = backdrop - unique_backdrops = [backdrops[x] for x in set(backdrops.keys())] - if not unique_backdrops: - self.log.error(("No backdrops detected for template. " - "Please move template instance node onto " - "some backdrop and try again.")) - raise AssertionError("No backdrop detected") - # Get non-connected nodes within backdrops. - all_nodes = instance.context.data.get("allNodes") - for node in [x for x in all_nodes if x not in dependencies]: - within_unique_backdrops = bool( - [x for x in self.get_backdrops(node) if x in unique_backdrops] - ) - if within_unique_backdrops: - dependencies.append(node) - - # Make sure we dont export the instance node. - if instance.data["setMembers"][0] in dependencies: - dependencies.remove(instance.data["setMembers"][0]) - - # Export template. - harmony.export_template( - unique_backdrops, dependencies, filepath - ) - - # Prep representation. - os.chdir(staging_dir) - shutil.make_archive( - f"{instance.name}", - "zip", - os.path.join(staging_dir, f"{instance.name}.tpl") - ) - - representation = { - "name": "tpl", - "ext": "zip", - "files": f"{instance.name}.zip", - "stagingDir": staging_dir - } - - self.log.info(instance.data.get("representations")) - if instance.data.get("representations"): - instance.data["representations"].extend([representation]) - else: - instance.data["representations"] = [representation] - - instance.data["version_name"] = "{}_{}".format( - instance.data["productName"], - instance.context.data["task"] - ) - - def get_backdrops(self, node: str) -> list: - """Get backdrops for the node. - - Args: - node (str): Node path. - - Returns: - list: list of Backdrops. - - """ - self_name = self.__class__.__name__ - return harmony.send({ - "function": f"PypeHarmony.Publish.{self_name}.getBackdropsByNode", - "args": node})["result"] - - def get_dependencies( - self, node: str, dependencies: list = None) -> list: - """Get node dependencies. - - This will return recursive dependency list of given node. - - Args: - node (str): Path to the node. - dependencies (list, optional): existing dependency list. - - Returns: - list: List of dependent nodes. - - """ - current_dependencies = harmony.send( - { - "function": "PypeHarmony.getDependencies", - "args": node} - )["result"] - - for dependency in current_dependencies: - if not dependency: - continue - - if dependency in dependencies: - continue - - dependencies.append(dependency) - - self.get_dependencies(dependency, dependencies) diff --git a/server_addon/harmony/client/ayon_harmony/plugins/publish/extract_workfile.py b/server_addon/harmony/client/ayon_harmony/plugins/publish/extract_workfile.py deleted file mode 100644 index 3081a57157..0000000000 --- a/server_addon/harmony/client/ayon_harmony/plugins/publish/extract_workfile.py +++ /dev/null @@ -1,43 +0,0 @@ -# -*- coding: utf-8 -*- -"""Extract work file.""" -import os -import shutil -from zipfile import ZipFile - -from ayon_core.pipeline import publish - - -class ExtractWorkfile(publish.Extractor): - """Extract and zip complete workfile folder into zip.""" - - label = "Extract Workfile" - hosts = ["harmony"] - families = ["workfile"] - - def process(self, instance): - """Plugin entry point.""" - staging_dir = self.staging_dir(instance) - filepath = os.path.join(staging_dir, "{}.tpl".format(instance.name)) - src = os.path.dirname(instance.context.data["currentFile"]) - self.log.info("Copying to {}".format(filepath)) - shutil.copytree(src, filepath) - - # Prep representation. - os.chdir(staging_dir) - shutil.make_archive( - f"{instance.name}", - "zip", - os.path.join(staging_dir, f"{instance.name}.tpl") - ) - # Check if archive is ok - with ZipFile(os.path.basename(f"{instance.name}.zip")) as zr: - if zr.testzip() is not None: - raise Exception("File archive is corrupted.") - - representation = { - "name": "tpl", - "ext": "zip", - "files": f"{instance.name}.zip", - "stagingDir": staging_dir - } - instance.data["representations"] = [representation] diff --git a/server_addon/harmony/client/ayon_harmony/plugins/publish/help/validate_audio.xml b/server_addon/harmony/client/ayon_harmony/plugins/publish/help/validate_audio.xml deleted file mode 100644 index e9a183c675..0000000000 --- a/server_addon/harmony/client/ayon_harmony/plugins/publish/help/validate_audio.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - -Missing audio file - -## Cannot locate linked audio file - -Audio file at {audio_url} cannot be found. - -### How to repair? - -Copy audio file to the highlighted location or remove audio link in the workfile. - - - \ No newline at end of file diff --git a/server_addon/harmony/client/ayon_harmony/plugins/publish/help/validate_instances.xml b/server_addon/harmony/client/ayon_harmony/plugins/publish/help/validate_instances.xml deleted file mode 100644 index 8c2b523e29..0000000000 --- a/server_addon/harmony/client/ayon_harmony/plugins/publish/help/validate_instances.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - -Product context - -## Invalid product context - -Folder path found '{found}' in products, expected '{expected}'. - -### How to repair? - -You can fix this with `Repair` button on the right. This will use '{expected}' folder path and overwrite '{found}' folder path in scene metadata. - -After that restart `Publish` with a `Reload button`. - -If this is unwanted, close workfile and open again, that way different folder value would be used for context information. - - -### __Detailed Info__ (optional) - -This might happen if you are reuse old workfile and open it in different context. -(Eg. you created product "renderCompositingDefault" from folder "Robot' in "your_project_Robot_compositing.aep", now you opened this workfile in a context "Sloth" but existing product for "Robot" folder stayed in the workfile.) - - - \ No newline at end of file diff --git a/server_addon/harmony/client/ayon_harmony/plugins/publish/help/validate_scene_settings.xml b/server_addon/harmony/client/ayon_harmony/plugins/publish/help/validate_scene_settings.xml deleted file mode 100644 index b645a97cb2..0000000000 --- a/server_addon/harmony/client/ayon_harmony/plugins/publish/help/validate_scene_settings.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - -Scene setting - -## Invalid scene setting found - -One of the settings in a scene doesn't match to folder attributes on server. - -{invalid_setting_str} - -### How to repair? - -Change values for {invalid_keys_str} in the scene OR change them on the folder if they are wrong there. - - -### __Detailed Info__ (optional) - -This error is shown when for example resolution in the scene doesn't match to resolution set on the folder on the server. -Either value in the database or in the scene is wrong. - - - -Scene file doesn't exist - -## Scene file doesn't exist - -Collected scene {scene_url} doesn't exist. - -### How to repair? - -Re-save file, start publish from the beginning again. - - - \ No newline at end of file diff --git a/server_addon/harmony/client/ayon_harmony/plugins/publish/increment_workfile.py b/server_addon/harmony/client/ayon_harmony/plugins/publish/increment_workfile.py deleted file mode 100644 index fa43455b0d..0000000000 --- a/server_addon/harmony/client/ayon_harmony/plugins/publish/increment_workfile.py +++ /dev/null @@ -1,37 +0,0 @@ -import os - -import pyblish.api -from ayon_core.pipeline.publish import get_errored_plugins_from_context -from ayon_core.lib import version_up -import ayon_harmony.api as harmony - - -class IncrementWorkfile(pyblish.api.InstancePlugin): - """Increment the current workfile. - - Saves the current scene with an increased version number. - """ - - label = "Increment Workfile" - order = pyblish.api.IntegratorOrder + 9.0 - hosts = ["harmony"] - families = ["workfile"] - optional = True - - def process(self, instance): - errored_plugins = get_errored_plugins_from_context(instance.context) - if errored_plugins: - raise RuntimeError( - "Skipping incrementing current file because publishing failed." - ) - - scene_dir = version_up( - os.path.dirname(instance.context.data["currentFile"]) - ) - scene_path = os.path.join( - scene_dir, os.path.basename(scene_dir) + ".xstage" - ) - - harmony.save_scene_as(scene_path) - - self.log.info("Incremented workfile to: {}".format(scene_path)) diff --git a/server_addon/harmony/client/ayon_harmony/plugins/publish/validate_audio.py b/server_addon/harmony/client/ayon_harmony/plugins/publish/validate_audio.py deleted file mode 100644 index 6caa12c1e1..0000000000 --- a/server_addon/harmony/client/ayon_harmony/plugins/publish/validate_audio.py +++ /dev/null @@ -1,53 +0,0 @@ -import os - -import pyblish.api - -import ayon_harmony.api as harmony - -from ayon_core.pipeline import PublishXmlValidationError - - -class ValidateAudio(pyblish.api.InstancePlugin): - """Ensures that there is an audio file in the scene. - - If you are sure that you want to send render without audio, you can - disable this validator before clicking on "publish" - """ - - order = pyblish.api.ValidatorOrder - label = "Validate Audio" - families = ["render"] - hosts = ["harmony"] - settings_category = "harmony" - optional = True - - def process(self, instance): - node = None - if instance.data.get("setMembers"): - node = instance.data["setMembers"][0] - - if not node: - return - # Collect scene data. - func = """function func(write_node) - { - return [ - sound.getSoundtrackAll().path() - ] - } - func - """ - result = harmony.send( - {"function": func, "args": [node]} - )["result"] - - audio_path = result[0] - - msg = "You are missing audio file:\n{}".format(audio_path) - - formatting_data = { - "audio_url": audio_path - } - if not os.path.isfile(audio_path): - raise PublishXmlValidationError(self, msg, - formatting_data=formatting_data) diff --git a/server_addon/harmony/client/ayon_harmony/plugins/publish/validate_instances.py b/server_addon/harmony/client/ayon_harmony/plugins/publish/validate_instances.py deleted file mode 100644 index 8152aeeadf..0000000000 --- a/server_addon/harmony/client/ayon_harmony/plugins/publish/validate_instances.py +++ /dev/null @@ -1,60 +0,0 @@ -import pyblish.api - -import ayon_harmony.api as harmony -from ayon_core.pipeline import get_current_folder_path -from ayon_core.pipeline.publish import ( - ValidateContentsOrder, - PublishXmlValidationError, -) - - -class ValidateInstanceRepair(pyblish.api.Action): - """Repair the instance.""" - - label = "Repair" - icon = "wrench" - on = "failed" - - def process(self, context, plugin): - - # Get the errored instances - failed = [] - for result in context.data["results"]: - if (result["error"] is not None and result["instance"] is not None - and result["instance"] not in failed): - failed.append(result["instance"]) - - # Apply pyblish.logic to get the instances for the plug-in - instances = pyblish.api.instances_by_plugin(failed, plugin) - - folder_path = get_current_folder_path() - for instance in instances: - data = harmony.read(instance.data["setMembers"][0]) - data["folderPath"] = folder_path - harmony.imprint(instance.data["setMembers"][0], data) - - -class ValidateInstance(pyblish.api.InstancePlugin): - """Validate the instance folder is the current folder.""" - - label = "Validate Instance" - hosts = ["harmony"] - actions = [ValidateInstanceRepair] - order = ValidateContentsOrder - - def process(self, instance): - instance_folder_path = instance.data["folderPath"] - current_colder_path = get_current_folder_path() - msg = ( - "Instance folder is not the same as current folder:" - f"\nInstance: {instance_folder_path}]" - f"\nCurrent: {current_colder_path}" - ) - - formatting_data = { - "found": instance_folder_path, - "expected": current_colder_path - } - if instance_folder_path != current_colder_path: - raise PublishXmlValidationError(self, msg, - formatting_data=formatting_data) diff --git a/server_addon/harmony/client/ayon_harmony/plugins/publish/validate_scene_settings.py b/server_addon/harmony/client/ayon_harmony/plugins/publish/validate_scene_settings.py deleted file mode 100644 index 082eb4f1dd..0000000000 --- a/server_addon/harmony/client/ayon_harmony/plugins/publish/validate_scene_settings.py +++ /dev/null @@ -1,187 +0,0 @@ -# -*- coding: utf-8 -*- -"""Validate scene settings.""" -import os -import json -import re - -import pyblish.api - -import ayon_harmony.api as harmony -from ayon_core.pipeline import PublishXmlValidationError - - -class ValidateSceneSettingsRepair(pyblish.api.Action): - """Repair the instance.""" - - label = "Repair" - icon = "wrench" - on = "failed" - - def process(self, context, plugin): - """Repair action entry point.""" - expected = harmony.get_current_context_settings() - expected_settings = _update_frames(dict.copy(expected)) - expected_settings["frameStart"] = 1 - expected_settings["frameEnd"] = expected_settings["frameEnd"] + \ - expected_settings["handleEnd"] - harmony.set_scene_settings(expected_settings) - if not os.path.exists(context.data["scenePath"]): - self.log.info("correcting scene name") - scene_dir = os.path.dirname(context.data["currentFile"]) - scene_path = os.path.join( - scene_dir, os.path.basename(scene_dir) + ".xstage" - ) - harmony.save_scene_as(scene_path) - - -class ValidateSceneSettings(pyblish.api.InstancePlugin): - """Ensure the scene settings are in sync with database.""" - - order = pyblish.api.ValidatorOrder - label = "Validate Scene Settings" - families = ["workfile"] - hosts = ["harmony"] - actions = [ValidateSceneSettingsRepair] - settings_category = "harmony" - optional = True - - # skip frameEnd check if asset contains any of: - frame_check_filter = ["_ch_", "_pr_", "_intd_", "_extd_"] # regex - - # skip resolution check if Task name matches any of regex patterns - skip_resolution_check = ["render", "Render"] # regex - - # skip frameStart, frameEnd check if Task name matches any of regex patt. - skip_timelines_check = [] # regex - - def process(self, instance): - """Plugin entry point.""" - - # TODO 'get_current_context_settings' could expect folder entity - # as an argument which is available on 'context.data["folderEntity"]' - # - the same approach can be used in 'ValidateSceneSettingsRepair' - expected_settings = harmony.get_current_context_settings() - self.log.info("scene settings from DB:{}".format(expected_settings)) - expected_settings.pop("entityType") # not useful for the validation - - expected_settings = _update_frames(dict.copy(expected_settings)) - expected_settings["frameEndHandle"] = expected_settings["frameEnd"] +\ - expected_settings["handleEnd"] - - task_name = instance.context.data["task"] - - if (any(re.search(pattern, task_name) - for pattern in self.skip_resolution_check)): - self.log.info("Skipping resolution check because of " - "task name and pattern {}".format( - self.skip_resolution_check)) - expected_settings.pop("resolutionWidth") - expected_settings.pop("resolutionHeight") - - if (any(re.search(pattern, os.getenv('AYON_TASK_NAME')) - for pattern in self.skip_timelines_check)): - self.log.info("Skipping frames check because of " - "task name and pattern {}".format( - self.skip_timelines_check)) - expected_settings.pop('frameStart', None) - expected_settings.pop('frameEnd', None) - expected_settings.pop('frameStartHandle', None) - expected_settings.pop('frameEndHandle', None) - - folder_name = instance.context.data["folderPath"].rsplit("/", 1)[-1] - if any(re.search(pattern, folder_name) - for pattern in self.frame_check_filter): - self.log.info("Skipping frames check because of " - "task name and pattern {}".format( - self.frame_check_filter)) - expected_settings.pop('frameStart', None) - expected_settings.pop('frameEnd', None) - expected_settings.pop('frameStartHandle', None) - expected_settings.pop('frameEndHandle', None) - - # handle case where ftrack uses only two decimal places - # 23.976023976023978 vs. 23.98 - fps = instance.context.data.get("frameRate") - if isinstance(instance.context.data.get("frameRate"), float): - fps = float( - "{:.2f}".format(instance.context.data.get("frameRate"))) - - self.log.debug("filtered settings: {}".format(expected_settings)) - - current_settings = { - "fps": fps, - "frameStart": instance.context.data["frameStart"], - "frameEnd": instance.context.data["frameEnd"], - "handleStart": instance.context.data.get("handleStart"), - "handleEnd": instance.context.data.get("handleEnd"), - "frameStartHandle": instance.context.data.get("frameStartHandle"), - "frameEndHandle": instance.context.data.get("frameEndHandle"), - "resolutionWidth": instance.context.data.get("resolutionWidth"), - "resolutionHeight": instance.context.data.get("resolutionHeight"), - } - self.log.debug("current scene settings {}".format(current_settings)) - - invalid_settings = [] - invalid_keys = set() - for key, value in expected_settings.items(): - if value != current_settings[key]: - invalid_settings.append( - "{} expected: {} found: {}".format(key, value, - current_settings[key])) - invalid_keys.add(key) - - if ((expected_settings["handleStart"] - or expected_settings["handleEnd"]) - and invalid_settings): - msg = "Handles included in calculation. Remove handles in DB " +\ - "or extend frame range in timeline." - invalid_settings[-1]["reason"] = msg - - msg = "Found invalid settings:\n{}".format( - json.dumps(invalid_settings, sort_keys=True, indent=4) - ) - - if invalid_settings: - invalid_keys_str = ",".join(invalid_keys) - break_str = "
" - invalid_setting_str = "Found invalid settings:
{}".\ - format(break_str.join(invalid_settings)) - - formatting_data = { - "invalid_setting_str": invalid_setting_str, - "invalid_keys_str": invalid_keys_str - } - raise PublishXmlValidationError(self, msg, - formatting_data=formatting_data) - - scene_url = instance.context.data.get("scenePath") - if not os.path.exists(scene_url): - msg = "Scene file {} not found (saved under wrong name)".format( - scene_url - ) - formatting_data = { - "scene_url": scene_url - } - raise PublishXmlValidationError(self, msg, key="file_not_found", - formatting_data=formatting_data) - - -def _update_frames(expected_settings): - """ - Calculate proper frame range including handles set in DB. - - Harmony requires rendering from 1, so frame range is always moved - to 1. - Args: - expected_settings (dict): pulled from DB - - Returns: - modified expected_setting (dict) - """ - frames_count = expected_settings["frameEnd"] - \ - expected_settings["frameStart"] + 1 - - expected_settings["frameStart"] = 1.0 + expected_settings["handleStart"] - expected_settings["frameEnd"] = \ - expected_settings["frameStart"] + frames_count - 1 - return expected_settings diff --git a/server_addon/harmony/client/ayon_harmony/vendor/.eslintrc.json b/server_addon/harmony/client/ayon_harmony/vendor/.eslintrc.json deleted file mode 100644 index 3aafb2b905..0000000000 --- a/server_addon/harmony/client/ayon_harmony/vendor/.eslintrc.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "env": { - "browser": true - }, - "extends": "eslint:recommended", - "ignorePatterns": ["**/*.js"] -} diff --git a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/.gitattributes b/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/.gitattributes deleted file mode 100644 index a9083715c5..0000000000 --- a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/.gitattributes +++ /dev/null @@ -1,36 +0,0 @@ -$.html merge=ours -$.oAttribute.html merge=ours -$.oBackdrop.html merge=ours -$.oBox.html merge=ours -$.oColor.html merge=ours -$.oColorValue.html merge=ours -$.oColumn.html merge=ours -$.oDialog.html merge=ours -$.oDialog.Progress.html merge=ours -$.oDrawing.html merge=ours -$.oDrawingColumn.html merge=ours -$.oDrawingNode.html merge=ours -$.oElement.html merge=ours -$.oFile.html merge=ours -$.oFolder.html merge=ours -$.oFrame.html merge=ours -$.oGroupNode.html merge=ours -$.oList.html merge=ours -$.oNetwork.html merge=ours -$.oNode.html merge=ours -$.oNodeLink.html merge=ours -$.oPalette.html merge=ours -$.oPathPoint.html merge=ours -$.oPegNode.html merge=ours -$.oPoint.html merge=ours -$.oScene.html merge=ours -$.oThread.html merge=ours -$.oTimeline.html merge=ours -$.oTimelineLayer.html merge=ours -$.oUtils.html merge=ours -$.index.html merge=ours -$.global.html merge=ours -$.oDatabase.html merge=ours -$.oProgressDialog.html merge=ours -$.oProcess.html merge=ours -NodeTypes.html merge=ours \ No newline at end of file diff --git a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/.gitignore b/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/.gitignore deleted file mode 100644 index 23ed1735fe..0000000000 --- a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules/* - diff --git a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/Install.bat b/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/Install.bat deleted file mode 100644 index ee632a0fbf..0000000000 --- a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/Install.bat +++ /dev/null @@ -1,40 +0,0 @@ -@echo off -SETLOCAL ENABLEDELAYEDEXPANSION -SET dlPath=%~dp0 -set harmonyPrefsDir=%appdata%\Toon Boom Animation - -SETX LIB_OPENHARMONY_PATH %dlPath% - -echo ------------------------------------------------------------------- -echo -- Starting install of openHarmony open source scripting library -- -echo ------------------------------------------------------------------- -echo OpenHarmony will be installed to the folder : -echo %dlpath% -echo Do not delete the contents of this folder. - -REM Check Harmony Versions and make a list -for /d %%D in ("%harmonyPrefsDir%\*Harmony*") do ( - set harmonyVersionDir=%%~fD - for /d %%V in ("!harmonyVersionDir!\*-layouts*") do ( - set "folderName=%%~nD" - set "versionName=%%~nV" - set "harmonyFolder=!folderName:~-7!" - set "harmonyVersions=!versionName:~0,2!" - echo Found Toonboom Harmony !harmonyFolder! !harmonyVersions! - installing openHarmony for this version. - set "installDir=!harmonyPrefsDir!\Toon Boom Harmony !harmonyFolder!\!harmonyVersions!00-scripts\" - - if not "!installDir!" == "!dlPath!" ( - REM creating a "openHarmony.js" file in script folders - if not exist "!installDir!" mkdir "!installDir!" - - cd !installDir! - - set "script=include(System.getenv('LIB_OPENHARMONY_PATH')+'openHarmony.js');" - echo !script!> openHarmony.js - ) - echo ---- done. ---- - ) -) - -echo - Install Complete - -pause \ No newline at end of file diff --git a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/LICENSE b/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/LICENSE deleted file mode 100644 index a612ad9813..0000000000 --- a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/LICENSE +++ /dev/null @@ -1,373 +0,0 @@ -Mozilla Public License Version 2.0 -================================== - -1. Definitions --------------- - -1.1. "Contributor" - means each individual or legal entity that creates, contributes to - the creation of, or owns Covered Software. - -1.2. "Contributor Version" - means the combination of the Contributions of others (if any) used - by a Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - means Source Code Form to which the initial Contributor has attached - the notice in Exhibit A, the Executable Form of such Source Code - Form, and Modifications of such Source Code Form, in each case - including portions thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - (a) that the initial Contributor has attached the notice described - in Exhibit B to the Covered Software; or - - (b) that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the - terms of a Secondary License. - -1.6. "Executable Form" - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - means a work that combines Covered Software with other material, in - a separate file or files, that is not Covered Software. - -1.8. "License" - means this document. - -1.9. "Licensable" - means having the right to grant, to the maximum extent possible, - whether at the time of the initial grant or subsequently, any and - all of the rights conveyed by this License. - -1.10. "Modifications" - means any of the following: - - (a) any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered - Software; or - - (b) any new file in Source Code Form that contains any Covered - Software. - -1.11. "Patent Claims" of a Contributor - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the - License, by the making, using, selling, offering for sale, having - made, import, or transfer of either its Contributions or its - Contributor Version. - -1.12. "Secondary License" - means either the GNU General Public License, Version 2.0, the GNU - Lesser General Public License, Version 2.1, the GNU Affero General - Public License, Version 3.0, or any later versions of those - licenses. - -1.13. "Source Code Form" - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that - controls, is controlled by, or is under common control with You. For - purposes of this definition, "control" means (a) the power, direct - or indirect, to cause the direction or management of such entity, - whether by contract or otherwise, or (b) ownership of more than - fifty percent (50%) of the outstanding shares or beneficial - ownership of such entity. - -2. License Grants and Conditions --------------------------------- - -2.1. Grants - -Each Contributor hereby grants You a world-wide, royalty-free, -non-exclusive license: - -(a) under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - -(b) under Patent Claims of such Contributor to make, use, sell, offer - for sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - -The licenses granted in Section 2.1 with respect to any Contribution -become effective for each Contribution on the date the Contributor first -distributes such Contribution. - -2.3. Limitations on Grant Scope - -The licenses granted in this Section 2 are the only rights granted under -this License. No additional rights or licenses will be implied from the -distribution or licensing of Covered Software under this License. -Notwithstanding Section 2.1(b) above, no patent license is granted by a -Contributor: - -(a) for any code that a Contributor has removed from Covered Software; - or - -(b) for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - -(c) under Patent Claims infringed by Covered Software in the absence of - its Contributions. - -This License does not grant any rights in the trademarks, service marks, -or logos of any Contributor (except as may be necessary to comply with -the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - -No Contributor makes additional grants as a result of Your choice to -distribute the Covered Software under a subsequent version of this -License (see Section 10.2) or under the terms of a Secondary License (if -permitted under the terms of Section 3.3). - -2.5. Representation - -Each Contributor represents that the Contributor believes its -Contributions are its original creation(s) or it has sufficient rights -to grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - -This License is not intended to limit any rights You have under -applicable copyright doctrines of fair use, fair dealing, or other -equivalents. - -2.7. Conditions - -Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted -in Section 2.1. - -3. Responsibilities -------------------- - -3.1. Distribution of Source Form - -All distribution of Covered Software in Source Code Form, including any -Modifications that You create or to which You contribute, must be under -the terms of this License. You must inform recipients that the Source -Code Form of the Covered Software is governed by the terms of this -License, and how they can obtain a copy of this License. You may not -attempt to alter or restrict the recipients' rights in the Source Code -Form. - -3.2. Distribution of Executable Form - -If You distribute Covered Software in Executable Form then: - -(a) such Covered Software must also be made available in Source Code - Form, as described in Section 3.1, and You must inform recipients of - the Executable Form how they can obtain a copy of such Source Code - Form by reasonable means in a timely manner, at a charge no more - than the cost of distribution to the recipient; and - -(b) You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter - the recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - -You may create and distribute a Larger Work under terms of Your choice, -provided that You also comply with the requirements of this License for -the Covered Software. If the Larger Work is a combination of Covered -Software with a work governed by one or more Secondary Licenses, and the -Covered Software is not Incompatible With Secondary Licenses, this -License permits You to additionally distribute such Covered Software -under the terms of such Secondary License(s), so that the recipient of -the Larger Work may, at their option, further distribute the Covered -Software under the terms of either this License or such Secondary -License(s). - -3.4. Notices - -You may not remove or alter the substance of any license notices -(including copyright notices, patent notices, disclaimers of warranty, -or limitations of liability) contained within the Source Code Form of -the Covered Software, except that You may alter any license notices to -the extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - -You may choose to offer, and to charge a fee for, warranty, support, -indemnity or liability obligations to one or more recipients of Covered -Software. However, You may do so only on Your own behalf, and not on -behalf of any Contributor. You must make it absolutely clear that any -such warranty, support, indemnity, or liability obligation is offered by -You alone, and You hereby agree to indemnify every Contributor for any -liability incurred by such Contributor as a result of warranty, support, -indemnity or liability terms You offer. You may include additional -disclaimers of warranty and limitations of liability specific to any -jurisdiction. - -4. Inability to Comply Due to Statute or Regulation ---------------------------------------------------- - -If it is impossible for You to comply with any of the terms of this -License with respect to some or all of the Covered Software due to -statute, judicial order, or regulation then You must: (a) comply with -the terms of this License to the maximum extent possible; and (b) -describe the limitations and the code they affect. Such description must -be placed in a text file included with all distributions of the Covered -Software under this License. Except to the extent prohibited by statute -or regulation, such description must be sufficiently detailed for a -recipient of ordinary skill to be able to understand it. - -5. Termination --------------- - -5.1. The rights granted under this License will terminate automatically -if You fail to comply with any of its terms. However, if You become -compliant, then the rights granted under this License from a particular -Contributor are reinstated (a) provisionally, unless and until such -Contributor explicitly and finally terminates Your grants, and (b) on an -ongoing basis, if such Contributor fails to notify You of the -non-compliance by some reasonable means prior to 60 days after You have -come back into compliance. Moreover, Your grants from a particular -Contributor are reinstated on an ongoing basis if such Contributor -notifies You of the non-compliance by some reasonable means, this is the -first time You have received notice of non-compliance with this License -from such Contributor, and You become compliant prior to 30 days after -Your receipt of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent -infringement claim (excluding declaratory judgment actions, -counter-claims, and cross-claims) alleging that a Contributor Version -directly or indirectly infringes any patent, then the rights granted to -You by any and all Contributors for the Covered Software under Section -2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all -end user license agreements (excluding distributors and resellers) which -have been validly granted by You or Your distributors under this License -prior to termination shall survive termination. - -************************************************************************ -* * -* 6. Disclaimer of Warranty * -* ------------------------- * -* * -* Covered Software is provided under this License on an "as is" * -* basis, without warranty of any kind, either expressed, implied, or * -* statutory, including, without limitation, warranties that the * -* Covered Software is free of defects, merchantable, fit for a * -* particular purpose or non-infringing. The entire risk as to the * -* quality and performance of the Covered Software is with You. * -* Should any Covered Software prove defective in any respect, You * -* (not any Contributor) assume the cost of any necessary servicing, * -* repair, or correction. This disclaimer of warranty constitutes an * -* essential part of this License. No use of any Covered Software is * -* authorized under this License except under this disclaimer. * -* * -************************************************************************ - -************************************************************************ -* * -* 7. Limitation of Liability * -* -------------------------- * -* * -* Under no circumstances and under no legal theory, whether tort * -* (including negligence), contract, or otherwise, shall any * -* Contributor, or anyone who distributes Covered Software as * -* permitted above, be liable to You for any direct, indirect, * -* special, incidental, or consequential damages of any character * -* including, without limitation, damages for lost profits, loss of * -* goodwill, work stoppage, computer failure or malfunction, or any * -* and all other commercial damages or losses, even if such party * -* shall have been informed of the possibility of such damages. This * -* limitation of liability shall not apply to liability for death or * -* personal injury resulting from such party's negligence to the * -* extent applicable law prohibits such limitation. Some * -* jurisdictions do not allow the exclusion or limitation of * -* incidental or consequential damages, so this exclusion and * -* limitation may not apply to You. * -* * -************************************************************************ - -8. Litigation -------------- - -Any litigation relating to this License may be brought only in the -courts of a jurisdiction where the defendant maintains its principal -place of business and such litigation shall be governed by laws of that -jurisdiction, without reference to its conflict-of-law provisions. -Nothing in this Section shall prevent a party's ability to bring -cross-claims or counter-claims. - -9. Miscellaneous ----------------- - -This License represents the complete agreement concerning the subject -matter hereof. If any provision of this License is held to be -unenforceable, such provision shall be reformed only to the extent -necessary to make it enforceable. Any law or regulation which provides -that the language of a contract shall be construed against the drafter -shall not be used to construe this License against a Contributor. - -10. Versions of the License ---------------------------- - -10.1. New Versions - -Mozilla Foundation is the license steward. Except as provided in Section -10.3, no one other than the license steward has the right to modify or -publish new versions of this License. Each version will be given a -distinguishing version number. - -10.2. Effect of New Versions - -You may distribute the Covered Software under the terms of the version -of the License under which You originally received the Covered Software, -or under the terms of any subsequent version published by the license -steward. - -10.3. Modified Versions - -If you create software not governed by this License, and you want to -create a new license for such software, you may create and use a -modified version of this License if you rename the license and remove -any references to the name of the license steward (except to note that -such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary -Licenses - -If You choose to distribute Source Code Form that is Incompatible With -Secondary Licenses under the terms of this version of the License, the -notice described in Exhibit B of this License must be attached. - -Exhibit A - Source Code Form License Notice -------------------------------------------- - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular -file, then You may include the notice in a location (such as a LICENSE -file in a relevant directory) where a recipient would be likely to look -for such a notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice ---------------------------------------------------------- - - This Source Code Form is "Incompatible With Secondary Licenses", as - defined by the Mozilla Public License, v. 2.0. diff --git a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/README.md b/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/README.md deleted file mode 100644 index 064afca86c..0000000000 --- a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/README.md +++ /dev/null @@ -1,202 +0,0 @@ -# OpenHarmony - The Toonboom Harmony Open Source DOM Library - -## Why did we make this library ? - -Ever tried to make a simple script for toonboom Harmony, then got stumped by the numerous amount of steps required to execute the simplest action? Or bored of coding the same helper routines again and again for every studio you work for? - -Toonboom Harmony is a very powerful software, with hundreds of functions and tools, and it unlocks a great amount of possibilities for animation studios around the globe. And... being the produce of the hard work of a small team forced to prioritise, it can also be a bit rustic at times! - -We are users at heart, animators and riggers, who just want to interact with the software as simply as possible. Simplicity is at the heart of the design of openHarmony. But we also are developers, and we made the library for people like us who can't resist tweaking the software and bend it in all possible ways, and are looking for powerful functions to help them do it. - -This library's aim is to create a more direct way to interact with Toonboom through scripts, by providing a more intuitive way to access its elements, and help with the cumbersome and repetitive tasks as well as help unlock untapped potential in its many available systems. So we can go from having to do things like this: - -```javascript - // adding a Drawing to the scene with the official API - var myNodeName = "Drawing"; - var myColumnName = myNodeName; - var myNode = node.add("Top", myNodeName, "READ",0,0,0); - var myColumn = column.add(myColumnName, "DRAWING", "BOTTOM"); - var myElement = element.add (myNodeName, "COLOR", 12, "SCAN", "TVG"); - column.setElementIdOfDrawing(myColumnName, myElement); - node.linkAttr (myNode, "DRAWING.ELEMENT", myColumnName); - drawing.create (myElement, "1", false, false); - column.setEntry (myColumnName, 0, 1, "1"); -``` - -to simply writing : - -```javascript - // with openHarmony - var myNode = $.scene.root.addDrawingNode("Drawing"); - myNode.element.addDrawing(1); -``` - -Less time spent coding, more time spent having ideas! - ------ -## Do I need any knowledge of toonboom scripting to use openHarmony? - -OpenHarmony aims to be self contained and to reimplement all the basic functions of the Harmony API. So, while it might help to have prior experience to understand what goes on under the hood, knowledge of the official API is not required. - -However, should you reach the limits of what openHarmony can offer at this time, you can always access the official API at any moment. Maybe you can submit a request and the missing parts will be added eventually, or you can even delve into the code and add the necessary functions yourself if you feel like it! - -You can access a list of all the functions, how to use them, as well as examples, from the online documentation: - -[https://cfourney.github.io/OpenHarmony/$.html](https://cfourney.github.io/OpenHarmony/$.html) - -To help you get started, here is a full example using the library to make and animate a small car, covering most of the basic features. - -[https://github.com/cfourney/OpenHarmony/blob/master/examples/openHarmonyExample.js](https://github.com/cfourney/OpenHarmony/blob/master/examples/openHarmonyExample.js) - ------ -## The OpenHarmony Document Object Model or DOM - -OpenHarmony is based around the four principles of Object Oriented Programming: *Abstraction*, *Encapsulation*, *Inheritance*, *Polymorphism*. - -This means every element of the Harmony scene has a corresponding abstraction existing in the code as a class. We have oNode, oScene, oColumn, etc. Unlike in the official API, each class is designed to create objects that are instances of these classes and encapsulate them and all their actions. It means no more storing the path of nodes, column abstract names and element ids to interact with them; if you can create or call it, you can access all of its functionalities. Nodes are declined as DrawingNodes and PegNodes, which inherint from the Node Class, and so on. - -The openHarmony library doesn't merely provide *access* to the elements of a Toonboom Harmony file, it *models* them and their relationship to each others. - -The Document ObjectModel - -The *Document Object Model* is a way to organise the elements of the Toonboom scene by highlighting the way they interact with each other. The Scene object has a root group, which contains Nodes, which have Attributes which can be linked to Columns which contain Frames, etc. This way it's always easy to find and access the content you are looking for. The attribute system has also been streamlined and you can now set values of node properties with a simple attribution synthax. - -We implemented a global access to all elements and functions through the standard **dot notation** for the hierarchy, for ease of use, and clarity of code. - -Functions and methods also make extensive use of **optional parameters** so no more need to fill in all arguments when calling functions when the default behavior is all that's needed. - -On the other hand, the "o" naming scheme allows us to retain full access to the official API at all times. This means you can use it only when it really makes your life better. - ------ -## Adopting openHarmony for your project - -This library is made available under the [Mozilla Public license 2.0](https://www.mozilla.org/en-US/MPL/2.0/). - -OpenHarmony can be downloaded from [this repository](https://github.com/cfourney/OpenHarmony/releases/) directly. In order to make use of its functions, it needs to be unzipped next to the scripts you will be writing. - -All you have to do is call : -```javascript -include("openHarmony.js"); -``` -at the beginning of your script. - -You can ask your users to download their copy of the library and store it alongside, or bundle it as you wish as long as you include the license file provided on this repository. - -The entire library is documented at the address : - -https://cfourney.github.io/OpenHarmony/$.html - -This include a list of all the available functions as well as examples and references (such as the list of all available node attributes). - -As time goes by, more functions will be added and the documentation will also get richer as more examples get created. - ------ -## Installation - -#### simple install: -- download the zip from [the releases page](https://github.com/cfourney/OpenHarmony/releases/), -- unzip the contents to [your scripts folder](https://docs.toonboom.com/help/harmony-17/advanced/scripting/import-script.html). - -#### advanced install (for developers): -- clone the repository to the location of your choice - - -- or -- - -- download the zip from [the releases page](https://github.com/cfourney/OpenHarmony/releases/) -- unzip the contents where you want to store the library, - - -- then -- - -- run `install.bat`. - -This last step will tell Harmony where to look to load the library, by setting the environment variable `LIB_OPENHARMONY_PATH` to the current folder. - -It will then create a `openHarmony.js` file into the user scripts folder which calls the files from the folder from the `LIB_OPENHARMONY_PATH` variable, so that scripts can make direct use of it without having to worry about where openHarmony is stored. - -##### Troubleshooting: -- to test if the library is correctly installed, open the `Script Editor` window and type: -```javascript -include ("openHarmony.js"); -$.alert("hello world"); -``` -Run the script, and if there is an error (for ex `MAX_REENTRENCY `), check that the file `openHarmony.js` exists in the script folder, and contains only the line: -```javascript -include(System.getenv('LIB_OPENHARMONY_PATH')+'openHarmony.js'); -``` -Check that the environment variable `LIB_OPENHARMONY_PATH` is set correctly to the remote folder. - ------ -## How to add openHarmony to vscode intellisense for autocompletion - -Although not fully supported, you can get most of the autocompletion features to work by adding the following lines to a `jsconfig.json` file placed at the root of your working folder. -The paths need to be relative which means the openHarmony source code must be placed directly in your developping environment. - -For example, if your working folder contains the openHarmony source in a folder called `OpenHarmony` and your working scripts in a folder called `myScripts`, place the `jsconfig.json` file at the root of the folder and add these lines to the file: - -```javascript -{ - include : [ - "OpenHarmony/*", - "OpenHarmony/openHarmony/*", - "myScripts/*", - "*" - ] -} -``` - -[More information on vs code and jsconfig.json.](https://code.visualstudio.com/docs/nodejs/working-with-javascript) - ------ -## Let's get technical. I can code, and want to contribute, where do I start? - -Reading and understanding the existing code, or at least the structure of the lib, is a great start, but not a requirement. You can simply start adding your classes to the $ object that is the root of the harmony lib, and start implementing. However, try to follow these guidelines as they are the underlying principles that make the library consistent: - - * There is a $ global object, which contains all the class declarations, and can be passed from one context to another to access the functions. - - * Each class is an abstract representation of a core concept of Harmony, so naming and consistency (within the lib) is essential. But we are not bound by the structure or naming of Harmony if we find a better way, for example to make nomenclatures more consistent between the scripting interface and the UI. - - * Each class defines a bunch of class properties with getter/setters for the values that are directly related to an entity of the scene. If you're thinking of making a getter function that doesn't require arguments, use a getter setter instead! - - * Each class also defines methods which can be called on the class instances to affect its contents, or its children's contents. For example, you'd go to the scene class to add the things that live in the scene, such as elements, columns and palettes. You wouldn't go to the column class or palette class to add one, because then what are you adding it *to*? - - * We use encapsulation over having to pass a function arguments every time we can. Instead of adding a node to the scene, and having to pass a group as argument, adding a node is done directly by calling a method of the parent group. This way the parent/child relationship is always clear and the arguments list kept to a minimum. - - * The goal is to make the most useful set of functions we can. Instead of making a large function that does a lot, consider extracting the small useful subroutines you need in your function into the existing classes directly. - - * Each method argument besides the core one (for example, for adding nodes, we have to specify the type of the new node we create) must have a default fallback to make the argument optional. - - * Don't use globals ever, but maybe use a class property if you need an enum for example. - - * Don't use the official API namespace, any function that exists in the official API must remain accessible otherwise things will break. Prefix your class names with "o" to avoid this and to signify this function is part of openHarmony. - - * We use the official API as little as we can in the code, so that if the implementation changes, we can easily fix it in a minimal amount of places. Wrap it, then use the wrapper. (ex: oScene.name) - - * Users of the lib should almost never have to use "new" to create instances of their classes. Create accessors/factories that will do that for them. For example, $.scn creates and return a oScene instance, and $.scn.nodes returns new oNodes instances, but users don't have to create them themselves, so it's like they were always there, contained within. It also lets you create different subclasses for one factory. For example, $.scn.$node("Top/myNode") will either return a oNode, oDrawingNode, oPegNode or oGroupNode object depending on the node type of the node represented by the object. - Exceptions are small useful value containing objects that don't belong to the Harmony hierarchy like oPoint, oBox, oColorValue, etc. - - * It's a JS Library, so use camelCase naming and try to follow the google style guide for JS : - https://google.github.io/styleguide/jsguide.html - - * Document your new functions using the JSDocs synthax : https://devdocs.io/jsdoc/howto-es2015-classes - - * Make a branch, create a merge request when you're done, and we'll add the new stuff you added to the lib :) - - ------ -## Credits - -This library was created by Mathieu Chaptel and Chris Fourney. - -If you're using openHarmony, and are noticing things that you would like to see in the library, please feel free to contribute to the code directly, or send us feedback through Github. This project will only be as good as people working together can make it, and we need every piece of code and feedback we can get, and would love to hear from you! - ------ -## Community - -Join the discord community for help with the library and to contribute: -https://discord.gg/kgT38MG - ------ -## Acknowledgements - * [Yu Ueda](https://github.com/yueda1984) for his help to understand Harmony coordinate systems - * [Dash](https://github.com/35743) for his help to debug, test and develop the Pie Menus widgets - * [All the contributors](https://github.com/cfourney/OpenHarmony/graphs/contributors) for their precious help. \ No newline at end of file diff --git a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/build_doc.bat b/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/build_doc.bat deleted file mode 100644 index 57a6161e95..0000000000 --- a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/build_doc.bat +++ /dev/null @@ -1,2 +0,0 @@ -jsdoc -c ./documentation.json -t ../node_modules/jaguarjs-jsdoc -pause \ No newline at end of file diff --git a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/documentation.json b/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/documentation.json deleted file mode 100644 index 1b3c2b9ee7..0000000000 --- a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/documentation.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "plugins": [], - "recurseDepth": 10, - "source": { - "include": ["."], - "includePattern": ".+\\.js(doc|x)?$", - "exclude": [ "./openHarmony_tools.js" ] - }, - "sourceType": "module", - "tags": { - "allowUnknownTags": true, - "dictionaries": ["jsdoc","closure"] - }, - "templates": { - "cleverLinks": false, - "monospaceLinks": false - }, - "opts": { - "encoding": "utf8", - "destination": "./docs/", - "recurse": true - } -} \ No newline at end of file diff --git a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/install.sh b/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/install.sh deleted file mode 100644 index 7d311d84f3..0000000000 --- a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/install.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash - -set dlPath=pwd -set harmonyPrefsDir=~/Library/Preferences/Toon Boom Animation/ - -echo ------------------------------------------------------------------- -echo -- Starting install of openHarmony open source scripting library -- -echo ------------------------------------------------------------------- -echo OpenHarmony will be installed to the folder : -echo $dlpath -echo Do not delete the contents of this folder. - -REM Check Harmony Versions and make a list -for /d %%D in ("%harmonyPrefsDir%\*Harmony*") do ( - set harmonyVersionDir=%%~fD - for /d %%V in ("!harmonyVersionDir!\*-layouts*") do ( - set "folderName=%%~nD" - set "versionName=%%~nV" - set "harmonyFolder=!folderName:~-7!" - set "harmonyVersions=!versionName:~0,2!" - echo Found Toonboom Harmony !harmonyFolder! !harmonyVersions! - installing openHarmony for this version. - set "installDir=!harmonyPrefsDir!\Toon Boom Harmony !harmonyFolder!\!harmonyVersions!00-scripts\" diff --git a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/oH_DOM.jpg b/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/oH_DOM.jpg deleted file mode 100644 index 3892cba69b..0000000000 Binary files a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/oH_DOM.jpg and /dev/null differ diff --git a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony.js b/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony.js deleted file mode 100644 index ae65d32a2b..0000000000 --- a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony.js +++ /dev/null @@ -1,497 +0,0 @@ -////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// -// -// openHarmony Library -// -// -// Developed by Mathieu Chaptel, Chris Fourney -// -// -// This library is an open source implementation of a Document Object Model -// for Toonboom Harmony. It also implements patterns similar to JQuery -// for traversing this DOM. -// -// Its intended purpose is to simplify and streamline toonboom scripting to -// empower users and be easy on newcomers, with default parameters values, -// and by hiding the heavy lifting required by the official API. -// -// This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is guaranteed to work. Feel free to contribute -// improvements to its official github. If you do make sure you follow the provided -// template and naming conventions and document your new methods properly. -// -// This library doesn't overwrite any of the objects and classes of the official -// Toonboom API which must remains available. -// -// This library is made available under the Mozilla Public license 2.0. -// https://www.mozilla.org/en-US/MPL/2.0/ -// -// The repository for this library is available at the address: -// https://github.com/cfourney/OpenHarmony/ -// -// -// For any requests feel free to contact m.chaptel@gmail.com -// -// -// -// -////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $ (DOM) class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * All the classes can be accessed from it, and it can be passed to a different context. - * @namespace - * @classdesc The $ global object that holds all the functions of openHarmony. - * @property {int} debug_level The debug level of the DOM. - * @property {bool} batchMode Deactivate all ui and incompatible functions to ensure scripts run in batch. - * @property {string} file The openHarmony base file - THIS! - * - * @property {$.oScene} getScene The harmony scene. - * @property {$.oScene} scene The harmony scene. - * @property {$.oScene} scn The harmony scene. - * @property {$.oScene} s The harmony scene. - * @property {$.oApp} getApplication The Harmony Application Object. - * @property {$.oApp} application The Harmony Application Object. - * @property {$.oApp} app The Harmony Application Object. - * @property {$.oNetwork} network Access point for all the functions of the $.oNetwork class - * @property {$.oUtils} utils Access point for all the functions of the $.oUtils class - * @property {$.oDialog} dialog Access point for all the functions of the $.oDialog class - * @property {Object} global The global scope. - * - * @example - * // To access the functions, first call the $ object. It is made available after loading openHarmony like so: - * - * include ("openHarmony.js"); - * - * var doc = $.scn; // grabbing the scene document - * $.log("hello"); // prints out a message to the MessageLog. - * var myPoint = new $.oPoint(0,0,0); // create a new class instance from an openHarmony class. - * - * // function members of the $ objects get published to the global scope, which means $ can be omitted - * - * log("hello"); - * var myPoint = new oPoint(0,0,0); // This is all valid - * var doc = scn; // "scn" isn't a function so this one isn't - * - */ -$ = { - debug_level : 0, - - /** - * Enum to set the debug level of debug statements. - * @name $#DEBUG_LEVEL - * @enum - */ - DEBUG_LEVEL : { - 'ERROR' : 0, - 'WARNING' : 1, - 'LOG' : 2 - }, - file : __file__, - directory : false, - pi : 3.14159265359 -}; - - -/** - * The openHarmony main Install directory - * @name $#directory - * @type {string} - */ -Object.defineProperty( $, "directory", { - get : function(){ - var currentFile = __file__ - return currentFile.split("\\").join("/").split( "/" ).slice(0, -1).join('/'); - } -}); - - -/** - * Whether Harmony is run with the interface or simply from command line - */ -Object.defineProperty( $, "batchMode", { - get: function(){ - // use a cache to avoid pulling the widgets every time - if (!this.hasOwnProperty("_batchMode")){ - this._batchMode = true; - - // batchmode is false if there are any widgets visible in the application - var _widgets = QApplication.topLevelWidgets(); - for (var i in _widgets){ - if (_widgets[i].visible) this._batchMode = false; - } - } - return this._batchMode - } -}) - -/** - * Function to load openHarmony files from the %installdir%/openHarmony/ folder. - * @name $#loadOpenHarmonyFiles - * @private - */ -var _ohDirectory = $.directory+"/openHarmony/"; -var _dir = new QDir(_ohDirectory); -_dir.setNameFilters(["openHarmony*.js"]); -_dir.setFilter( QDir.Files); -var _files = _dir.entryList(); - -for (var i in _files){ - include( _ohDirectory + "/" + _files[i]); -} - - - - -/** - * The standard debug that uses logic and level to write to the messagelog. Everything should just call this to write internally to a log in OpenHarmony. - * @function - * @name $#debug - * @param {obj} obj Description. - * @param {int} level The debug level of the incoming message to log. - */ -$.debug = function( obj, level ){ - if( level > this.debug_level ) return; - - try{ - if (typeof obj !== 'object') throw new Error(); - this.log(JSON.stringify(obj)); - }catch(err){ - this.log(obj); - } -} - - -/** - * Log the string to the MessageLog. - * @function - * @name $#log - * @param {string} str Text to log. - */ -$.log = function( str ){ - MessageLog.trace( str ); - System.println( str ); -} - - -/** - * Log the object and its contents. - * @function - * @name $#logObj - * @param {object} object The object to log. - * @param {int} debugLevel The debug level. - */ -$.logObj = function( object ){ - for (var i in object){ - try { - if (typeof object[i] === "function") continue; - $.log(i+' : '+object[i]) - if (typeof object[i] == "Object"){ - $.log(' -> ') - $.logObj(object[i]) - $.log(' ----- ') - } - }catch(error){} - } -} - - -//---- App -------------- -$.app = new $.oApp(); -$.application = $.app; -$.getApplication = $.app; - - -//---- Scene -------------- -$.s = new $.oScene(); -$.scn = $.s; -$.scene = $.s; -$.getScene = $.s; - - -/** - * Prompts with a confirmation dialog (yes/no choice). - * @function - * @name $#confirm - * @param {string} [labelText] The label/internal text of the dialog. - * @param {string} [title] The title of the confirmation dialog. - * @param {string} [okButtonText] The text on the OK button of the dialog. - * @param {string} [cancelButtonText] The text on the CANCEL button of the dialog. - * - * @return {bool} Result of the confirmation dialog. - */ -$.confirm = function(){ return $.dialog.confirm.apply( $.dialog, arguments ) }; - - -/** - * Prompts with an alert dialog (informational). - * @function - * @name $#alert - * @param {string} [labelText] The label/internal text of the dialog. - * @param {string} [title] The title of the confirmation dialog. - * @param {string} [okButtonText] The text on the OK button of the dialog. - */ -$.alert = function(){ return $.dialog.alert.apply( $.dialog, arguments ) }; - - - -/** - * Prompts with an alert dialog with a text box which can be selected (informational). - * @function - * @name $#alertBox - * @param {string} [labelText] The label/internal text of the dialog. - * @param {string} [title] The title of the confirmation dialog. - * @param {string} [okButtonText] The text on the OK button of the dialog. - */ -$.alertBox = function(){ return $.dialog.alertBox.apply( $.dialog, arguments ) }; - - - -/** - * Prompts with an toast alert. This is a small message that can't be clicked and only stays on the screen for the duration specified. - * @function - * @name $#toast - * @param {string} labelText The label/internal text of the dialog. - * @param {$.oPoint} [position] The position on the screen where the toast will appear (by default, slightly under the middle of the screen). - * @param {float} [duration=2000] The duration of the display (in milliseconds). - * @param {$.oColorValue} [color="#000000"] The color of the background (a 50% alpha value will be applied). - */ -$.toast = function(){ return $.dialog.toast.apply( $.dialog, arguments ) }; - - - -/** - * Prompts for a user input. - * @function - * @name $#prompt - * @param {string} [labelText] The label/internal text of the dialog. - * @param {string} [title] The title of the confirmation dialog. - * @param {string} [prefilledText] The text to display in the input area. - */ -$.prompt = function(){ return $.dialog.prompt.apply( $.dialog, arguments ) }; - - -/** - * Prompts with a file selector window - * @function - * @name $#browseForFile - * @param {string} [text="Select a file:"] The title of the file select dialog. - * @param {string} [filter="*"] The filter for the file type and/or file name that can be selected. Accepts wildcard character "*". - * @param {string} [getExisting=true] Whether to select an existing file or a save location - * @param {string} [acceptMultiple=false] Whether or not selecting more than one file is ok. Is ignored if getExisting is false. - * @param {string} [startDirectory] The directory showed at the opening of the dialog. - * - * @return {string[]} The list of selected Files, 'undefined' if the dialog is cancelled - */ -$.browseForFile = function(){ return $.dialog.browseForFile.apply( $.dialog, arguments ) }; - - -/** - * Prompts with a folder selector window. - * @function - * @name $#browseForFolder - * @param {string} [text] The title of the confirmation dialog. - * @param {string} [startDirectory] The directory showed at the opening of the dialog. - * - * @return {string} The path of the selected folder, 'undefined' if the dialog is cancelled - */ -$.browseForFolder = function(){ return $.dialog.browseForFolder.apply( $.dialog, arguments ) }; - - -/** - * Gets access to a widget from the Harmony Interface. - * @function - * @name $#getHarmonyUIWidget - * @param {string} name The name of the widget to look for. - * @param {string} [parentName] The name of the parent widget to look into, in case of duplicates. - */ -$.getHarmonyUIWidget = function(){ return $.app.getWidgetByName.apply( $.app, arguments ) } - - -//---- Cache Helpers ------ -$.cache_columnToNodeAttribute = {}; -$.cache_columnToNodeAttribute_date = (new Date()).getTime(); -$.cache_oNode = {}; - - -//------------------------------------------------ -//-- Undo operations - -/** - * Starts the tracking of the undo accumulation, all subsequent actions are done in a single undo operation.
Close the undo accum with $.endUndo(). - * If this function is called multiple time, only the first time will count. - * (this prevents small functions wrapped in their own undo block to interfere with global script undo) - * @param {string} undoName The name of the operation that is being done in the undo accum. - * @name $#beginUndo - * @function - * @see $.endUndo - */ -$.beginUndo = function( undoName ){ - if ($.batchMode) return - if (typeof undoName === 'undefined') var undoName = ''+((new Date()).getTime()); - if (!$.hasOwnProperty("undoStackSize")) $.undoStackSize = 0; - if ($.undoStackSize == 0) scene.beginUndoRedoAccum( undoName ); - $.undoStackSize++; -} - -/** - * Cancels the tracking of the undo accumulation, everything between this and the start of the accumulation is undone. - * @name $#cancelUndo - * @function - */ -$.cancelUndo = function( ){ - scene.cancelUndoRedoAccum( ); -} - -/** - * Stops the tracking of the undo accumulation, everything between this and the start of the accumulation behaves as a single undo operation. - * If beginUndo function is called multiple time, each call must be matched with this function. - * (this prevents small functions wrapped in their own undo block to interfere with global script undo) - * @name $#endUndo - * @function - * @see $.beginUndo - */ -$.endUndo = function( ){ - if ($.batchMode) return - - if (!$.hasOwnProperty("undoStackSize")) $.undoStackSize = 1; - $.undoStackSize--; - if ($.undoStackSize == 0) scene.endUndoRedoAccum(); -} - -/** - * Undoes the last n operations. If n is not specified, it will be 1 - * @name $#undo - * @function - * @param {int} dist The amount of operations to undo. - */ -$.undo = function( dist ){ - if (typeof dist === 'undefined'){ var dist = 1; } - scene.undo( dist ); -} - -/** - * Redoes the last n operations. If n is not specified, it will be 1 - * @name $#redo - * @function - * @param {int} dist The amount of operations to undo. - */ -$.redo = function( dist ){ - if (typeof dist === 'undefined'){ var dist = 1; } - scene.redo( dist ); -} - - -/** - * Gets the preferences from the Harmony stage. - * @name $#getPreferences - * @function - */ -$.getPreferences = function( ){ - return new $.oPreferences(); -} - -//---- Attach Helpers ------ -$.network = new $.oNetwork(); -$.utils = $.oUtils; -$.dialog = new $.oDialog(); -$.global = this; - - -//---- Self caching ----- - -/** - * change this value to allow self caching across openHarmony when initialising objects. - * @name $#useCache - * @type {bool} - */ -$.useCache = false; - - -/** - * function to call in constructors of classes so that instances of this class - * are cached and unique based on constructor arguments. - * @returns a cached class instance or null if no cached instance exists. - */ -$.getInstanceFromCache = function(){ - if (!this.__proto__.hasOwnProperty("__cache__")) { - this.__proto__.__cache__ = {}; - } - var _cache = this.__proto__.__cache__; - - if (!this.$.useCache) return; - - var key = []; - for (var i=0; i, ); - * - * // To launch an action, call the synthax: - * Action.perform (, , parameters); - */ - -/** - * Actions available in the ExportGifResponder responder. - * @name actions#ExportGifResponder - * @property {QAction} onActionExportGif() - */ - -/** - * Actions available in the ExposureFillResponder responder. - * @name actions#ExposureFillResponder - * @property {QAction} onActionExposureFillUsingRenderChange() - */ - -/** - * Actions available in the GameSkinResponder responder. - * @name actions#GameSkinResponder - */ - -/** - * Actions available in the GuideToolResponder responder. - * @name actions#GuideToolResponder - */ - -/** - * Actions available in the MatteGeneratorResponder responder. - * @name actions#MatteGeneratorResponder - * @property {QAction} onActionNull() - * @property {QAction} onActionNullAddHint() - * @property {QAction} onActionGenerateMatte() - * @property {QAction} onActionGenerateHints() - * @property {QAction} onActionMakeMatteVerticesAnimatable() - * @property {QAction} onActionMergeInnerOuterContours() - * @property {QAction} onActionRemoveUnusedMatteDisplacements() - * @property {QAction} onActionShowOptionsInCameraView() - * @property {QAction} onActionRemoveSelectedHints() - * @property {QAction} onActionRemoveSelectedVertices() - * @property {QAction} onActionRemoveSelectedVertexAnimation() - * @property {QAction} onActionEnableNormalMode() - * @property {QAction} onActionEnableSetupMode() - * @property {QAction} onActionEnableAddVertexMode() - * @property {QAction} onActionEnableAddHintMode() - * @property {QAction} onActionToggleShowOuterContour() - * @property {QAction} onActionToggleShowInnerContour() - * @property {QAction} onActionToggleShowPointId() - * @property {QAction} onActionToggleShowHints() - * @property {QAction} onActionToggleShowOverlayAnnotation() - * @property {QAction} onActionToggleShowInflate() - * @property {QAction} onActionAlignMatteHandles() - * @property {QAction} onActionShortenMatteHandles() - * @property {QAction} onActionExpandOuterContour() - * @property {QAction} onActionExpandInnerContour() - * @property {QAction} onActionReduceOuterContour() - * @property {QAction} onActionReduceInnerContour() - * @property {QAction} onActionToggleAutoKey() - * @property {QAction} onActionToggleFixAdjacentKeyframes() - * @property {QAction} onActionReloadView() - * @property {QAction} onActionDefineResourceFolder() - * @property {QAction} onActionExportResourceFolder() - * @property {QAction} onActionResetResourceFolder() - */ - -/** - * Actions available in the ModuleLibraryIconView responder. - * @name actions#ModuleLibraryIconView - */ - -/** - * Actions available in the ModuleLibraryListView responder. - * @name actions#ModuleLibraryListView - */ - -/** - * Actions available in the ModuleLibraryTemplatesResponder responder. - * @name actions#ModuleLibraryTemplatesResponder - */ - -/** - * Actions available in the Node View responder. - * @name actions#Node View - * @property {QAction} onActionResetView() - * @property {QAction} onActionTag() - * @property {QAction} onActionUntag() - * @property {QAction} onActionUntagAll() - * @property {QAction} onActionUntagAllOthers() - * @property {QAction} onActionZoomIn() - * @property {QAction} onActionZoomOut() - * @property {QAction} onActionResetZoom() - * @property {QAction} onActionResetPan() - * @property {QAction} onActionShowAllModules() - * @property {QAction} onActionPasteSpecial() - * @property {QAction} onActionPasteSpecialAgain() - * @property {QAction} onActionCloneElement() - * @property {QAction} onActionCloneElement_DrawingsOnly() - * @property {QAction} onActionCopyQualifiedName() - * @property {QAction} onActionDuplicateElement() - * @property {QAction} onActionSelEnable() - * @property {QAction} onActionEnableAll() - * @property {QAction} onActionSelDisable() - * @property {QAction} onActionDisableAllUnselected() - * @property {QAction} onActionRecomputeAll() - * @property {QAction} onActionRecomputeSelected() - * @property {QAction} onActionSelCreateGroup() - * @property {QAction} onActionSelCreateGroupWithComposite() - * @property {QAction} onActionSelMoveToParentGroup() - * @property {QAction} onActionSelMergeInto() - * @property {QAction} onActionClearPublishedAttributes() - * @property {QAction} onActionPrintNetwork() - * @property {QAction} onActionUpToParent() - * @property {QAction} onActionShowHideWorldView() - * @property {QAction} onActionMoveWorldNE() - * @property {QAction} onActionMoveWorldNW() - * @property {QAction} onActionMoveWorldSE() - * @property {QAction} onActionMoveWorldSW() - * @property {QAction} onActionEnterGroup() - * @property {QAction} onActionCreateGroup() - * @property {QAction} onActionCreatePeg() - * @property {QAction} onActionCreateParentPeg() - * @property {QAction} onActionCreateDisplay() - * @property {QAction} onActionCreateRead() - * @property {QAction} onActionCreateComposite() - * @property {QAction} onActionCreateBackdrop() - * @property {QAction} onActionToggleDefinePublishMode() - * @property {QAction} onActionNavigateGroup() - * @property {QAction} onActionGotoPortAbove() - * @property {QAction} onActionGotoPortUnder() - * @property {QAction} onActionGotoPortLeft() - * @property {QAction} onActionGotoPortRight() - * @property {QAction} onActionToggleDefineAttributeInfo() - * @property {QAction} onActionCreateFavorite(QString) - * @property {QAction} onActionCreateModule(QString) - * @property {QAction} onActionCableLine() - * @property {QAction} onActionCableStraight() - * @property {QAction} onActionCableBezier() - * @property {QAction} onActionRecenter() - * @property {QAction} onActionFocusOnSelectionNV() - * @property {QAction} onActionFocusOnParentNodeNV() - * @property {QAction} onActionFocusOnChildNodeNV() - * @property {QAction} onActionToggleSelectedThumbNail() - * @property {QAction} onActionShowAllThumbNail() - * @property {QAction} onActionHideAllThumbNails() - * @property {QAction} onActionShowSelectedThumbNail() - * @property {QAction} onActionHideSelectedThumbNail() - * @property {QAction} onActionNaviSelectChild() - * @property {QAction} onActionNaviSelectChilds() - * @property {QAction} onActionNaviSelectParent() - * @property {QAction} onActionNaviSelectPreviousBrother() - * @property {QAction} onActionNaviSelectNextBrother() - * @property {QAction} onActionNaviSelectInnerChildren() - * @property {QAction} onActionNaviSelectParentWithEffects() - * @property {QAction} onActionNaviSelectChildWithEffects() - * @property {QAction} onActionSelectLinkedLayers() - * @property {QAction} onActionSetDrawingAsSubLayer() - * @property {QAction} onActionUnlinkSubLayer() - * @property {QAction} onActionAddSubLayer() - * @property {QAction} onActionRenameWaypoint() - * @property {QAction} onActionCreateWaypointFromContextMenu() - * @property {QAction} onActionCreateWaypointFromShortcut() - */ - -/** - * Actions available in the ParticleCoreGuiResponder responder. - * @name actions#ParticleCoreGuiResponder - * @property {QAction} onActionInsertParticleTemplate(QString) - * @property {QAction} onActionToggleShowAsDots() - */ - -/** - * Actions available in the PluginHelpViewResponder responder. - * @name actions#PluginHelpViewResponder - * @property {QAction} onActionShowShortcuts() - */ - -/** - * Actions available in the Script responder. - * @name actions#Script - */ - -/** - * Actions available in the ScriptManagerResponder responder. - * @name actions#ScriptManagerResponder - */ - -/** - * Actions available in the ScriptViewResponder responder. - * @name actions#ScriptViewResponder - * @property {QAction} onActionNewScriptFile() - * @property {QAction} onActionImportScript() - * @property {QAction} onActionDeleteScript() - * @property {QAction} onActionRefreshScripts() - * @property {QAction} onActionRun() - * @property {QAction} onActionDebug() - * @property {QAction} onActionStopExecution() - * @property {QAction} onActionOpenHelp() - * @property {QAction} onActionSetTarget() - * @property {QAction} onActionSetExternalEditor() - * @property {QAction} onActionCallExternalEditor() - */ - -/** - * Actions available in the ShiftAndTraceToolResponder responder. - * @name actions#ShiftAndTraceToolResponder - * @property {QAction} onActionEnableShiftAndTrace() - * @property {QAction} onActionSelectShiftAndTraceTool() - * @property {QAction} onActionToggleShowManipulator() - * @property {QAction} onActionToggleShowPegs() - * @property {QAction} onActionToggleShowOutline() - * @property {QAction} onActionSetPegPosition(int) - * @property {QAction} onActionShiftAndTraceToolRotateOverride() - * @property {QAction} onActionShiftAndTraceToolScaleOverride() - * @property {QAction} onActionShiftAndTraceToolResetCurrentPosition() - * @property {QAction} onActionShiftAndTraceToolResetAllPositions() - * @property {QAction} onActionResetCurrentShiftPosition() - * @property {QAction} onActionResetAllShiftPositions() - * @property {QAction} onActionShowCrossHair() - * @property {QAction} onActionAddCrossHairMode() - * @property {QAction} onActionRemoveCrossHair() - */ - -/** - * Actions available in the artLayerResponder responder. - * @name actions#artLayerResponder - * @property {QAction} onActionPreviewModeToggle() - * @property {QAction} onActionOverlayArtSelected() - * @property {QAction} onActionLineArtSelected() - * @property {QAction} onActionColorArtSelected() - * @property {QAction} onActionUnderlayArtSelected() - * @property {QAction} onActionToggleLineColorArt() - * @property {QAction} onActionToggleOverlayUnderlayArt() - */ - -/** - * Actions available in the brushSettingsResponder responder. - * @name actions#brushSettingsResponder - */ - -/** - * Actions available in the cameraView responder. - * @name actions#cameraView - * @property {QAction} onActionRenameDrawing() - * @property {QAction} onActionRenameDrawingWithPrefix() - * @property {QAction} onActionDeleteDrawings() - * @property {QAction} onActionToggleShowSymbolPivot() - * @property {QAction} onActionShowGrid() - * @property {QAction} onActionNormalGrid() - * @property {QAction} onAction12FieldGrid() - * @property {QAction} onAction16FieldGrid() - * @property {QAction} onActionWorldGrid() - * @property {QAction} onActionGridUnderlay() - * @property {QAction} onActionGridOverlay() - * @property {QAction} onActionFieldGridBox() - * @property {QAction} onActionHideLineTexture() - * @property {QAction} onActionAutoLightTable() - * @property {QAction} onActionGetRightToModifyDrawings() - * @property {QAction} onActionReleaseRightToModifyDrawings() - * @property {QAction} onActionChooseSelectToolOverride() - * @property {QAction} onActionChooseContourEditorToolOverride() - * @property {QAction} onActionChooseCenterlineEditorToolOverride() - * @property {QAction} onActionChooseDeformToolOverride() - * @property {QAction} onActionChoosePerspectiveToolOverride() - * @property {QAction} onActionChooseCutterToolOverride() - * @property {QAction} onActionChooseMorphToolOverride() - * @property {QAction} onActionChooseBrushToolOverride() - * @property {QAction} onActionChooseRepositionAllDrawingsToolOverride() - * @property {QAction} onActionChooseEraserToolOverride() - * @property {QAction} onActionChooseRepaintBrushToolOverride() - * @property {QAction} onActionChoosePencilToolOverride() - * @property {QAction} onActionChooseLineToolOverride() - * @property {QAction} onActionChoosePolylineToolOverride() - * @property {QAction} onActionChooseRectangleToolOverride() - * @property {QAction} onActionChooseEllipseToolOverride() - * @property {QAction} onActionChoosePaintToolOverride() - * @property {QAction} onActionChooseInkToolOverride() - * @property {QAction} onActionChoosePaintUnpaintedToolOverride() - * @property {QAction} onActionChooseRepaintToolOverride() - * @property {QAction} onActionChooseStrokeToolOverride() - * @property {QAction} onActionChooseCloseGapToolOverride() - * @property {QAction} onActionChooseUnpaintToolOverride() - * @property {QAction} onActionChooseDropperToolOverride() - * @property {QAction} onActionChooseEditTransformToolOverride() - * @property {QAction} onActionChooseGrabberToolOverride() - * @property {QAction} onActionChooseZoomToolOverride() - * @property {QAction} onActionChooseRotateToolOverride() - * @property {QAction} onActionChooseThirdPersonNavigation3dToolOverride() - * @property {QAction} onActionChooseFirstPersonNavigation3dToolOverride() - * @property {QAction} onActionChooseShiftAndTraceToolOverride() - * @property {QAction} onActionChooseNoToolOverride() - * @property {QAction} onActionChooseResizePenStyleToolOverride() - * @property {QAction} onActionZoomIn() - * @property {QAction} onActionZoomOut() - * @property {QAction} onActionRotateCW() - * @property {QAction} onActionRotateCCW() - * @property {QAction} onActionToggleQuickCloseUp() - * @property {QAction} onActionResetZoom() - * @property {QAction} onActionResetRotation() - * @property {QAction} onActionResetPan() - * @property {QAction} onActionResetView() - * @property {QAction} onActionRecenter() - * @property {QAction} onActionMorphSwitchKeyDrawing() - * @property {QAction} onActionShowPaletteManager() - * @property {QAction} onActionShowColorEditor() - * @property {QAction} onActionShowColorPicker() - * @property {QAction} onActionShowColorModel() - * @property {QAction} onActionShowThumbnailPanel() - * @property {QAction} onActionPlayByFrame() - * @property {QAction} onActionPreviousDrawing() - * @property {QAction} onActionNextDrawing() - * @property {QAction} onActionPreviousColumn() - * @property {QAction} onActionNextColumn() - * @property {QAction} onActionCreateEmptyDrawing() - * @property {QAction} onActionDuplicateDrawing() - * @property {QAction} onActionShowScanInfo() - * @property {QAction} onActionSetThumbnailSize(int) - * @property {QAction} onActionSelectedElementSwapToNextDrawing() - * @property {QAction} onActionSelectedElementSwapToPrevDrawing() - * @property {QAction} onActionToggleShiftAndTracePegView() - * @property {QAction} onActionToggleShiftAndTraceManipulator() - * @property {QAction} onActionShowMorphingInspector() - * @property {QAction} onActionRemoveFromDrawingList() - * @property {QAction} onActionResetDrawingPosition() - * @property {QAction} onActionToggleDrawingOnPeg() - * @property {QAction} onActionToggleDrawingOnPeg(VL_DrawingListWidget*) - * @property {QAction} onActionToggleDrawingVisibility() - * @property {QAction} onActionToggleDrawingVisibility(VL_DrawingListWidget*) - * @property {QAction} onActionMoveDrawingUp() - * @property {QAction} onActionMoveDrawingDown() - * @property {QAction} onActionReturnToNormalMode() - * @property {QAction} onActionLinkSelectedDrawings() - * @property {QAction} onActionMainGotoNextFrame() - * @property {QAction} onActionMainGotoPreviousFrame() - * @property {QAction} onActionMainGotoFirstFrame() - * @property {QAction} onActionMainGotoLastFrame() - * @property {QAction} onActionRenameDrawing() - * @property {QAction} onActionRenameDrawingWithPrefix() - * @property {QAction} onActionNaviSelectChild() - * @property {QAction} onActionNaviSelectChilds() - * @property {QAction} onActionInsertControlPoint() - * @property {QAction} onActionSelectControlPoint() - * @property {QAction} onActionNaviSelectNextBrother() - * @property {QAction} onActionNaviSelectParent() - * @property {QAction} onActionNaviSelectPreviousBrother() - * @property {QAction} onActionNaviSelectParentWithEffects() - * @property {QAction} onActionNaviSelectChildWithEffects() - * @property {QAction} onActionAutoLightTable() - * @property {QAction} onActionSetSmallFilesResolution() - * @property {QAction} onActionInvalidateCanvas() - * @property {QAction} onActionChooseSpSelectToolOverride() - * @property {QAction} onActionChooseSpTranslateToolOverride() - * @property {QAction} onActionChooseSpRotateToolOverride() - * @property {QAction} onActionChooseSpScaleToolOverride() - * @property {QAction} onActionChooseSpSkewToolOverride() - * @property {QAction} onActionChooseSpMaintainSizeToolOverride() - * @property {QAction} onActionChooseSpTransformToolOverride() - * @property {QAction} onActionChooseSpInverseKinematicsToolOverride() - * @property {QAction} onActionChooseSpOffsetZToolOverride() - * @property {QAction} onActionChooseSpSplineOffsetToolOverride() - * @property {QAction} onActionChooseSpSmoothEditingToolOverride() - * @property {QAction} onActionUnlockAll() - * @property {QAction} onActionUnlock() - * @property {QAction} onActionLockAll() - * @property {QAction} onActionLockAllOthers() - * @property {QAction} onActionLock() - * @property {QAction} onActionTag() - * @property {QAction} onActionUntag() - * @property {QAction} onActionToggleCameraCone() - * @property {QAction} onActionToggleCameraMask() - * @property {QAction} onActionTogglePreventFromDrawing() - * @property {QAction} onActionFocusOnSelectionCV() - * @property {QAction} onActionTogglePlayback() - * @property {QAction} onActionOnionOnSelection() - * @property {QAction} onActionOnionOffSelection() - * @property {QAction} onActionOnionOffAllOther() - * @property {QAction} onActionOnionOnAll() - * @property {QAction} onActionOnionOffAll() - * @property {QAction} onActionOpenGLView() - * @property {QAction} onActionRenderView() - * @property {QAction} onActionMatteView() - * @property {QAction} onActionDepthView() - * @property {QAction} onActionNodeCacheEnable() - * @property {QAction} onActionNodeCacheQuality() - * @property {QAction} onActionNodeCacheHide() - * @property {QAction} onActionNodeCacheDisable() - * @property {QAction} onActionMorphSwitchKeyDrawing() - * @property {QAction} onActionRender() - * @property {QAction} onActionAutoRender() - * @property {QAction} onActionEnterSymbol() - * @property {QAction} onActionLeaveSymbol() - */ - -/** - * Actions available in the colorOperationsResponder responder. - * @name actions#colorOperationsResponder - * @property {QAction} onActionRepaintColorInDrawing() - */ - -/** - * Actions available in the coordControlView responder. - * @name actions#coordControlView - */ - -/** - * Actions available in the drawingSelectionResponder responder. - * @name actions#drawingSelectionResponder - */ - -/** - * Actions available in the drawingView responder. - * @name actions#drawingView - * @property {QAction} onActionRenameDrawing() - * @property {QAction} onActionRenameDrawingWithPrefix() - * @property {QAction} onActionDeleteDrawings() - * @property {QAction} onActionToggleShowSymbolPivot() - * @property {QAction} onActionShowGrid() - * @property {QAction} onActionNormalGrid() - * @property {QAction} onAction12FieldGrid() - * @property {QAction} onAction16FieldGrid() - * @property {QAction} onActionWorldGrid() - * @property {QAction} onActionGridUnderlay() - * @property {QAction} onActionGridOverlay() - * @property {QAction} onActionFieldGridBox() - * @property {QAction} onActionHideLineTexture() - * @property {QAction} onActionAutoLightTable() - * @property {QAction} onActionGetRightToModifyDrawings() - * @property {QAction} onActionReleaseRightToModifyDrawings() - * @property {QAction} onActionChooseSelectToolOverride() - * @property {QAction} onActionChooseContourEditorToolOverride() - * @property {QAction} onActionChooseCenterlineEditorToolOverride() - * @property {QAction} onActionChooseDeformToolOverride() - * @property {QAction} onActionChoosePerspectiveToolOverride() - * @property {QAction} onActionChooseCutterToolOverride() - * @property {QAction} onActionChooseMorphToolOverride() - * @property {QAction} onActionChooseBrushToolOverride() - * @property {QAction} onActionChooseRepositionAllDrawingsToolOverride() - * @property {QAction} onActionChooseEraserToolOverride() - * @property {QAction} onActionChooseRepaintBrushToolOverride() - * @property {QAction} onActionChoosePencilToolOverride() - * @property {QAction} onActionChooseLineToolOverride() - * @property {QAction} onActionChoosePolylineToolOverride() - * @property {QAction} onActionChooseRectangleToolOverride() - * @property {QAction} onActionChooseEllipseToolOverride() - * @property {QAction} onActionChoosePaintToolOverride() - * @property {QAction} onActionChooseInkToolOverride() - * @property {QAction} onActionChoosePaintUnpaintedToolOverride() - * @property {QAction} onActionChooseRepaintToolOverride() - * @property {QAction} onActionChooseStrokeToolOverride() - * @property {QAction} onActionChooseCloseGapToolOverride() - * @property {QAction} onActionChooseUnpaintToolOverride() - * @property {QAction} onActionChooseDropperToolOverride() - * @property {QAction} onActionChooseEditTransformToolOverride() - * @property {QAction} onActionChooseGrabberToolOverride() - * @property {QAction} onActionChooseZoomToolOverride() - * @property {QAction} onActionChooseRotateToolOverride() - * @property {QAction} onActionChooseThirdPersonNavigation3dToolOverride() - * @property {QAction} onActionChooseFirstPersonNavigation3dToolOverride() - * @property {QAction} onActionChooseShiftAndTraceToolOverride() - * @property {QAction} onActionChooseNoToolOverride() - * @property {QAction} onActionChooseResizePenStyleToolOverride() - * @property {QAction} onActionZoomIn() - * @property {QAction} onActionZoomOut() - * @property {QAction} onActionRotateCW() - * @property {QAction} onActionRotateCCW() - * @property {QAction} onActionToggleQuickCloseUp() - * @property {QAction} onActionResetZoom() - * @property {QAction} onActionResetRotation() - * @property {QAction} onActionResetPan() - * @property {QAction} onActionResetView() - * @property {QAction} onActionRecenter() - * @property {QAction} onActionMorphSwitchKeyDrawing() - * @property {QAction} onActionShowPaletteManager() - * @property {QAction} onActionShowColorEditor() - * @property {QAction} onActionShowColorPicker() - * @property {QAction} onActionShowColorModel() - * @property {QAction} onActionShowThumbnailPanel() - * @property {QAction} onActionPlayByFrame() - * @property {QAction} onActionPreviousDrawing() - * @property {QAction} onActionNextDrawing() - * @property {QAction} onActionPreviousColumn() - * @property {QAction} onActionNextColumn() - * @property {QAction} onActionCreateEmptyDrawing() - * @property {QAction} onActionDuplicateDrawing() - * @property {QAction} onActionShowScanInfo() - * @property {QAction} onActionSetThumbnailSize(int) - * @property {QAction} onActionSelectedElementSwapToNextDrawing() - * @property {QAction} onActionSelectedElementSwapToPrevDrawing() - * @property {QAction} onActionToggleShiftAndTracePegView() - * @property {QAction} onActionToggleShiftAndTraceManipulator() - * @property {QAction} onActionShowMorphingInspector() - * @property {QAction} onActionRemoveFromDrawingList() - * @property {QAction} onActionResetDrawingPosition() - * @property {QAction} onActionToggleDrawingOnPeg() - * @property {QAction} onActionToggleDrawingOnPeg(VL_DrawingListWidget*) - * @property {QAction} onActionToggleDrawingVisibility() - * @property {QAction} onActionToggleDrawingVisibility(VL_DrawingListWidget*) - * @property {QAction} onActionMoveDrawingUp() - * @property {QAction} onActionMoveDrawingDown() - * @property {QAction} onActionReturnToNormalMode() - * @property {QAction} onActionLinkSelectedDrawings() - */ - -/** - * Actions available in the exportCoreResponder responder. - * @name actions#exportCoreResponder - * @property {QAction} onActionGenerateLayoutImage() - */ - -/** - * Actions available in the graph3dresponder responder. - * @name actions#graph3dresponder - * @property {QAction} onActionShowSubnodeShape() - * @property {QAction} onActionHideSubnodeShape() - * @property {QAction} onActionEnableSubnode() - * @property {QAction} onActionDisableSubnode() - * @property {QAction} onActionCreateSubNodeTransformation() - * @property {QAction} onActionAddSubTransformationFilter() - * @property {QAction} onActionSelectParent() - * @property {QAction} onActionSelectChild() - * @property {QAction} onActionSelectNextSibling() - * @property {QAction} onActionSelectPreviousSibling() - * @property {QAction} onActionDumpSceneGraphInformation() - */ - -/** - * Actions available in the ikResponder responder. - * @name actions#ikResponder - * @property {QAction} onActionSetIKNail() - * @property {QAction} onActionSetIKHoldOrientation() - * @property {QAction} onActionSetIKHoldX() - * @property {QAction} onActionSetIKHoldY() - * @property {QAction} onActionSetIKMinAngle() - * @property {QAction} onActionSetIKMaxAngle() - * @property {QAction} onActionRemoveAllConstraints() - */ - -/** - * Actions available in the libraryView responder. - * @name actions#libraryView - */ - -/** - * Actions available in the logView responder. - * @name actions#logView - */ - -/** - * Actions available in the miniPegModuleResponder responder. - * @name actions#miniPegModuleResponder - * @property {QAction} onActionResetDeform() - * @property {QAction} onActionCopyRestingPositionToCurrentPosition() - * @property {QAction} onActionConvertEllipseToShape() - * @property {QAction} onActionSelectRigTool() - * @property {QAction} onActionInsertDeformationAbove() - * @property {QAction} onActionInsertDeformationUnder() - * @property {QAction} onActionToggleEnableDeformation() - * @property {QAction} onActionToggleShowAllManipulators() - * @property {QAction} onActionToggleShowAllROI() - * @property {QAction} onActionToggleShowSimpleManipulators() - * @property {QAction} onActionConvertSelectionToCurve() - * @property {QAction} onActionStraightenSelection() - * @property {QAction} onActionShowSelectedDeformers() - * @property {QAction} onActionShowDeformer(QString) - * @property {QAction} onActionHideDeformer(QString) - * @property {QAction} onActionCreateKinematicOutput() - * @property {QAction} onActionConvertDeformedDrawingsToDrawings() - * @property {QAction} onActionConvertDeformedDrawingsAndCreateDeformation() - * @property {QAction} onActionUnsetLocalFlag() - * @property {QAction} onActionCopyCurvePositionToOffset() - * @property {QAction} onActionAddDeformationModuleByName(QString) - * @property {QAction} onActionCreateNewDeformationChain() - * @property {QAction} onActionRenameTransformation() - * @property {QAction} onActionSetTransformation() - * @property {QAction} onActionSetMasterElementModule() - * @property {QAction} onActionToggleShowManipulator() - */ - -/** - * Actions available in the moduleLibraryView responder. - * @name actions#moduleLibraryView - * @property {QAction} onActionReceiveFocus() - * @property {QAction} onActionNewCategory() - * @property {QAction} onActionRenameCategory() - * @property {QAction} onActionRemoveCategory() - * @property {QAction} onActionRemoveUserModule() - * @property {QAction} onActionRefresh() - */ - -/** - * Actions available in the moduleResponder responder. - * @name actions#moduleResponder - * @property {QAction} onActionAddModuleByName(QString) - * @property {QAction} onActionAddModule(int,int) - */ - -/** - * Actions available in the onionSkinResponder responder. - * @name actions#onionSkinResponder - * @property {QAction} onActionOnionSkinToggle() - * @property {QAction} onActionOnionSkinToggleCenterline() - * @property {QAction} onActionOnionSkinToggleFramesToDrawingsMode() - * @property {QAction} onActionOnionSkinNoPrevDrawings() - * @property {QAction} onActionOnionSkin1PrevDrawing() - * @property {QAction} onActionOnionSkin2PrevDrawings() - * @property {QAction} onActionOnionSkin3PrevDrawings() - * @property {QAction} onActionOnionSkinNoNextDrawings() - * @property {QAction} onActionOnionSkin1NextDrawing() - * @property {QAction} onActionOnionSkin2NextDrawings() - * @property {QAction} onActionOnionSkin3NextDrawings() - * @property {QAction} onActionSetMarksOnionSkinInBetween() - * @property {QAction} onActionSetMarksOnionSkinInBreakdown() - * @property {QAction} onActionSetMarksOnionSkinInKey() - * @property {QAction} onActionSetDrawingEnhancedOnionSkin() - * @property {QAction} onActionOnionSkinReduceNextDrawing() - * @property {QAction} onActionOnionSkinAddNextDrawing() - * @property {QAction} onActionOnionSkinReducePrevDrawing() - * @property {QAction} onActionOnionSkinAddPrevDrawing() - * @property {QAction} onActionToggleOnionSkinForCustomMarkedType(QString) - * @property {QAction} onActionOnionSkinSelectedLayerOnly() - * @property {QAction} onActionOnionSkinRenderStyle(int) - * @property {QAction} onActionOnionSkinDrawingMode(int) - * @property {QAction} onActionOnionSkinToggleBaseMode() - * @property {QAction} onActionOnionSkinToggleAdvancedMode() - * @property {QAction} onActionOnionSkinToggleColorWash() - * @property {QAction} onActionOnionSkinLinkSliders() - * @property {QAction} onActionOnionSkinToggleAdvancedNext(int) - * @property {QAction} onActionOnionSkinToggleAdvancedPrev(int) - * @property {QAction} onActionOnionSkinAdvancedNextSliderChanged(int,int) - * @property {QAction} onActionOnionSkinAdvancedPrevSliderChanged(int,int) - * @property {QAction} onActionMaxOpacitySliderChanged(int) - */ - -/** - * Actions available in the onionSkinView responder. - * @name actions#onionSkinView - */ - -/** - * Actions available in the opacityPanel responder. - * @name actions#opacityPanel - * @property {QAction} onActionNewOpacityTexture() - * @property {QAction} onActionDeleteOpacityTexture() - * @property {QAction} onActionRenameOpacityTexture() - * @property {QAction} onActionCurToPrefPalette() - * @property {QAction} onActionPrefToCurPalette() - */ - -/** - * Actions available in the paletteView responder. - * @name actions#paletteView - */ - -/** - * Actions available in the pencilPanel responder. - * @name actions#pencilPanel - * @property {QAction} onActionNewPencilTemplate() - * @property {QAction} onActionDeletePencilTemplate() - * @property {QAction} onActionRenamePencilTemplate() - * @property {QAction} onActionShowSmallThumbnail() - * @property {QAction} onActionShowLargeThumbnail() - * @property {QAction} onActionShowStroke() - */ - -/** - * Actions available in the scene responder. - * @name actions#scene - * @property {QAction} onActionHideSelection() - * @property {QAction} onActionShowHidden() - * @property {QAction} onActionRehideSelection() - * @property {QAction} onActionInsertPositionKeyframe() - * @property {QAction} onActionInsertKeyframe() - * @property {QAction} onActionSetKeyFrames() - * @property {QAction} onActionInsertControlPointAtFrame() - * @property {QAction} onActionSetConstant() - * @property {QAction} onActionSetNonConstant() - * @property {QAction} onActionToggleContinuity() - * @property {QAction} onActionToggleLockInTime() - * @property {QAction} onActionResetTransformation() - * @property {QAction} onActionResetAll() - * @property {QAction} onActionResetAllExceptZ() - * @property {QAction} onActionSelectPrevObject() - * @property {QAction} onActionSelectNextObject() - * @property {QAction} onActionToggleNoFBDragging() - * @property {QAction} onActionToggleAutoApply() - * @property {QAction} onActionToggleAutoLock() - * @property {QAction} onActionToggleAutoLockPalettes() - * @property {QAction} onActionToggleAutoLockPaletteLists() - * @property {QAction} onActionToggleEnableWrite() - * @property {QAction} onActionShowHideManager() - * @property {QAction} onActionToggleControl() - * @property {QAction} onActionHideAllControls() - * @property {QAction} onActionPreviousDrawing() - * @property {QAction} onActionNextDrawing() - * @property {QAction} onActionPreviousColumn() - * @property {QAction} onActionNextColumn() - * @property {QAction} onActionShowSubNode(bool) - * @property {QAction} onActionGotoDrawing1() - * @property {QAction} onActionGotoDrawing2() - * @property {QAction} onActionGotoDrawing3() - * @property {QAction} onActionGotoDrawing4() - * @property {QAction} onActionGotoDrawing5() - * @property {QAction} onActionGotoDrawing6() - * @property {QAction} onActionGotoDrawing7() - * @property {QAction} onActionGotoDrawing8() - * @property {QAction} onActionGotoDrawing9() - * @property {QAction} onActionGotoDrawing10() - * @property {QAction} onActionToggleVelocityEditor() - * @property {QAction} onActionCreateScene() - * @property {QAction} onActionChooseSelectToolInNormalMode() - * @property {QAction} onActionChooseSelectToolInColorMode() - * @property {QAction} onActionChoosePaintToolInPaintMode() - * @property {QAction} onActionChooseInkTool() - * @property {QAction} onActionChoosePaintToolInRepaintMode() - * @property {QAction} onActionChoosePaintToolInUnpaintMode() - * @property {QAction} onActionChoosePaintToolInPaintUnpaintedMode() - * @property {QAction} onActionChooseBrushToolInBrushMode() - * @property {QAction} onActionChooseBrushToolInRepaintBrushMode() - * @property {QAction} onActionToggleDrawBehindMode() - * @property {QAction} onActionWhatsThis() - * @property {QAction} onActionEditProperties() - */ - -/** - * Actions available in the sceneUI responder. - * @name actions#sceneUI - * @property {QAction} onActionSaveLayouts() - * @property {QAction} onActionSaveWorkspaceAs() - * @property {QAction} onActionShowLayoutManager() - * @property {QAction} onActionFullscreen() - * @property {QAction} onActionRaiseArea(QString,bool) - * @property {QAction} onActionRaiseArea(QString) - * @property {QAction} onActionSetLayout(QString,int) - * @property {QAction} onActionLockScene() - * @property {QAction} onActionLockSceneVersion() - * @property {QAction} onActionPaintModePaletteManager() - * @property {QAction} onActionPaintModeLogView() - * @property {QAction} onActionPaintModeModelView() - * @property {QAction} onActionPaintModeToolPropertiesView() - * @property {QAction} onActionUndo() - * @property {QAction} onActionUndo(int) - * @property {QAction} onActionRedo() - * @property {QAction} onActionRedo(int) - * @property {QAction} onActionShowCurrentDrawingOnTop() - * @property {QAction} onActionShowWelcomeScreen() - * @property {QAction} onActionShowWelcomeScreenQuit() - * @property {QAction} onActionSaveLayoutInScene() - * @property {QAction} onActionNewView(int) - * @property {QAction} onActionNewView(QString) - * @property {QAction} onActionNewViewChecked(QString) - * @property {QAction} onActionToggleRenderer() - * @property {QAction} onActionToggleBBoxHighlighting() - * @property {QAction} onActionToggleShowLockedDrawingsInOutline() - * @property {QAction} onActionCancelSoftRender() - * @property {QAction} onActionCheckFiles() - * @property {QAction} onActionCleanPaletteLists() - * @property {QAction} onActionDeleteVersions() - * @property {QAction} onActionMacroManager() - * @property {QAction} onActionRestoreDefaultLayout() - * @property {QAction} onActionExit() - * @property {QAction} onActionExitDelayed() - * @property {QAction} onActionAddVectorDrawing() - * @property {QAction} onActionAddSound() - * @property {QAction} onActionAddPeg() - * @property {QAction} onActionToggleShowMergeSelectionDialog() - * @property {QAction} onActionToggleShowScanDialog() - * @property {QAction} onActionSetPreviewResolution(int) - * @property {QAction} onActionSetTempoMarker() - * @property {QAction} onActionSingleFlip() - * @property {QAction} onActionNewScene() - * @property {QAction} onActionNewSceneDelayed() - * @property {QAction} onActionOpen() - * @property {QAction} onActionOpenDelayed() - * @property {QAction} onActionOpenScene() - * @property {QAction} onActionOpenSceneDelayed() - * @property {QAction} onActionOpenScene(QString) - * @property {QAction} onActionSaveEverything() - * @property {QAction} onActionSaveEverythingIncludingSceneMachineFrames() - * @property {QAction} onActionSaveAsScene() - * @property {QAction} onActionSaveVersion() - * @property {QAction} onActionSaveDialog() - * @property {QAction} onActionImportDrawings() - * @property {QAction} onActionImport3dmodels() - * @property {QAction} onActionImportTimings() - * @property {QAction} onActionScanDrawings() - * @property {QAction} onActionImportLocalLibrary() - * @property {QAction} onActionImportSound() - * @property {QAction} onActionMmxImport() - * @property {QAction} onActionFlashExport() - * @property {QAction} onActionFLVExport() - * @property {QAction} onActionMmxExport() - * @property {QAction} onActionSoundtrackExport() - * @property {QAction} onActionComposite() - * @property {QAction} onActionCompositeBatchOnly() - * @property {QAction} onActionSaveOpenGLFrames() - * @property {QAction} onActionToggleFlipForCustomMarkedType(QString) - * @property {QAction} onActionCreateFullImport() - * @property {QAction} onActionPerformFullImport() - * @property {QAction} onActionPerformPartialImport() - * @property {QAction} onActionPerformPartialUpdate() - * @property {QAction} onActionToggleToolBar(QString) - * @property {QAction} onActionSetDefaultDisplay(QString) - * @property {QAction} onActionCloseScene() - * @property {QAction} onActionCloseSceneDelayed() - * @property {QAction} onActionCloseThenReopen() - * @property {QAction} onActionOpenDrawings() - * @property {QAction} onActionOpenDrawingsDelayed() - * @property {QAction} onActionOpenDrawingsModify() - * @property {QAction} onActionOpenElements() - * @property {QAction} onActionOpenElementsDelayed() - * @property {QAction} onActionClearRecentSceneList() - * @property {QAction} onActionOpenBackgroundFile() - * @property {QAction} onActionUnloadBackground() - * @property {QAction} onActionScaleBackgroundUp() - * @property {QAction} onActionScaleBackgroundDown() - * @property {QAction} onActionResetBackgroundPosition() - * @property {QAction} onActionSetDrawingMarksFlipKey() - * @property {QAction} onActionSetDrawingMarksFlipBreakdown() - * @property {QAction} onActionSetDrawingMarksFlipInBetween() - * @property {QAction} onActionChooseSelectTool() - * @property {QAction} onActionChooseContourEditorTool() - * @property {QAction} onActionChooseCenterlineEditorTool() - * @property {QAction} onActionChooseDeformTool() - * @property {QAction} onActionChoosePerspectiveTool() - * @property {QAction} onActionChooseEnvelopeTool() - * @property {QAction} onActionChooseCutterTool() - * @property {QAction} onActionChooseMorphTool() - * @property {QAction} onActionChoosePivotTool() - * @property {QAction} onActionChooseBrushTool() - * @property {QAction} onActionChooseRepositionAllDrawingsTool() - * @property {QAction} onActionChooseEraserTool() - * @property {QAction} onActionChooseRepaintBrushTool() - * @property {QAction} onActionChoosePencilTool() - * @property {QAction} onActionChoosePencilEditorTool() - * @property {QAction} onActionChooseLineTool() - * @property {QAction} onActionChoosePolylineTool() - * @property {QAction} onActionChooseRectangleTool() - * @property {QAction} onActionChooseEllipseTool() - * @property {QAction} onActionChoosePaintTool() - * @property {QAction} onActionChooseInkTool() - * @property {QAction} onActionChoosePaintUnpaintedTool() - * @property {QAction} onActionChooseRepaintTool() - * @property {QAction} onActionChooseStampTool() - * @property {QAction} onActionChooseStrokeTool() - * @property {QAction} onActionChooseCloseGapTool() - * @property {QAction} onActionChooseUnpaintTool() - * @property {QAction} onActionChooseDropperTool() - * @property {QAction} onActionChooseEditTransformTool() - * @property {QAction} onActionChooseGrabberTool() - * @property {QAction} onActionChooseZoomTool() - * @property {QAction} onActionChooseRotateTool() - * @property {QAction} onActionChooseThirdPersonNavigation3dTool() - * @property {QAction} onActionChooseFirstPersonNavigation3dTool() - * @property {QAction} onActionChooseShiftAndTraceTool() - * @property {QAction} onActionChooseNoTool() - * @property {QAction} onActionChooseResizePenStyleTool() - * @property {QAction} onActionChooseSpSelectTool() - * @property {QAction} onActionChooseSpTranslateTool() - * @property {QAction} onActionChooseSpRotateTool() - * @property {QAction} onActionChooseSpScaleTool() - * @property {QAction} onActionChooseSpSkewTool() - * @property {QAction} onActionChooseSpMaintainSizeTool() - * @property {QAction} onActionChooseSpTransformTool() - * @property {QAction} onActionChooseSpInverseKinematicsTool() - * @property {QAction} onActionChooseSpOffsetZTool() - * @property {QAction} onActionChooseSpSplineOffsetTool() - * @property {QAction} onActionChooseSpSmoothEditingTool() - * @property {QAction} onActionChooseMoveBackgroundTool() - * @property {QAction} onActionChooseTextTool() - * @property {QAction} onActionActivatePreset(int) - * @property {QAction} onActionToggleKeyframeMode() - * @property {QAction} onActionAnimatedKeyframeMode() - * @property {QAction} onActionAnimatedOnRangeKeyframeMode() - * @property {QAction} onActionStaticKeyframeMode() - * @property {QAction} onActionSetKeyframeMode() - * @property {QAction} onActionSetAllKeyframesMode() - * @property {QAction} onActionSetConstantSegMode() - * @property {QAction} onActionMainPlay() - * @property {QAction} onActionMainPlayFw() - * @property {QAction} onActionMainPlayBw() - * @property {QAction} onActionMainPlayPreviewFw() - * @property {QAction} onActionMainPlayPreviewSwf() - * @property {QAction} onActionMainStopPlaying() - * @property {QAction} onActionMainToggleLoopPlay() - * @property {QAction} onActionMainToggleEnableCacheForPlay() - * @property {QAction} onActionMainToggleEnableSoundForPlay() - * @property {QAction} onActionMainToggleEnableSoundScrubbing() - * @property {QAction} onActionChooseSpRepositionTool() - * @property {QAction} onActionMainSetPlaybackStartFrame() - * @property {QAction} onActionMainSetPlaybackStopFrame() - * @property {QAction} onActionMainGotoFrame() - * @property {QAction} onActionMainSetPlaybackSpeed() - * @property {QAction} onActionMainGotoFirstFrame() - * @property {QAction} onActionMainGotoPreviousFrame() - * @property {QAction} onActionMainGotoLastFrame() - * @property {QAction} onActionMainGotoNextFrame() - * @property {QAction} onActionToggleSideViewPlayback() - * @property {QAction} onActionToggleTopViewPlayback() - * @property {QAction} onActionTogglePersViewPlayback() - * @property {QAction} onActionReshapeMultipleKeyframes() - * @property {QAction} onActionJogForward() - * @property {QAction} onActionJogBackward() - * @property {QAction} onActionShuttleForward() - * @property {QAction} onActionShuttleBackward() - * @property {QAction} onActionShuttleReset() - * @property {QAction} onActionConformationImport() - * @property {QAction} onActionShowPreferenceDialog() - * @property {QAction} onActionShowShortcutsDialog() - * @property {QAction} onActionManageLocalCaches() - * @property {QAction} onActionReadChangedDrawings() - * @property {QAction} onActionReadChangedDrawingsNoWarning() - * @property {QAction} onActionPaletteOperations() - * @property {QAction} onActionToggleDebugMode() - * @property {QAction} onActionHelp() - * @property {QAction} onActionHtmlHelp(QString) - * @property {QAction} onActionOpenBook(QString) - * @property {QAction} onActionAbout() - * @property {QAction} onActionCEIP() - * @property {QAction} onActionShowLicense() - * @property {QAction} onActionShowReadme() - * @property {QAction} onActionOpenURL(QString,int) - * @property {QAction} onActionOpenURL(QString) - * @property {QAction} onActionTerminate() - * @property {QAction} onActionToggleGoogleAnalytics() - */ - -/** - * Actions available in the scriptResponder responder. - * @name actions#scriptResponder - * @property {QAction} onActionExecuteScript(QString) - * @property {QAction} onActionExecuteScriptWithValidator(QString,AC_ActionInfo*) - * @property {QAction} onActionActivateTool(int) - * @property {QAction} onActionActivateToolByName(QString) - */ - -/** - * Actions available in the selectionResponder responder. - * @name actions#selectionResponder - */ - -/** - * Actions available in the sessionResponder responder. - * @name actions#sessionResponder - * @property {QAction} onActionFixSymbolCompositeAndDisplay() - */ - -/** - * Actions available in the timelineView responder. - * @name actions#timelineView - * @property {QAction} onActionPropagateLayerSelection() - */ - -/** - * Actions available in the toolProperties responder. - * @name actions#toolProperties - * @property {QAction} onActionNewBrush() - * @property {QAction} onActionDeleteBrush() - * @property {QAction} onActionRenameBrush() - * @property {QAction} onActionEditBrush() - * @property {QAction} onActionImportBrushes() - * @property {QAction} onActionExportBrushes() - * @property {QAction} onActionShowSmallThumbnail() - * @property {QAction} onActionShowLargeThumbnail() - * @property {QAction} onActionShowStroke() - */ - -/** - * Actions available in the toolPropertiesView responder. - * @name actions#toolPropertiesView - */ - -/** - * Actions available in the xsheetView responder. - * @name actions#xsheetView - * @property {QAction} onActionPrintXsheet() - * @property {QAction} onActionResetCellsSize() - * @property {QAction} onActionZoomIn() - * @property {QAction} onActionZoomOut() - * @property {QAction} onActionZoomExtents() - * @property {QAction} onActionResetZoom() - * @property {QAction} onActionResetPan() - * @property {QAction} onActionResetView() - * @property {QAction} onActionShowUnhideObjectsEditor() - * @property {QAction} onActionUnhideAllColumns() - * @property {QAction} onActionXsheetHoldValueMenu(int) - * @property {QAction} onActionSendToFunctionView() - * @property {QAction} onActionToggleShowGrouping() - * @property {QAction} onActionToggleMinimalHeaders() - * @property {QAction} onActionDisplayShowDlg() - * @property {QAction} onActionToggleInsertMode() - * @property {QAction} onActionToggleGesturalDrag() - * @property {QAction} onActionToggleThumbnails() - * @property {QAction} onActionToggleIsShowDrawingCols() - * @property {QAction} onActionToggleIsShowFunctionCols() - * @property {QAction} onActionToggleIsShowPath3dCols() - * @property {QAction} onActionToggleIsShow3dRotationCols() - * @property {QAction} onActionToggleIsShowSoundCols() - * @property {QAction} onActionToggleSidePanel() - * @property {QAction} onActionXsheetHeldFramesLine(int) - * @property {QAction} onActionXsheetEmptyCellsX(int) - * @property {QAction} onActionXsheetLabelsFrames(int) - * @property {QAction} onActionSelectedElementSwapToNextDrawing() - * @property {QAction} onActionSelectedElementSwapToPrevDrawing() - * @property {QAction} onActionToggleSelection() - * @property {QAction} onActionTag() - * @property {QAction} onActionUntag() - * @property {QAction} onActionUntagAllOthers() - * @property {QAction} onActionTagPublic() - * @property {QAction} onActionUntagPublic() - * @property {QAction} onActionUntagPublicAllOthers() - */ \ No newline at end of file diff --git a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_application.js b/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_application.js deleted file mode 100644 index 5809cee694..0000000000 --- a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_application.js +++ /dev/null @@ -1,477 +0,0 @@ -////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// -// -// openHarmony Library -// -// -// Developed by Mathieu Chaptel, Chris Fourney -// -// -// This library is an open source implementation of a Document Object Model -// for Toonboom Harmony. It also implements patterns similar to JQuery -// for traversing this DOM. -// -// Its intended purpose is to simplify and streamline toonboom scripting to -// empower users and be easy on newcomers, with default parameters values, -// and by hiding the heavy lifting required by the official API. -// -// This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is guaranteed to work. Feel free to contribute -// improvements to its official github. If you do make sure you follow the provided -// template and naming conventions and document your new methods properly. -// -// This library doesn't overwrite any of the objects and classes of the official -// Toonboom API which must remains available. -// -// This library is made available under the Mozilla Public license 2.0. -// https://www.mozilla.org/en-US/MPL/2.0/ -// -// The repository for this library is available at the address: -// https://github.com/cfourney/OpenHarmony/ -// -// -// For any requests feel free to contact m.chaptel@gmail.com -// -// -// -// -////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// - - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oApp class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - -/** - * The constructor for the $.oApp class - * @classdesc - * The $.oApp class provides access to the Harmony application and its widgets. - * @constructor - */ -$.oApp = function(){ -} - - -/** - * The Harmony version number - * @name $.oApp#version - * @type {int} - * @readonly - */ -Object.defineProperty($.oApp.prototype, 'version', { - get : function(){ - return parseInt(about.getVersionInfoStr().split("version").pop().split(".")[0], 10); - } -}); - - -/** - * The software flavour: Premium, Advanced, Essential - * @name $.oApp#flavour - * @type {string} - * @readonly - */ -Object.defineProperty($.oApp.prototype, 'flavour', { - get : function(){ - return about.getFlavorString(); - } -}); - - -/** - * The Harmony Main Window. - * @name $.oApp#mainWindow - * @type {QWidget} - * @readonly - */ -Object.defineProperty($.oApp.prototype, 'mainWindow', { - get : function(){ - var windows = QApplication.topLevelWidgets(); - for ( var i in windows) { - if (windows[i] instanceof QMainWindow && !windows[i].parentWidget()) return windows[i]; - } - return false - } -}); - - -/** - * The Harmony UI Toolbars. - * @name $.oApp#toolbars - * @type {QToolbar} - * @readonly - */ -Object.defineProperty($.oApp.prototype, 'toolbars', { - get : function(){ - var widgets = QApplication.allWidgets(); - var _toolbars = widgets.filter(function(x){return x instanceof QToolBar}) - - return _toolbars - } -}); - - - -/** - * The Position of the mouse cursor in the toonboom window coordinates. - * @name $.oApp#mousePosition - * @type {$.oPoint} - * @readonly - */ -Object.defineProperty($.oApp.prototype, 'mousePosition', { - get : function(){ - var _position = this.$.app.mainWindow.mapFromGlobal(QCursor.pos()); - return new this.$.oPoint(_position.x(), _position.y(), 0); - } -}); - - -/** - * The Position of the mouse cursor in the screen coordinates. - * @name $.oApp#globalMousePosition - * @type {$.oPoint} - * @readonly - */ -Object.defineProperty($.oApp.prototype, 'globalMousePosition', { - get : function(){ - var _position = QCursor.pos(); - return new this.$.oPoint(_position.x(), _position.y(), 0); - } -}); - - -/** - * Access the tools available in the application - * @name $.oApp#tools - * @type {$.oTool[]} - * @readonly - * @example - * // Access the list of currently existing tools by using the $.app object - * var tools = $.app.tools; - * - * // output the list of tools names and ids - * for (var i in tools){ - * log(i+" "+tools[i].name) - * } - * - * // To get a tool by name, use the $.app.getToolByName() function - * var brushTool = $.app.getToolByName("Brush"); - * log (brushTool.name+" "+brushTool.id) // Output: Brush 9 - * - * // it's also possible to activate a tool in several ways: - * $.app.currentTool = 9; // using the tool "id" - * $.app.currentTool = brushTool // by passing a oTool object - * $.app.currentTool = "Brush" // using the tool name - * - * brushTool.activate() // by using the activate function of the oTool class - */ -Object.defineProperty($.oApp.prototype, 'tools', { - get: function(){ - if (typeof this._toolsObject === 'undefined'){ - this._toolsObject = []; - var _currentTool = this.currentTool; - var i = 0; - Tools.setToolSettings({currentTool:{id:i}}) - while(Tools.getToolSettings().currentTool.name){ - var tool = Tools.getToolSettings().currentTool; - this._toolsObject.push(new this.$.oTool(tool.id,tool.name)); - i++; - Tools.setToolSettings({currentTool:{id:i}}); - } - this.currentTool = _currentTool; - } - return this._toolsObject; - } -}) - - -/** - * The Position of the mouse cursor in the screen coordinates. - * @name $.oApp#currentTool - * @type {$.oTool} - */ -Object.defineProperty($.oApp.prototype, 'currentTool', { - get : function(){ - var _tool = Tools.getToolSettings().currentTool.id; - return _tool; - }, - set : function(tool){ - if (tool instanceof this.$.oTool) { - tool.activate(); - return - } - if (typeof tool == "string"){ - try{ - this.getToolByName(tool).activate(); - return - }catch(err){ - this.$.debug("'"+ tool + "' is not a valid tool name. Valid: "+this.tools.map(function(x){return x.name}).join(", ")) - } - } - if (typeof tool == "number"){ - this.tools[tool].activate(); - return - } - } -}); - - -/** - * Gets access to a widget from the Harmony Interface. - * @param {string} name The name of the widget to look for. - * @param {string} [parentName] The name of the parent widget to look into, in case of duplicates. - * @return {QWidget} The widget if found, or null if it doesn't exist. - */ -$.oApp.prototype.getWidgetByName = function(name, parentName){ - var widgets = QApplication.allWidgets(); - for( var i in widgets){ - if (widgets[i].objectName == name){ - if (typeof parentName !== 'undefined' && (widgets[i].parentWidget().objectName != parentName)) continue; - return widgets[i]; - } - } - return null; -} - - -/** - * Access the Harmony Preferences - * @name $.oApp#preferences - * @example - * // To access the preferences of Harmony, grab the preference object in the $.oApp class: - * var prefs = $.app.preferences; - * - * // It's then possible to access all available preferences of the software: - * for (var i in prefs){ - * log (i+" "+prefs[i]); - * } - * - * // accessing the preference value can be done directly by using the dot notation: - * prefs.USE_OVERLAY_UNDERLAY_ART = true; - * log (prefs.USE_OVERLAY_UNDERLAY_ART); - * - * //the details objects of the preferences object allows access to more information about each preference - * var details = prefs.details - * log(details.USE_OVERLAY_UNDERLAY_ART.category+" "+details.USE_OVERLAY_UNDERLAY_ART.id+" "+details.USE_OVERLAY_UNDERLAY_ART.type); - * - * for (var i in details){ - * log(i+" "+JSON.stringify(details[i])) // each object inside detail is a complete oPreference instance - * } - * - * // the preference object also holds a categories array with the list of all categories - * log (prefs.categories) - */ -Object.defineProperty($.oApp.prototype, 'preferences', { - get: function(){ - if (typeof this._prefsObject === 'undefined'){ - var _prefsObject = {}; - _categories = []; - _details = {}; - - Object.defineProperty(_prefsObject, "categories", { - enumerable:false, - value:_categories - }) - - Object.defineProperty(_prefsObject, "details", { - enumerable:false, - value:_details - }) - - var prefFile = (new oFile(specialFolders.resource+"/prefs.xml")).parseAsXml().children[0].children; - - var userPrefFile = new oFile(specialFolders.userConfig + "/Harmony Premium-pref.xml") - // Harmony Pref file is called differently on the database userConfig - if (!userPrefFile.exists) userPrefFile = new oFile(specialFolders.userConfig + "/Harmony-pref.xml") - - if (userPrefFile.exists){ - var userPref = {objectName: "category", id: "user", children:userPrefFile.parseAsXml().children[0].children}; - prefFile.push(userPref); - } - - for (var i in prefFile){ - if (prefFile[i].objectName != "category" || prefFile[i].id == "Storyboard") continue; - var category = prefFile[i].id; - if (_categories.indexOf(category) == -1) _categories.push(category); - - var preferences = prefFile[i].children; - - // create a oPreference instance for each found preference and add a getter setter to the $.oApp._prefsObject - for (var j in preferences){ - - // evaluate condition for conditional preferences. For now only support Harmony Premium prefs - if (preferences[j].objectName == "if"){ - var condition = preferences[j].condition; - var regex = /(not essentials|not sboard|not paint)/ - if (regex.exec(condition)) preferences = preferences.concat(preferences[j].children) - continue; - } - var type = preferences[j].objectName; - var keyword = preferences[j].id; - var description = preferences[j].shortDesc; - var descriptionText = preferences[j].longDesc; - if (type == "color"){ - if (typeof preferences[j].alpha === 'undefined') preferences[j].alpha = 255; - var value = new ColorRGBA(preferences[j].red, preferences[j].green, preferences[j].blue, preferences[j].alpha) - }else{ - var value = preferences[j].value; - } - // var docString = (category+" "+keyword+" "+type+" "+description) - // - var pref = this.$.oPreference.createPreference(category, keyword, type, value, description, descriptionText, _prefsObject); - _details[pref.keyword] = pref; - } - } - - this._prefsObject = _prefsObject; - } - - return this._prefsObject; - } -}) - - - -/** - * The list of stencils available in the Harmony UI. - * @name $.oApp#stencils - * @type {$.oStencil[]} - * @example - * // Access the stencils list through the $.app object. - * var stencils = $.app.stencils - * - * // list all the properties of stencils - * for (var i in stencils){ - * log(" ---- "+stencils[i].type+" "+stencils[i].name+" ---- ") - * for(var j in stencils[i]){ - * log (j); - * } - * } - */ -Object.defineProperty($.oApp.prototype, 'stencils', { - get: function(){ - if (typeof this._stencilsObject === 'undefined'){ - // parse stencil xml file penstyles.xml to get stencils info - var stencilsFile = (new oFile(specialFolders.userConfig+"/penstyles.xml")).read(); - var penRegex = /([\S\s]*?)<\/pen>/igm - var stencils = []; - var stencilXml; - while(stencilXml = penRegex.exec(stencilsFile)){ - var stencilObject = this.$.oStencil.getFromXml(stencilXml[1]); - stencils.push(stencilObject); - } - this._stencilsObject = stencils; - } - return this._stencilsObject; - } -}) - - - -/** - * The currently selected stencil. Always returns the pencil tool current stencil. - * @name $.oApp#currentStencil - * @type {$.oStencil} - */ -Object.defineProperty($.oApp.prototype, 'currentStencil', { - get: function(){ - return this.stencils[PaletteManager.getCurrentPenstyleIndex()]; - }, - set: function(stencil){ - if (stencil instanceof this.$.oStencil) var stencil = stencil.name - this.$.debug("Setting current pen: "+ stencil) - PenstyleManager.setCurrentPenstyleByName(stencil); - } -}) - - - -// $.oApp Class Methods - -/** - * get a tool by its name - * @return {$.oTool} a oTool object representing the tool, or null if not found. - */ -$.oApp.prototype.getToolByName = function(toolName){ - var _tools = this.tools; - for (var i in _tools){ - if (_tools[i].name.toLowerCase() == toolName.toLowerCase()) return _tools[i]; - } - return null; -} - - -/** - * returns the list of stencils usable by the specified tool - * @param {$.oTool} tool the tool object we want valid stencils for - * @return {$.oStencil[]} the list of stencils compatible with the specified tool - */ -$.oApp.prototype.getValidStencils = function (tool){ - if (typeof tool === 'undefined') var tool = this.currentTool; - return tool.stencils; -} - - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oToolbar class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - -/** - * The $.oToolbar constructor. - * @name $.oToolbar - * @constructor - * @classdesc A toolbar that can contain any type of widgets. - * @param {string} name The name of the toolbar to create. - * @param {QWidget[]} [widgets] The list of widgets to add to the toolbar. - * @param {QWidget} [parent] The parent widget to add the toolbar to. - * @param {bool} [show] Whether to show the toolbar instantly after creation. - */ -$.oToolbar = function( name, widgets, parent, show ){ - if (typeof parent === 'undefined') var parent = $.app.mainWindow; - if (typeof widgets === 'undefined') var widgets = []; - if (typeof show === 'undefined') var show = true; - - this.name = name; - this._widgets = widgets; - this._parent = parent; - - if (show) this.show(); -} - - -/** - * Shows the oToolbar. - * @name $.oToolbar#show - */ -$.oToolbar.prototype.show = function(){ - if (this.$.batchMode) { - this.$.debug("$.oToolbar not supported in batch mode", this.$.DEBUG_LEVEL.ERROR) - return; - } - - var _parent = this._parent; - var _toolbar = new QToolbar(); - _toolbar.objectName = this.name; - - for (var i in this.widgets){ - _toolbar.addWidget(this.widgets[i]); - } - - _parent.addToolbar(_toolbar); - this.toolbar = _toolbar; - - return this.toolbar; -} diff --git a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_attribute.js b/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_attribute.js deleted file mode 100644 index fa044d5b74..0000000000 --- a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_attribute.js +++ /dev/null @@ -1,738 +0,0 @@ -////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// -// -// openHarmony Library v0.01 -// -// -// Developed by Mathieu Chaptel, Chris Fourney... -// -// -// This library is an open source implementation of a Document Object Model -// for Toonboom Harmony. It also implements patterns similar to JQuery -// for traversing this DOM. -// -// Its intended purpose is to simplify and streamline toonboom scripting to -// empower users and be easy on newcomers, with default parameters values, -// and by hiding the heavy lifting required by the official API. -// -// This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is guaranteed to work. Feel free to contribute -// improvements to its official github. If you do make sure you follow the provided -// template and naming conventions and document your new methods properly. -// -// This library doesn't overwrite any of the objects and classes of the official -// Toonboom API which must remains available. -// -// This library is made available under the MIT license. -// https://opensource.org/licenses/mit -// -// The repository for this library is available at the address: -// https://github.com/cfourney/OpenHarmony/ -// -// -// For any requests feel free to contact m.chaptel@gmail.com -// -// -// -// -////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// - - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oAttribute class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - -/** - * The constructor for the $.oAttribute class. - * @classdesc - * The $.oAttribute class holds the smart version of the parameter you can find in layer property.
- * It is used internally to get and set values and link a oColumn to a parameter in order to animate it. (Users should never have to instantiate this class)
- * For a list of attributes existing in each node type and their type, as well as examples of the values they can hold, refer to :
- * {@link NodeType}. - * @constructor - * @param {$.oNode} oNodeObject The oNodeObject that the attribute is associated to. - * @param {attr} attributeObject The internal harmony Attribute Object. - * @param {$.oAttribute} parentAttribute The parent attribute of the subattribute. - * - * @property {$.oNode} node The oNode this attribute belongs to. - * @property {attr} attributeObject The internal harmony Attribute Object. - * @property {string} keyword The keyword describing this attribute. (always in lower case) - * @property {string} shortKeyword The full keyword describing this attribute, including parent attributes separated with a "." (always in lower case) - * @property {$.oAttribute} parentAttribute The parent oAttribute object - * @property {$.oAttribute[]} subAttributes The subattributes of this attribute. - * @example - * // oAttribute objects can be grabbed from the node .attributes object with dot notation, by calling the attribute keyword in lowercase. - * - * var myNode = $.scn.getSelectedNodes()[0]; // grab the first selected node - * var Xattribute = myNode.attributes.position.x; // gets the position.x attribute of the node if it has it (for example, PEG nodes have it) - * - * var Xcolumn = Xattribute.column; // retrieve the linked column to the element (The object that holds the animation) - * - * Xattribute.setValue(5, 5); // sets the value to 5 at frame 5 - * - * // attribute values can also be set directly on the node when not animated: - * myNode.position.x = 5; - * - */ -$.oAttribute = function( oNodeObject, attributeObject, parentAttribute ){ - this._type = "attribute"; - - this.node = oNodeObject; - this.attributeObject = attributeObject; - - this._shortKeyword = attributeObject.keyword(); - - if( attributeObject.fullKeyword ){ - this._keyword = attributeObject.fullKeyword(); - }else{ - this._keyword = (parentAttribute?(parentAttribute._keyword+"."):"") + this._shortKeyword; - } - - this.parentAttribute = parentAttribute; // only for subAttributes - - // recursively add all subattributes as properties on the object - this.createSubAttributes(attributeObject); -} - - -/** - * Private function to create subAttributes in an oAttribute object at initialisation. - * @private - * @return {void} Nothing returned. - */ -$.oAttribute.prototype.createSubAttributes = function (attributeObject){ - var _subAttributes = []; - - // if harmony version supports getSubAttributes - var _subAttributesList = []; - if (attributeObject.getSubAttributes){ - _subAttributesList = attributeObject.getSubAttributes(); - }else{ - var sub_attrs = node.getAttrList( this.node.path, 1, this._keyword ); - - if( sub_attrs && sub_attrs.length>0 ){ - _subAttributesList = sub_attrs; - } - } - - for (var i in _subAttributesList){ - var _subAttribute = new this.$.oAttribute( this.node, _subAttributesList[i], this ); - var _keyword = _subAttribute.shortKeyword; - - // creating a property on the attribute object with the subattribute name to access it - this[_keyword] = _subAttribute; - _subAttributes.push(_subAttribute) - } - - // subAttributes is made available as an array for more formal access - this.subAttributes = _subAttributes; -} - - -/** - * Private function to add utility to subattributes on older versions of Harmony. - * @private - * @deprecated - * @return {void} Nothing returned. - */ -$.oAttribute.prototype.getSubAttributes_oldVersion = function (){ - var sub_attrs = []; - - switch( this.type ){ - case "POSITION_3D" : - //hard coded subAttr handler for POSITION_3D in older versions of Harmony. - sub_attrs = [ 'SEPARATE', 'X', 'Y', 'Z']; - break - case "ROTATION_3D" : - sub_attrs = [ 'SEPARATE', 'ANGLEX', 'ANGLEY', 'ANGLEZ', "QUATERNIONPATH" ]; - break - case "SCALE_3D" : - sub_attrs = [ 'SEPARATE', 'IN_FIELDS', 'XY', 'X', 'Y', 'Z' ]; - break - case "DRAWING" : - sub_attrs = [ 'ELEMENT', 'ELEMENT_MODE', 'CUSTOM_NAME']; - break - case "ELEMENT" : - sub_attrs = [ 'LAYER' ] - break - case "CUSTOM_NAME" : - sub_attrs = [ 'NAME', 'TIMING', 'EXTENSION', 'FIELD_CHART' ] - default: - break - } - - var _node = this.node.path; - var _keyword = this._keyword; - - sub_attrs = sub_attrs.map(function(x){return node.getAttr( _node, 1, _keyword+"."+x )}) - - return sub_attrs; -} - - -/** - * The display name of the attribute - * @name $.oAttribute#name - * @type {string} - */ -Object.defineProperty($.oAttribute.prototype, 'name', { - get: function(){ - return this.attributeObject.name(); - } -}) - -/** - * The full keyword of the attribute. - * @name $.oAttribute#keyword - * @type {string} - */ -Object.defineProperty($.oAttribute.prototype, 'keyword', { - get : function(){ - // formatting the keyword for our purposes - // hard coding a fix for 3DPath attribute name which starts with a number - var _keyword = this._keyword.toLowerCase(); - if (_keyword == "3dpath") _keyword = "path3d"; - return _keyword; - } -}); - - -/** - * The part of the attribute's keyword that is after the "." for subAttributes. - * @name $.oAttribute#shortKeyword - * @type {string} - */ -Object.defineProperty($.oAttribute.prototype, 'shortKeyword', { - get : function(){ - // formatting the keyword for our purposes - // hard coding a fix for 3DPath attribute name which starts with a number - var _keyword = this._shortKeyword.toLowerCase(); - if (_keyword == "3dpath") _keyword = "path3d"; - return _keyword; - } -}); - - -/** - * The type of the attribute. - * @name $.oAttribute#type - * @type {string} - */ -Object.defineProperty($.oAttribute.prototype, 'type', { - get : function(){ - return this.attributeObject.typeName(); - } -}); - -/** - * The column attached to the attribute. - * @name $.oAttribute#column - * @type {$.oColumn} - * @example -// link a new column to an attribute by setting this value: -var myColumn = $.scn.addColumn("BEZIER"); -myNode.attributes.position.x.column = myColumn; // values contained in "myColumn" now define the animation of our peg's x position - -// to automatically create a column and link it to the attribute, use: -myNode.attributes.position.x.addColumn(); // if the column exist already, it will just be returned. - -// to unlink a column, just set it to null/undefined: -myNode.attributes.position.x.column = null; // values are no longer animated. - */ -Object.defineProperty($.oAttribute.prototype, 'column', { - get : function(){ - var _column = node.linkedColumn ( this.node.path, this._keyword ); - if( _column && _column.length ){ - return this.node.scene.$column( _column, this ); - }else{ - return null; - } - }, - - set : function(columnObject){ - // unlink if provided with null value or empty string - if (!columnObject){ - node.unlinkAttr(this.node.path, this._keyword); - }else{ - node.linkAttr(this.node.path, this._keyword, columnObject.uniqueName); - columnObject.attributeObject = this; - // TODO: transfer current value of attribute to a first key on the column if column is empty - } - } -}); - - - /** - * The frames array holding the values of the animation. Starts at 1, as array indexes correspond to frame numbers. - * @name $.oAttribute#frames - * @type {$.oFrame[]} - */ -Object.defineProperty($.oAttribute.prototype, 'frames', { - get : function(){ - var _column = this.column - if (_column != null){ - return _column.frames; - }else{ - //Need a method to get frames of non-column values. Local Values. - return [ new this.$.oFrame( 1, this, false ) ]; - } - }, - - set : function(){ - throw "Not implemented." - } -}); - - -/** - * An array of only the keyframes (frames with a set value) of the animation. - * @name $.oAttribute#keyframes - * @type {$.oFrame[]} - */ -// MCNote: I would prefer if this could remain getKeyFrames() -Object.defineProperty($.oAttribute.prototype, 'keyframes', { - get : function(){ - var col = this.column; - var frames = this.frames; - - if( !col ){ - return frames[1]; - } - - return this.column.keyframes; - }, - - set : function(){ - throw "Not implemented." - } -}); - -/** - * WIP. - * @name $.oAttribute#useSeparate - * @type {bool} - * @private - */ -//CF Note: Not sure if this should be a general attribute, or a subattribute. -Object.defineProperty($.oAttribute.prototype, "useSeparate", { - get : function(){ - // TODO - throw new Error("not yet implemented"); - }, - - set : function( _value ){ - // TODO: when swapping from one to the other, copy key values and link new columns if missing - throw new Error("not yet implemented"); - } -}); - - -/** - * Returns the default value of the attribute for most keywords - * @name $.oAttribute#defaultValue - * @type {bool} - * @todo switch the implementation to types? - * @example - * // to reset an attribute to its default value: - * // (mostly used for position/angle/skew parameters of pegs and drawing nodes) - * var myAttribute = $.scn.nodes[0].attributes.position.x; - * - * myAttribute.setValue(myAttribute.defaultValue); - */ -Object.defineProperty($.oAttribute.prototype, "defaultValue", { - get : function(){ - // TODO: we could use this to reset bones/deformers to their rest states - var _keyword = this._keyword; - - switch (_keyword){ - case "OFFSET.X" : - case "OFFSET.Y" : - case "OFFSET.Z" : - - case "POSITION.X" : - case "POSITION.Y" : - case "POSITION.Z" : - - case "PIVOT.X": - case "PIVOT.Y": - case "PIVOT.Z": - - case "ROTATION.ANGLEX": - case "ROTATION.ANGLEY": - case "ROTATION.ANGLEZ": - - case "ANGLE": - case "SKEW": - - case "SPLINE_OFFSET.X": - case "SPLINE_OFFSET.Y": - case "SPLINE_OFFSET.Z": - - return 0; - - case "SCALE.X" : - case "SCALE.Y" : - case "SCALE.Z" : - return 1; - - case "OPACITY" : - return 100; - - case "COLOR" : - return new this.$.oColorValue(); - - case "OFFSET.3DPATH": - // pseudo oPathPoint - // CFNote: is this supposed to be an object? - // this is a fake object value that can be easily checked with a "==" operator. - // oPathPoint will be converted to string for checking, and have the same format. - // I made this to check if the value is default but I guess it's not ideal for assigning a default value, so maybe we should change it. - return "{x:0, y:0, z:0}"; - - default: - return null; // for attributes that don't have a default value, we return null - } - } -}); - - -// $.oAttribute Class methods - -/** - * Provides the keyframes of the attribute. - * @return {$.oFrame[]} The filtered keyframes. - */ -$.oAttribute.prototype.getKeyframes = function(){ - var _frames = this.frames; - _frames = _frames.filter(function(x){return x.isKeyframe}); - return _frames; -} - - -/** - * Provides the keyframes of the attribute. - * @return {$.oFrame[]} The filtered keyframes. - * @deprecated For case consistency, keyframe will never have a capital F - */ -$.oAttribute.prototype.getKeyFrames = function(){ - this.$.debug("oAttribute.getKeyFrames is deprecated. Use oAttribute.getKeyframes instead.", this.$.DEBUG_LEVEL.ERROR); - var _frames = this.frames; - _frames = _frames.filter(function(x){return x.isKeyframe}); - return _frames; -} - - -/** - * Recursively get all the columns linked to the attribute and its subattributes - * @return {$.oColumn[]} the list of columns linked to the subattributes - */ -$.oAttribute.prototype.getLinkedColumns = function(){ - var _columns = []; - var _subAttributes = this.subAttributes; - var _ownColumn = this.column; - if (_ownColumn != null) _columns.push(_ownColumn); - - for (var i=0; i<_subAttributes.length; i++) { - _columns = _columns.concat(_subAttributes[i].getLinkedColumns()); - } - - return _columns; -} - - -/** - * Recursively sets an attribute to the same value as another. Both must have the same keyword. - * @param {bool} [duplicateColumns=false] In the case that the attribute has a column, whether to duplicate the column before linking - * @private - */ -$.oAttribute.prototype.setToAttributeValue = function(attributeToCopy, duplicateColumns){ - if (typeof duplicateColumns === 'undefined') var duplicateColumns = false; - - if (this.keyword !== attributeToCopy.keyword) return; - var _subAttributes = this.subAttributes; - - var _column = attributeToCopy.column; - if (_column == null) { - var value = attributeToCopy.getValue(); - this.setValue(value); - }else{ - if (duplicateColumns) var _column = _column.duplicate(this); - this.column = _column; - } - - var _subAttributesToCopy = attributeToCopy.subAttributes; - for (var i=0; i<_subAttributes.length; i++){ - _subAttributes[i].setToAttributeValue(_subAttributesToCopy[i], duplicateColumns); - } -} - - -//CFNote: Is it worth having a getValueType? -/** - * Gets the value of the attribute at the given frame. - * @param {int} frame The frame at which to set the value, if not set, assumes 1 - * - * @return {object} The value of the attribute in the native format of that attribute (contextual to the attribute). - */ -$.oAttribute.prototype.getValue = function (frame) { - if (typeof frame === 'undefined') var frame = 1; - this.$.debug('getting value of frame :'+frame+' of attribute: '+this._keyword+' of node '+this.node+' - type '+this.type, this.$.DEBUG_LEVEL.LOG) - - var _attr = this.attributeObject; - var _type = this.type; - var _value; - var _column = this.column; - - // handling conversion of all return types into our own types - switch (_type){ - case 'BOOL': - _value = _attr.boolValueAt(frame) - break; - - case 'INT': - _value = _attr.intValueAt(frame) - break; - - case 'DOUBLE': - case 'DOUBLEVB': - _value = _attr.doubleValueAt(frame) - break; - - case 'STRING': - _value = _attr.textValueAt(frame) - break; - - case 'COLOR': - _value = new this.$.oColorValue(_attr.colorValueAt(frame)) - break; - - case 'POSITION_2D': - _value = _attr.pos2dValueAt(frame) - _value = new this.$.oPoint(_value.x, _value.y) - break; - - case 'POSITION_3D': - _value = _attr.pos3dValueAt(frame) - _value = new this.$.oPoint(_value.x, _value.y, _value.z) - break; - - case 'SCALE_3D': - _value = _attr.pos3dValueAt(frame) - _value = new this.$.oPoint(_value.x, _value.y, _value.z) - break; - - case 'PATH_3D': - _attr = this.parentAttribute.attributeObject; - var _frame = _column?(new this.$.oFrame(frame, _column)):(new this.$.oFrame(frame, _attr)); - if(_column && _frame.isKeyframe){ - _value = new this.$.oPathPoint(_column, _frame); - }else{ - _value = _attr.pos3dValueAt(frame); - } - break; - - /*case 'DRAWING': - // override with returning an oElement object - this.$.debug( "DRAWING: " + this.keyword , this.$.DEBUG_LEVEL.LOG); - - value = _column.element; - break;*/ - - case 'ELEMENT': - // an element always has a column, so we'll fetch it from there - _value = column.getEntry(_column.uniqueName, 1, frame); - - // Convert to an instance of oDrawing, with a safety in case of psd import - _drawing = _column.element.getDrawingByName(_value); - if (_drawing) _value = _drawing; - break; - - // TODO: How does QUATERNION_PATH work? subcolumns I imagine - // TODO: How to get types SCALE_3D, ROTATION_3D, DRAWING, GENERIC_ENUM? -> maybe we don't need to, they don't have intrinsic values - - default: - // enums, etc - _value = _attr.textValueAt(frame); - - // in case of subattributes, create a fake string that can have properties so we can create getter setters on it for its subattrs - if ( _attr.hasSubAttributes && _attr.hasSubAttributes() ){ - _value = { value:_value }; - _value.toString = function(){ return this.value }; - }else{ - var sub_attrs = node.getAttrList( this.node.path, 1, this._keyword ); - if( sub_attrs && sub_attrs.length>0 ){ - _value = { value:_value }; - _value.toString = function(){ return this.value }; - } - } - } - - return _value; -} - - -/** - * Sets the value of the attribute at the given frame. - * @param {string} value The value to set on the attribute. - * @param {int} [frame=1] The frame at which to set the value, if not set, assumes 1 - */ -$.oAttribute.prototype.setValue = function (value, frame) { - var _attr = this.attributeObject; - var _column = this.column; - var _type = this.type; - var _animate = false; - - if (!frame){ - // we don't animate - var frame = 1; - }else if (!_column){ - // generate a new column to be able to animate - _column = this.addColumn(); - } - - if( _column ){ - _animate = true; - } - - try{ - this.$.debug("setting attr "+this._keyword+" (type : "+this.type+") on node "+this.node+" to value "+JSON.stringify(value)+" at frame "+frame, this.$.DEBUG_LEVEL.LOG) - }catch(err){ - this.$.debug("setting attr "+this._keyword+" at frame "+frame, this.$.DEBUG_LEVEL.LOG) - }; - - switch(_type){ - // TODO: sanitize input - case "COLOR" : - // doesn't work for burnin because it has color.Red, color.green etc and not .r .g ... - value = (value instanceof this.$.oColorValue)?value: new this.$.oColorValue(value); - value = ColorRGBA(value.r, value.g, value.b, value.a); - _animate ? _attr.setValueAt(value, frame) : _attr.setValue(value); - break; - - case "GENERIC_ENUM" : - node.setTextAttr(this.node.path, this._keyword, frame, value); - break; - - case "PATH_3D" : - // check if frame is tied to a column or an attribute - var _frame = _column?(new this.$.oFrame(frame, this.column)):(new this.$.oFrame(frame, _attr)); - if (_column){ - if (!_frame.isKeyframe) _frame.isKeyframe = true; - var _point = new this.$.oPathPoint (this.column, _frame); - _point.set(value); - }else{ - // TODO: create keyframe? - this.parentAttribute.setValue(value); - } - break; - - case "POSITION_2D": - value = Point2d(value.x, value.y); - _animate ? _attr.setValueAt(value, frame) : _attr.setValue(value); - break; - - case "POSITION_3D": - value = Point3d(value.x, value.y, value.z); - _animate ? _attr.setValueAt(value, frame) : _attr.setValue(value); - break; - - case "ELEMENT" : - _column = this.column; - value = (value instanceof this.$.oDrawing) ? value.name : value; - column.setEntry(_column.uniqueName, 1, frame, value+""); - break; - - case "QUATERNIONPATH" : - // set quaternion paths as textattr until a better way is found - - default : - try{ - _animate ? _attr.setValueAt( value, frame ) : _attr.setValue( value ); - }catch(err){ - this.$.debug("error setting attr "+this._keyword+" value "+value+": "+err, this.$.DEBUG_LEVEL.DEBUG); - this.$.debug("setting text attr "+this._keyword+" value "+value+" as textAttr ", this.$.DEBUG_LEVEL.ERROR); - node.setTextAttr( this.node.path, this._keyword, frame, value ); - } - } -} - - -/** - * Adds a column with a default name, based on the attribute type. - * If a column already exists, it returns it. - * @returns {$.oColumn} the created column - */ -$.oAttribute.prototype.addColumn = function(){ - var _column = this.column; - if (_column) return _column; - - if (this.hasSubAttributes){ - throw new Error("Can't create columns for attribute "+this.keyword+", column must be created for its subattributes."); - } - - var _type = this.type; - var _columnType = ""; - var _columnName = this.node.name+": "+this.name.replace(/\s/g, "_"); - - switch(_type){ - case 'INT': - case 'DOUBLE': - case 'DOUBLEVB': - _columnType = "BEZIER"; - break; - - case "QUATERNIONPATH" : - _columnName = "QUARTERNION"; - break; - - case "PATH_3D" : - _columnName = "3DPATH"; - break; - - case "ELEMENT" : - _columnType = "DRAWING"; - _columnName = this.node.name; - break; - - default : - throw new Error("Can't create columns for attribute "+this.keyword+", not supported by attribute type '"+_type+"'"); - } - - var _column = this.$.scn.addColumn(_columnType, _columnName); - this.column = _column; - - if (!this.column) { - _column.remove(); - throw new Error("Can't create columns for attribute "+this.keyword+", animation not supported."); - } - - return this.column; -} - - -/** - * Gets the value of the attribute at the given frame. - * @param {int} frame The frame at which to set the value, if not set, assumes 1 - * @deprecated use oAttribute.getValue(frame) instead (see: function names as verbs) - * @return {object} The value of the attribute in the native format of that attribute (contextual to the attribute). - */ -$.oAttribute.prototype.value = function(frame){ - return this.getValue( frame ); -} - - -/** - * Represents an oAttribute object in string form - * @private - * @returns {string} - */ -$.oAttribute.prototype.toString = function(){ - return "[object $.oAttribute '"+this.keyword+(this.subAttributes.length?"' subAttributes: "+this.subAttributes.map(function(x){return x.shortKeyword}):"")+"]"; -} \ No newline at end of file diff --git a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_backdrop.js b/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_backdrop.js deleted file mode 100644 index 1d359f93c4..0000000000 --- a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_backdrop.js +++ /dev/null @@ -1,415 +0,0 @@ -////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// -// -// openHarmony Library -// -// -// Developed by Mathieu Chaptel, Chris Fourney -// -// -// This library is an open source implementation of a Document Object Model -// for Toonboom Harmony. It also implements patterns similar to JQuery -// for traversing this DOM. -// -// Its intended purpose is to simplify and streamline toonboom scripting to -// empower users and be easy on newcomers, with default parameters values, -// and by hiding the heavy lifting required by the official API. -// -// This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is guaranteed to work. Feel free to contribute -// improvements to its official github. If you do make sure you follow the provided -// template and naming conventions and document your new methods properly. -// -// This library doesn't overwrite any of the objects and classes of the official -// Toonboom API which must remains available. -// -// This library is made available under the Mozilla Public license 2.0. -// https://www.mozilla.org/en-US/MPL/2.0/ -// -// The repository for this library is available at the address: -// https://github.com/cfourney/OpenHarmony/ -// -// -// For any requests feel free to contact m.chaptel@gmail.com -// -// -// -// -////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// - - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oBackdrop class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * The constructor for the $.oBackdrop class. - * @constructor - * @classdesc The $.oBackdrop Class represents a backdrop in the node view, and allows users to add, remove and modify existing Backdrops. Accessing these functions is done through the oGroupNode class. - * @param {string} groupPath The path to the object in which this backdrop is placed. - * @param {backdropObject} backdropObject The harmony-internal backdrop object associated with this oBackdrop. - * @example - * function createColoredBackdrop(){ - * // This script will prompt for a color and create a backdrop around the selection - * $.beginUndo() - * - * var doc = $.scn; // grab the scene - * var nodes = doc.selectedNodes; // grab the selection - * - * if(!nodes) return // exit the function if no nodes are selected - * - * var color = pickColor(); // prompt for color - * - * var group = doc.root // get the group to add the backdrop to - * var backdrop = group.addBackdropToNodes(nodes, "BackDrop", "", color) - * - * $.endUndo(); - * - * // function to get the color chosen by the user - * function pickColor(){ - * var d = new QColorDialog; - * d.exec(); - * var color = d.selectedColor(); - * return new $.oColorValue({r:color.red(), g:color.green(), b:color.blue(), a:color.alpha()}) - * } - * } - */ -$.oBackdrop = function( groupPath, backdropObject ){ - this.group = ( groupPath instanceof this.$.oGroupNode )? groupPath.path: groupPath; - this.backdropObject = backdropObject; -} - - -/** - * The index of this backdrop in the current group. - * @name $.oBackdrop#index - * @type {int} - */ -Object.defineProperty($.oBackdrop.prototype, 'index', { - get : function(){ - var _groupBackdrops = Backdrop.backdrops(this.group).map(function(x){return x.title.text}) - return _groupBackdrops.indexOf(this.title) - } -}) - - -/** - * The title of the backdrop. - * @name $.oBackdrop#title - * @type {string} - */ -Object.defineProperty($.oBackdrop.prototype, 'title', { - get : function(){ - var _title = this.backdropObject.title.text; - return _title; - }, - - set : function(newTitle){ - var _backdrops = Backdrop.backdrops(this.group); - - // incrementing to prevent two backdrops to have the same title - var names = _backdrops.map(function(x){return x.title.text}) - var count = 0; - var title = newTitle - - while (names.indexOf(title) != -1){ - count++; - title = newTitle+"_"+count; - } - newTitle = title; - - var _index = this.index; - - _backdrops[_index].title.text = newTitle; - - this.backdropObject = _backdrops[_index]; - Backdrop.setBackdrops(this.group, _backdrops); - } -}) - - -/** - * The body text of the backdrop. - * @name $.oBackdrop#body - * @type {string} - */ -Object.defineProperty($.oBackdrop.prototype, 'body', { - get : function(){ - var _title = this.backdropObject.description.text; - return _title; - }, - - set : function(newBody){ - var _backdrops = Backdrop.backdrops(this.group); - - var _index = this.index; - _backdrops[_index].description.text = newBody; - - this.backdropObject = _backdrops[_index]; - Backdrop.setBackdrops(this.group, _backdrops); - } -}) - - -/** - * The title font of the backdrop in form { family:"familyName", "size":int, "color": oColorValue } - * @name $.oBackdrop#titleFont - * @type {object} - */ -Object.defineProperty($.oBackdrop.prototype, 'titleFont', { - get : function(){ - var _font = {family : this.backdropObject.title.font, - size : this.backdropObject.title.size, - color : ( new oColorValue() ).parseColorFromInt(this.backdropObject.title.color)} - return _font; - }, - - set : function(newFont){ - var _backdrops = Backdrop.backdrops(this.group); - var _index = this.index; - - _backdrops[_index].title.font = newFont.family; - _backdrops[_index].title.size = newFont.size; - _backdrops[_index].title.color = newFont.color.toInt(); - - this.backdropObject = _backdrops[_index]; - Backdrop.setBackdrops(this.group, _backdrops); - } -}) - - -/** - * The body font of the backdrop in form { family:"familyName", "size":int, "color": oColorValue } - * @name $.oBackdrop#bodyFont - * @type {object} - */ -Object.defineProperty($.oBackdrop.prototype, 'bodyFont', { - get : function(){ - var _font = {family : this.backdropObject.description.font, - size : this.backdropObject.description.size, - color : ( new oColorValue() ).parseColorFromInt(this.backdropObject.description.color)} - return _font; - }, - - set : function(newFont){ - var _backdrops = Backdrop.backdrops(this.group); - var _index = this.index; - - _backdrops[_index].title.font = newFont.family; - _backdrops[_index].title.size = newFont.size; - _backdrops[_index].title.color = newFont.color.toInt(); - - this.backdropObject = _backdrops[_index]; - Backdrop.setBackdrops(this.group, _backdrops); - } -}) - - -/** - * The nodes contained within this backdrop - * @name $.oBackdrop#parent - * @type {$.oNode[]} - * @readonly - */ - Object.defineProperty($.oBackdrop.prototype, 'parent', { - get : function(){ - if (!this.hasOwnProperty("_parent")){ - this._parent = this.$.scn.getNodeByPath(this.group); - } - return this._parent - } -}) - - -/** - * The nodes contained within this backdrop - * @name $.oBackdrop#nodes - * @type {$.oNode[]} - * @readonly - */ -Object.defineProperty($.oBackdrop.prototype, 'nodes', { - get : function(){ - var _nodes = this.parent.nodes; - var _bounds = this.bounds; - _nodes = _nodes.filter(function(x){ - return _bounds.contains(x.bounds); - }) - - return _nodes; - } -}) - -/** - * The position of the backdrop on the horizontal axis. - * @name $.oBackdrop#x - * @type {float} - */ -Object.defineProperty($.oBackdrop.prototype, 'x', { - get : function(){ - var _x = this.backdropObject.position.x; - return _x; - }, - - set : function(newX){ - var _backdrops = Backdrop.backdrops(this.group); - var _index = this.index; - - _backdrops[_index].position.x = newX; - - this.backdropObject = _backdrops[_index]; - Backdrop.setBackdrops(this.group, _backdrops); - } -}) - - -/** - * The position of the backdrop on the vertical axis. - * @name $.oBackdrop#y - * @type {float} - */ -Object.defineProperty($.oBackdrop.prototype, 'y', { - get : function(){ - var _y = this.backdropObject.position.y; - return _y; - }, - - set : function(newY){ - var _backdrops = Backdrop.backdrops(this.group); - var _index = this.index; - - _backdrops[_index].position.y = newY; - - this.backdropObject = _backdrops[_index]; - Backdrop.setBackdrops(this.group, _backdrops); - } -}) - - -/** - * The width of the backdrop. - * @name $.oBackdrop#width - * @type {float} - */ -Object.defineProperty($.oBackdrop.prototype, 'width', { - get : function(){ - var _width = this.backdropObject.position.w; - return _width; - }, - - set : function(newWidth){ - var _backdrops = Backdrop.backdrops(this.group); - var _index = this.index; - - _backdrops[_index].position.w = newWidth; - - this.backdropObject = _backdrops[_index]; - Backdrop.setBackdrops(this.group, _backdrops); - } -}) - - -/** - * The height of the backdrop. - * @name $.oBackdrop#height - * @memberof $.oBackdrop# - * @type {float} - */ -Object.defineProperty($.oBackdrop.prototype, 'height', { - get : function(){ - var _height = this.backdropObject.position.h; - return _height; - }, - - set : function(newHeight){ - var _backdrops = Backdrop.backdrops(this.group); - var _index = this.index; - - _backdrops[_index].position.h = newHeight; - - this.backdropObject = _backdrops[_index]; - Backdrop.setBackdrops(this.group, _backdrops); - } -}) - - -/** - * The position of the backdrop. - * @name $.oBackdrop#position - * @type {oPoint} - */ -Object.defineProperty($.oBackdrop.prototype, 'position', { - get : function(){ - var _position = new oPoint(this.x, this.y, this.index) - return _position; - }, - - set : function(newPos){ - var _backdrops = Backdrop.backdrops(this.group); - var _index = this.index; - - _backdrops[_index].position.x = newPos.x; - _backdrops[_index].position.y = newPos.y; - - this.backdropObject = _backdrops[_index]; - Backdrop.setBackdrops(this.group, _backdrops); - } -}) - - -/** - * The bounds of the backdrop. - * @name $.oBackdrop#bounds - * @type {oBox} - */ -Object.defineProperty($.oBackdrop.prototype, 'bounds', { - get : function(){ - var _box = new oBox(this.x, this.y, this.width+this.x, this.height+this.y) - return _box; - }, - - set : function(newBounds){ - var _backdrops = Backdrop.backdrops(this.group); - var _index = this.index; - - _backdrops[_index].position.x = newBounds.top; - _backdrops[_index].position.y = newBounds.left; - _backdrops[_index].position.w = newBounds.width; - _backdrops[_index].position.h = newBounds.height; - - this.backdropObject = _backdrops[_index]; - Backdrop.setBackdrops(this.group, _backdrops); - } -}) - - -/** - * The color of the backdrop. - * @name $.oBackdrop#color - * @type {oColorValue} - */ -Object.defineProperty($.oBackdrop.prototype, 'color', { - get : function(){ - var _color = this.backdropObject.color; - // TODO: get the rgba values from the int - return _color; - }, - - set : function(newOColorValue){ - var _color = new oColorValue(newOColorValue); - var _index = this.index; - - var _backdrops = Backdrop.backdrops(this.group); - _backdrops[_index].color = _color.toInt(); - - this.backdropObject = _backdrops[_index]; - Backdrop.setBackdrops(this.group, _backdrops); - } -}) \ No newline at end of file diff --git a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_color.js b/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_color.js deleted file mode 100644 index ff06688e66..0000000000 --- a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_color.js +++ /dev/null @@ -1,661 +0,0 @@ -////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// -// -// openHarmony Library -// -// -// Developed by Mathieu Chaptel, Chris Fourney -// -// -// This library is an open source implementation of a Document Object Model -// for Toonboom Harmony. It also implements patterns similar to JQuery -// for traversing this DOM. -// -// Its intended purpose is to simplify and streamline toonboom scripting to -// empower users and be easy on newcomers, with default parameters values, -// and by hiding the heavy lifting required by the official API. -// -// This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is guaranteed to work. Feel free to contribute -// improvements to its official github. If you do make sure you follow the provided -// template and naming conventions and document your new methods properly. -// -// This library doesn't overwrite any of the objects and classes of the official -// Toonboom API which must remains available. -// -// This library is made available under the Mozilla Public license 2.0. -// https://www.mozilla.org/en-US/MPL/2.0/ -// -// The repository for this library is available at the address: -// https://github.com/cfourney/OpenHarmony/ -// -// -// For any requests feel free to contact m.chaptel@gmail.com -// -// -// -// -////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// - - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oColorValue class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - -/** - * This class holds a color value. It can be used to set color attributes to a specific value and to convert colors between different formats such as hex strings, RGBA decompositions, as well as HSL values. - * @constructor - * @classdesc Constructor for the $.oColorValue Class. - * @param {string/object} colorValue Hex string value, or object in form {rgba} - * - * @property {int} r The int value of the red component. - * @property {int} g The int value of the green component. - * @property {int} b The int value of the blue component. - * @property {int} a The int value of the alpha component. - * @example - * // initialise the class to start setting up attributes and making conversions by creating a new instance - * - * var myColor = new $.oColorValue("#336600ff"); - * $.log(myColor.r+" "+mycolor.g+" "+myColor.b+" "+myColor+a) // you can then access each component of the color - * - * var myBackdrop = $.scn.root.addBackdrop("Backdrop") - * var myBackdrop.color = myColor // can be used to set the color of a backdrop - * - */ -$.oColorValue = function( colorValue ){ - if (typeof colorValue === 'undefined') var colorValue = "#000000ff"; - - this.r = 0; - this.g = 0; - this.b = 0; - this.a = 255; - - //Special case in which RGBA values are defined directly. - switch( arguments.length ){ - case 4: - this.a = ( (typeof arguments[3]) == "number" ) ? arguments[3] : 0; - case 3: - this.r = ( (typeof arguments[0]) == "number" ) ? arguments[0] : 0; - this.g = ( (typeof arguments[1]) == "number" ) ? arguments[1] : 0; - this.b = ( (typeof arguments[2]) == "number" ) ? arguments[2] : 0; - return; - default: - } - - if (typeof colorValue === 'string'){ - this.fromColorString(colorValue); - }else{ - if (typeof colorValue.r === 'undefined') colorValue.r = 0; - if (typeof colorValue.g === 'undefined') colorValue.g = 0; - if (typeof colorValue.b === 'undefined') colorValue.b = 0; - if (typeof colorValue.a === 'undefined') colorValue.a = 255; - - this.r = colorValue.r; - this.g = colorValue.g; - this.b = colorValue.b; - this.a = colorValue.a; - } -} - - -/** - * Creates an int from the color value, as used for backdrop colors. - * @return: {string} ALPHA<<24 RED<<16 GREEN<<8 BLUE - */ -$.oColorValue.prototype.toInt = function (){ - return ((this.a & 0xff) << 24) | ((this.r & 0xff) << 16) | ((this.g & 0xff) << 8) | (this.b & 0xff); -} - - -/** - * The colour value represented as a string. - * @return: {string} RGBA components in a string in format #RRGGBBAA - */ -$.oColorValue.prototype.toString = function (){ - var _hex = "#"; - - var r = ("00"+this.r.toString(16)).slice(-2); - var g = ("00"+this.g.toString(16)).slice(-2); - var b = ("00"+this.b.toString(16)).slice(-2); - var a = ("00"+this.a.toString(16)).slice(-2); - - _hex += r + g + b + a; - - return _hex; -} - -/** - * The colour value represented as a string. - * @return: {string} RGBA components in a string in format #RRGGBBAA - */ -$.oColorValue.prototype.toHex = function (){ - return this.toString(); -} - -/** - * Ingest a hex string in form #RRGGBBAA to define the colour. - * @param {string} hexString The colour in form #RRGGBBAA - */ -$.oColorValue.prototype.fromColorString = function (hexString){ - hexString = hexString.replace("#",""); - if (hexString.length == 6) hexString += "ff"; - if (hexString.length != 8) throw new Error("incorrect color string format"); - - this.$.debug( "HEX : " + hexString, this.$.DEBUG_LEVEL.LOG); - - this.r = parseInt(hexString.slice(0,2), 16); - this.g = parseInt(hexString.slice(2,4), 16); - this.b = parseInt(hexString.slice(4,6), 16); - this.a = parseInt(hexString.slice(6,8), 16); -} - - -/** - * Uses a color integer (used in backdrops) and parses the INT; applies the RGBA components of the INT to the oColorValue - * @param { int } colorInt 24 bit-shifted integer containing RGBA values - */ -$.oColorValue.prototype.parseColorFromInt = function(colorInt){ - this.r = colorInt >> 16 & 0xFF; - this.g = colorInt >> 8 & 0xFF; - this.b = colorInt & 0xFF; - this.a = colorInt >> 24 & 0xFF; -} - - -/** - * Gets the color's HUE value. - * @name $.oColorValue#h - * @type {float} - */ -Object.defineProperty($.oColorValue.prototype, 'h', { - get : function(){ - var r = this.r; - var g = this.g; - var b = this.b; - - var cmin = Math.min(r,g,b); - var cmax = Math.max(r,g,b); - var delta = cmax - cmin; - var h = 0; - var s = 0; - var l = 0; - - if (delta == 0){ - h = 0.0; - // Red is max - }else if (cmax == r){ - h = ((g - b) / delta) % 6.0; - // Green is max - }else if (cmax == g){ - h = (b - r) / delta + 2.0; - // Blue is max - }else{ - h = (r - g) / delta + 4.0; - } - - h = Math.round(h * 60.0); - - //WRAP IN 360. - if (h < 0){ - h += 360.0; - } - - // // Calculate lightness - // l = (cmax + cmin) / 2.0; - - // // Calculate saturation - // s = delta == 0 ? 0 : delta / (1.0 - Math.abs(2.0 * l - 1.0)); - - // s = Math.min( Math.abs(s)*100.0, 100.0 ); - // l = (Math.abs(l)/255.0)*100.0; - - return h; - }, - - set : function( new_h ){ - var h = Math.min( new_h, 360.0 ); - var s = Math.min( this.s, 100.0 )/100.0; - var l = Math.min( this.l, 100.0 )/100.0; - - var c = (1.0 - Math.abs(2.0 * l - 1.0)) * s; - var x = c * (1 - Math.abs((h / 60.0) % 2.0 - 1.0)); - var m = l - c/2.0; - var r = 0.0; - var g = 0.0; - var b = 0.0; - - if (0.0 <= h && h < 60.0) { - r = c; g = x; b = 0; - } else if (60.0 <= h && h < 120.0) { - r = x; g = c; b = 0; - } else if (120.0 <= h && h < 180.0) { - r = 0; g = c; b = x; - } else if (180.0 <= h && h < 240.0) { - r = 0; g = x; b = c; - } else if (240.0 <= h && h < 300.0) { - r = x; g = 0; b = c; - } else if (300.0 <= h && h < 360.0) { - r = c; g = 0; b = x; - } - - this.r = (r + m) * 255.0; - this.g = (g + m) * 255.0; - this.b = (b + m) * 255.0; - } -}); - -/** - * Gets the color's SATURATION value. - * @name $.oColorValue#s - * @type {float} - */ -Object.defineProperty($.oColorValue.prototype, 's', { - get : function(){ - var r = this.r; - var g = this.g; - var b = this.b; - - var cmin = Math.min(r,g,b); - var cmax = Math.max(r,g,b); - var delta = cmax - cmin; - var s = 0; - var l = 0; - - // Calculate lightness - l = (cmax + cmin) / 2.0; - s = delta == 0 ? 0 : delta / (1.0 - Math.abs(2.0 * l - 1.0)); - - // Calculate saturation - s = Math.min( Math.abs(s)*100.0, 100.0 ); - - return s; - }, - - set : function( new_s ){ - var h = Math.min( this.h, 360.0 ); - var s = Math.min( new_s, 100.0 )/100.0; - var l = Math.min( this.l, 100.0 )/100.0; - - var c = (1.0 - Math.abs(2.0 * l - 1.0)) * s; - var x = c * (1 - Math.abs((h / 60.0) % 2.0 - 1.0)); - var m = l - c/2.0; - var r = 0.0; - var g = 0.0; - var b = 0.0; - - if (0.0 <= h && h < 60.0) { - r = c; g = x; b = 0; - } else if (60.0 <= h && h < 120.0) { - r = x; g = c; b = 0; - } else if (120.0 <= h && h < 180.0) { - r = 0; g = c; b = x; - } else if (180.0 <= h && h < 240.0) { - r = 0; g = x; b = c; - } else if (240.0 <= h && h < 300.0) { - r = x; g = 0; b = c; - } else if (300.0 <= h && h < 360.0) { - r = c; g = 0; b = x; - } - - this.r = (r + m) * 255.0; - this.g = (g + m) * 255.0; - this.b = (b + m) * 255.0; - } -}); - -/** - * Gets the color's LIGHTNESS value. - * @name $.oColorValue#l - * @type {float} - */ -Object.defineProperty($.oColorValue.prototype, 'l', { - get : function(){ - var r = this.r; - var g = this.g; - var b = this.b; - - var cmin = Math.min(r,g,b); - var cmax = Math.max(r,g,b); - var delta = cmax - cmin; - var s = 0; - var l = 0; - - - // Calculate lightness - l = (cmax + cmin) / 2.0; - l = (Math.abs(l)/255.0)*100.0; - return l; - }, - - set : function( new_l ){ - var h = Math.min( this.h, 360.0 ); - var s = Math.min( this.s, 100.0 )/100.0; - var l = Math.min( new_l, 100.0 )/100.0; - - var c = (1.0 - Math.abs(2.0 * l - 1.0)) * s; - var x = c * (1 - Math.abs((h / 60.0) % 2.0 - 1.0)); - var m = l - c/2.0; - var r = 0.0; - var g = 0.0; - var b = 0.0; - - if (0.0 <= h && h < 60.0) { - r = c; g = x; b = 0; - } else if (60.0 <= h && h < 120.0) { - r = x; g = c; b = 0; - } else if (120.0 <= h && h < 180.0) { - r = 0; g = c; b = x; - } else if (180.0 <= h && h < 240.0) { - r = 0; g = x; b = c; - } else if (240.0 <= h && h < 300.0) { - r = x; g = 0; b = c; - } else if (300.0 <= h && h < 360.0) { - r = c; g = 0; b = x; - } - - this.r = (r + m) * 255.0; - this.g = (g + m) * 255.0; - this.b = (b + m) * 255.0; - } -}); - - - - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oColor class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -// oPalette constructor - -/** - * The base class for the $.oColor. - * @constructor - * @classdesc $.oColor Base Class - * @param {$.oPalette} oPaletteObject The palette to which the color belongs. - * @param {int} attributeObject The index of the color in the palette. - * - * @property {$.oPalette} palette The palette to which the color belongs. - */ -$.oColor = function( oPaletteObject, index ){ - // We don't use id in the constructor as multiple colors with the same id can exist in the same palette. - this._type = "color"; - - this.palette = oPaletteObject; - this._index = index; -} - -// $.oColor Object Properties - -/** - * The Harmony color object. - * @name $.oColor#colorObject - * @type {BaseColor} - */ -Object.defineProperty($.oColor.prototype, 'colorObject', { - get : function(){ - return this.palette.paletteObject.getColorByIndex(this._index); - } -}); - - - -/** - * The name of the color. - * @name $.oColor#name - * @type {string} - */ -Object.defineProperty($.oColor.prototype, 'name', { - get : function(){ - var _color = this.colorObject; - return _color.name; - }, - - set : function(newName){ - var _color = this.colorObject; - _color.setName(newName); - } -}); - - -/** - * The id of the color. - * @name $.oColor#id - * @type {string} - */ -Object.defineProperty($.oColor.prototype, 'id', { - get : function(){ - var _color = this.colorObject; - return _color.id - }, - - set : function(newId){ - // TODO: figure out a way to change id? Create a new color with specific id in the palette? - throw new Error("setting oColor.id Not yet implemented"); - } -}); - - -/** - * The index of the color. - * @name $.oColor#index - * @type {int} - */ -Object.defineProperty($.oColor.prototype, 'index', { - get : function(){ - return this._index; - }, - - set : function(newIndex){ - var _color = this.palette.paletteObject.moveColor(this._index, newIndex); - this._index = newIndex; - } -}); - - -/** - * The type of the color. - * @name $.oColor#type - * @type {int} - */ -Object.defineProperty($.oColor.prototype, 'type', { - set : function(){ - throw new Error("setting oColor.type Not yet implemented."); - }, - - get : function(){ - var _color = this.colorObject; - if (_color.isTexture) return "texture"; - - switch (_color.colorType) { - case PaletteObjectManager.Constants.ColorType.SOLID_COLOR: - return "solid"; - case PaletteObjectManager.Constants.ColorType.LINEAR_GRADIENT : - return "gradient"; - case PaletteObjectManager.Constants.ColorType.RADIAL_GRADIENT: - return "radial gradient"; - default: - } - } -}); - - -/** - * Whether the color is selected. - * @name $.oColor#selected - * @type {bool} - */ -Object.defineProperty($.oColor.prototype, 'selected', { - get : function(){ - var _currentId = PaletteManager.getCurrentColorId() - var _colors = this.palette.colors; - var _ids = _colors.map(function(x){return x.id}) - return this._index == _ids.indexOf(_currentId); - }, - - set : function(isSelected){ - // TODO: find a way to work with index as more than one color can have the same id, also, can there be no selected color when removing selection? - if (isSelected){ - var _id = this.id; - PaletteManager.setCurrentColorById(_id); - } - } -}); - - -/** - * Takes a string or array of strings for gradients and filename for textures. Instead of passing rgba objects, it accepts "#rrggbbaa" hex strings for convenience.
set gradients, provide an object with keys from 0 to 1 for the position of each color.
(ex: {0: new $.oColorValue("000000ff"), 1:new $.oColorValue("ffffffff")}). - * @name $.oColor#value - * @type {$.oColorValue} - */ -Object.defineProperty($.oColor.prototype, 'value', { - get : function(){ - var _color = this.colorObject; - - switch(this.type){ - case "solid": - return new this.$.oColorValue(_color.colorData); - case "texture": - return this.palette.path.parent.path + this.palette.name+"_textures/" + this.id + ".tga"; - case "gradient": - case "radial gradient": - var _gradientArray = _color.colorData; - var _value = {}; - for (var i in _gradientArray){ - var _data = _gradientArray[i]; - _value[_gradientArray[i].t] = new this.$.oColorValue(_data.r, _data.g, _data.b, _data.a); - } - return _value; - default: - } - }, - - set : function(newValue){ - var _color = this.colorObject; - - switch(this.type){ - case "solid": - _value = new $.oColorValue(newValue); - _color.setColorData(_value); - break; - case "texture": - // TODO: need to copy the file into the folder first? - _color.setTextureFile(newValue); - break; - case "gradient": - case "radial gradient": - var _value = []; - var _gradient = newValue; - for (var i in _gradient){ - var _color = _gradient[i]; - var _tack = {r:_color.r, g:_color.g, b:_color.b, a:_color.a, t:parseFloat(i, 10)} - _value.push(_tack); - } - _color.setColorData(_value); - break; - default: - }; - } -}); - - -// Methods - -/** - * Moves the palette to another Palette Object (CFNote: perhaps have it push to paletteObject, instead of being done at the color level) - * @param {$.oPalette} oPaletteObject The paletteObject to move this color into. - * @param {int} index Need clarification from mchap - * - * @return: {$.oColor} The new resulting $.oColor object. - */ -$.oColor.prototype.moveToPalette = function (oPaletteObject, index){ - if (typeof index === 'undefined') var index = oPaletteObject.paletteObject.nColors; - var _duplicate = this.copyToPalette(oPaletteObject, index) - this.remove() - - return _duplicate; -} - - -/** - * Copies the palette to another Palette Object (CFNote: perhaps have it push to paletteObject, instead of being done at the color level) - * @param {$.oPalette} oPaletteObject The paletteObject to move this color into. - * @param {int} index Need clarification from mchap - * - * @return: {$.oColor} The new resulting $.oColor object. - */ -$.oColor.prototype.copyToPalette = function (oPaletteObject, index){ - var _color = this.colorObject; - - oPaletteObject.paletteObject.cloneColor(_color); - var _colors = oPaletteObject.colors; - var _duplicate = _colors.pop(); - - if (typeof index !== 'undefined') _duplicate.index = index; - - return _duplicate; -} - - -/** - * Removes the color from the palette it belongs to. - */ -$.oColor.prototype.remove = function (){ - // TODO: find a way to work with index as more than one color can have the same id - this.palette.paletteObject.removeColor(this.id); -} - - -/** - * Static helper function to convert from {r:int, g:int, b:int, a:int} to a hex string in format #FFFFFFFF
- * Consider moving this to a helper function. - * @param { obj } rgbaObject RGB object - * @static - * @return: { string } Hex color string in format #FFFFFFFF. - */ -$.oColor.prototype.rgbaToHex = function (rgbaObject){ - var _hex = "#"; - _hex += rvbObject.r.toString(16) - _hex += rvbObject.g.toString(16) - _hex += rvbObject.b.toString(16) - _hex += rvbObject.a.toString(16) - - return _hex; -} - - -/** - * Static helper function to convert from hex string in format #FFFFFFFF to {r:int, g:int, b:int, a:int}
- * Consider moving this to a helper function. - * @param { string } hexString RGB object - * @static - * @return: { obj } The hex object returned { r:int, g:int, b:int, a:int } - */ -$.oColor.prototype.hexToRgba = function (hexString){ - var _rgba = {}; - //Needs a better fail state. - - _rgba.r = parseInt(hexString.slice(1,3), 16) - _rgba.g = parseInt(hexString.slice(3,5), 16) - _rgba.b = parseInt(hexString.slice(5,7), 16) - _rgba.a = parseInt(hexString.slice(7,9), 16) - - return _rgba; -} - - - diff --git a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_column.js b/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_column.js deleted file mode 100644 index f73309049e..0000000000 --- a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_column.js +++ /dev/null @@ -1,649 +0,0 @@ -////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// -// -// openHarmony Library -// -// -// Developed by Mathieu Chaptel, Chris Fourney -// -// -// This library is an open source implementation of a Document Object Model -// for Toonboom Harmony. It also implements patterns similar to JQuery -// for traversing this DOM. -// -// Its intended purpose is to simplify and streamline toonboom scripting to -// empower users and be easy on newcomers, with default parameters values, -// and by hiding the heavy lifting required by the official API. -// -// This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is guaranteed to work. Feel free to contribute -// improvements to its official github. If you do make sure you follow the provided -// template and naming conventions and document your new methods properly. -// -// This library doesn't overwrite any of the objects and classes of the official -// Toonboom API which must remains available. -// -// This library is made available under the Mozilla Public license 2.0. -// https://www.mozilla.org/en-US/MPL/2.0/ -// -// The repository for this library is available at the address: -// https://github.com/cfourney/OpenHarmony/ -// -// -// For any requests feel free to contact m.chaptel@gmail.com -// -// -// -// -////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// - - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oColumn class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * The constructor for the $.oColumn class. - * @classdesc Columns are the objects that hold all the animation information of an attribute. Any animated value in Harmony is so thanks to a column linked to the attribute representing the node parameter. Columns can be added from the scene class, or are directly created when giving a non 1 value when setting an attribute. - * @constructor - * @param {string} uniqueName The unique name of the column. - * @param {$.oAttribute} oAttributeObject The oAttribute thats connected to the column. - * - * @property {string} uniqueName The unique name of the column. - * @property {$.oAttribute} attributeObject The attribute object that the column is attached to. - * @example - * // You can get the entirety of the columns in the scene by calling: - * var doc = $.scn; - * var allColumns = doc.columns; - * - * // However, to get a specific column, you can retrieve it from its linked attribute: - * - * var myAttribute = doc.nodes[0].attributes.position.x - * var mycolumn = myAttribute.column; - * - * // once you have the column, you can do things like remove duplicates keys to simplify an animation; - * myColumn.removeDuplicateKeys(); - * - * // you can extract all the keys to be able to iterate over it: - * var keyFrames = myColumn.getKeyFrames(); - * - * for (var i in keyFrames){ - * $.log (keyFrames[i].frameNumber); - * } - * - * // you can also link a given column to more than one attribute so they share the same animated values: - * - * doc.nodes[0].attributes.position.y.column = myColumn; // now position.x and position.y will share the same animation on the node. - */ -$.oColumn = function( uniqueName, oAttributeObject ){ - var instance = this.$.getInstanceFromCache.call(this, uniqueName); - if (instance) return instance; - - this._type = "column"; - - this.uniqueName = uniqueName; - this.attributeObject = oAttributeObject; - - this._cacheFrames = []; - - //Helper cache for subsequent actions. - try{ - // fails when the column has no attribute - if( !this.$.cache_columnToNodeAttribute ){ this.$.cache_columnToNodeAttribute = {}; } - this.$.cache_columnToNodeAttribute[this.uniqueName] = { "node":oAttributeObject.node, "attribute": this.attributeObject, "date": (new Date()).getTime() }; - }catch(err){} -} - - -// $.oColumn Object Properties -/** - * The name of the column. - * @name $.oColumn#name - * @type {string} - */ -Object.defineProperty( $.oColumn.prototype, 'name', { - get : function(){ - return column.getDisplayName(this.uniqueName); - }, - - set : function(newName){ - var _success = column.rename(this.uniqueName, newName) - if (_success){ - this.uniqueName = newName; - }else{ - throw new Error("Failed to rename column "+this.uniqueName+" to "+newName+".") - } - } -}); - - -/** - * The type of the column. There are nine column types: drawing (DRAWING), sound (SOUND), 3D Path (3DPATH), Bezier Curve (BEZIER), Ease Curve (EASE), Expression (EXPR), Timing (TIMING) for timing columns, Quaternion path (QUATERNIONPATH) for 3D rotation and Annotation (ANNOTATION) for annotation columns. - * @name $.oColumn#type - * @readonly - * @type {string} - */ -Object.defineProperty( $.oColumn.prototype, 'type', { - get : function(){ - return column.type(this.uniqueName) - } -}); - - -/** - * Whether the column is selected. - * @name $.oColumn#selected - * @type {bool} - */ -Object.defineProperty($.oColumn.prototype, 'selected', { - get : function(){ - var sel_num = selection.numberOfColumnsSelected(); - for( var n=0;n allows to loop through subcolumns if they exist - if (this.type == "3DPATH"){ - return { x : 1, - y : 2, - z : 3, - velocity : 4} - } - return { a : 1 }; - } -}); - -/** - * The type of easing used by the column - * @name $.oColumn#subColumns - * @readonly - * @type {object} - */ -Object.defineProperty($.oColumn.prototype, 'easeType', { - get : function(){ - switch(this.type){ - case "BEZIER": - return "BEZIER"; - case "3DPATH": - return column.velocityType( this.uniqueName ); - default: - return null; - } - } -}) - - -/** - * An object with three int values : start, end and step, representing the value of the stepped section parameter (interpolation with non linear "step" parameter). - * @name $.oColumn#stepSection - * @type {object} - */ -Object.defineProperty($.oColumn.prototype, 'stepSection', { - get : function(){ - var _columnName = this.uniqueName; - var _section = { - start: func.holdStartFrame (_columnName), - end : func.holdStopFrame (_columnName), - step : func.holdStep (_columnName) - } - return _section; - }, - - set : function(newSection){ - var _columnName = this.uniqueName; - func.setHoldStartFrame (_columnName, newSection.start) - func.setHoldStopFrame (_columnName, newSection.end) - func.setHoldStep (_columnName, newSection.step) - } -}); - - -// $.oColumn Class methods - -/** - * Deletes the column from the scene. The column must be unlinked from any attribute first. - */ -$.oColumn.prototype.remove = function(){ - column.removeUnlinkedFunctionColumn(this.name); - if (this.type) throw new Error("Couldn't remove column "+this.name+", unlink it from any attribute first.") -} - - -/** - * Extends the exposure of the drawing's keyframes given the provided arguments. - * @deprecated Use oDrawingColumn.extendExposures instead. - * @param {$.oFrame[]} exposures The exposures to extend. If UNDEFINED, extends all keyframes. - * @param {int} amount The amount to extend. - * @param {bool} replace Setting this to false will insert frames as opposed to overwrite existing ones. - */ -$.oColumn.prototype.extendExposures = function( exposures, amount, replace){ - if (this.type != "DRAWING") return false; - // if amount is undefined, extend function below will automatically fill empty frames - - if (typeof exposures === 'undefined') var exposures = this.attributeObject.getKeyframes(); - - for (var i in exposures) { - if (!exposures[i].isBlank) exposures[i].extend(amount, replace); - } - -} - - - -/** - * Removes concurrent/duplicate keys from drawing layers. - */ -$.oColumn.prototype.removeDuplicateKeys = function(){ - var _keys = this.getKeyframes(); - - var _pointsToRemove = []; - var _pointC; - - // check the extremities - var _pointA = _keys[0].value; - var _pointB = _keys[1].value; - if (JSON.stringify(_pointA) == JSON.stringify(_pointB)) _pointsToRemove.push(_keys[0].frameNumber); - - for (var k=1; k<_keys.length-2; k++){ - _pointA = _keys[k-1].value; - _pointB = _keys[k].value; - _pointC = _keys[k+1].value; - - MessageLog.trace(this.attributeObject.keyword+" pointA: "+JSON.stringify(_pointA)+" pointB: "+JSON.stringify(_pointB)+" pointC: "+JSON.stringify(_pointC)); - - if (JSON.stringify(_pointA) == JSON.stringify(_pointB) && JSON.stringify(_pointB) == JSON.stringify(_pointC)){ - _pointsToRemove.push(_keys[k].frameNumber); - } - } - - _pointA = _keys[_keys.length-2].value; - _pointB = _keys[_keys.length-1].value; - if (JSON.stringify(_pointC) == JSON.stringify(_pointB)) _pointsToRemove.push(_keys[_keys.length-1].frameNumber); - - var _frames = this.frames; - - for (var i in _pointsToRemove){ - _frames[_pointsToRemove[i]].isKeyframe = false; - } - -} - - -/** - * Duplicates a column. Because of the way Harmony works, specifying an attribute the column will be connected to ensures higher value fidelity between the original and the copy. - * @param {$.oAttribute} [newAttribute] An attribute to link the column to upon duplication. - * - * @return {$.oColumn} The column generated. - */ -$.oColumn.prototype.duplicate = function(newAttribute) { - var _duplicateColumn = this.$.scene.addColumn(this.type, this.name); - - // linking to an attribute if one is provided - if (typeof newAttribute !== 'undefined'){ - newAttribute.column = _duplicateColumn; - _duplicateColumn.attributeObject = newAttribute; - } - - var _duplicatedFrames = _duplicateColumn.frames; - var _keyframes = this.keyframes; - - // we set the ease twice to avoid incompatibilities between ease parameters and yet unchanged points - for (var i in _keyframes){ - var _duplicateFrame = _duplicatedFrames[_keyframes[i].frameNumber]; - _duplicateFrame.value = _keyframes[i].value; - } - - for (var i in _keyframes){ - var _duplicateFrame = _duplicatedFrames[_keyframes[i].frameNumber]; - _duplicateFrame.ease = _keyframes[i].ease; - } - - for (var i in _keyframes){ - var _duplicateFrame = _duplicatedFrames[_keyframes[i].frameNumber]; - _duplicateFrame.ease = _keyframes[i].ease; - } - - _duplicateColumn.stepSection = this.stepSection; - - return _duplicateColumn; -} - - -/** - * Filters out only the keyframes from the frames array. - * - * @return {$.oFrame[]} Provides the array of frames from the column. - */ -$.oColumn.prototype.getKeyframes = function(){ - var _frames = this.frames; - - var _ease = this.easeType; - if( _ease == "BEZIER" || _ease == "EASE" ){ - var _keyFrames = []; - var _columnName = this.uniqueName; - var _points = func.numberOfPoints(_columnName); - - for (var i = 0; i<_points; i++) { - var _frameNumber = func.pointX( _columnName, i ) - _keyFrames.push( _frames[_frameNumber] ); - } - - return _keyFrames; - } - - _frames = _frames.filter(function(x){return x.isKeyframe}); - return _frames; -} - - -/** - * Filters out only the keyframes from the frames array. - * @deprecated For case consistency, keyframe will never have a capital F - * @return {$.oFrame[]} Provides the array of frames from the column. - */ -$.oColumn.prototype.getKeyFrames = function(){ - this.$.debug("oColumn.getKeyFrames is deprecated. Use oColumn.getKeyframes instead.", this.$.DEBUG_LEVEL.ERROR); - return this.keyframes; -} - - -/** - * Gets the value of the column at the given frame. - * @param {int} [frame=1] The frame at which to get the value - * @return {various} The value of the column, can be different types depending on column type. - */ -$.oColumn.prototype.getValue = function(frame){ - if (typeof frame === 'undefined') var frame = 1; - - // this.$.log("Getting value of frame "+this.frameNumber+" of column "+this.column.name) - if (this.attributeObject){ - return this.attributeObject.getValue(frame); - }else{ - this.$.debug("getting unlinked column "+this.name+" value at frame "+frame, this.$.DEBUG_LEVEL.ERROR); - this.$.debug("warning : getting a value from a column without attribute destroys value fidelity", this.$.DEBUG_LEVEL.ERROR); - - if (this.type == "3DPATH") { - var _frame = new this.$.oFrame(frame, this, this.subColumns); - return new this.$.oPathPoint(this, _frame); - } - - return column.getEntry (this.uniqueName, 1, frame); - } -} - - -/** - * Sets the value of the column at the given frame. - * @param {various} newValue The new value to set the column to - * @param {int} [frame=1] The frame at which to get the value - */ -$.oColumn.prototype.setValue = function(newValue, frame){ - if (typeof frame === 'undefined') var frame = 1; - - if (this.attributeObject){ - this.attributeObject.setValue( newValue, frame); - }else{ - this.$.debug("setting unlinked column "+this.name+" value to "+newValue+" at frame "+frame, this.$.DEBUG_LEVEL.ERROR); - this.$.debug("warning : setting a value on a column without attribute destroys value fidelity", this.$.DEBUG_LEVEL.ERROR); - - if (this.type == "3DPATH") { - column.setEntry (this.uniqueName, 1, frame, newValue.x); - column.setEntry (this.uniqueName, 2, frame, newValue.y); - column.setEntry (this.uniqueName, 3, frame, newValue.z); - column.setEntry (this.uniqueName, 4, frame, newValue.velocity); - }else{ - column.setEntry (this.uniqueName, 1, frame, newValue.toString()); - } - } -} - - - -/** - * Retrieves the nodes index in the timeline provided. - * @param {oTimeline} [timeline] Optional: the timeline object to search the column Layer. (by default, grabs the current timeline) - * - * @return {int} The index within that timeline. - */ -$.oColumn.prototype.getTimelineLayer = function(timeline){ - if (typeof timeline === 'undefined') var timeline = this.$.scene.getTimeline(); - - var _columnNames = timeline.allLayers.map(function(x){return x.column?x.column.uniqueName:null}); - return timeline.allLayers[_columnNames.indexOf(this.uniqueName)]; -} - - -/** - * @private - */ -$.oColumn.prototype.toString = function(){ - return "[object $.oColumn '"+this.name+"']" -} - - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oDrawingColumn class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * the $.oDrawingColumn constructor. Only called internally by the factory function [scene.getColumnByName()]{@link $.oScene#getColumnByName}; - * @constructor - * @classdesc oDrawingColumn is a special case of column which can be linked to an [oElement]{@link $.oElement}. This type of column is used to display drawings and always is visible in the Xsheet window. - * @augments $.oColumn - * @param {string} uniqueName The unique name of the column. - * @param {$.oAttribute} oAttributeObject The oAttribute thats connected to the column. - * - * @property {string} uniqueName The unique name of the column. - * @property {$.oAttribute} attributeObject The attribute object that the column is attached to. - */ -$.oDrawingColumn = function( uniqueName, oAttributeObject ) { - // $.oDrawingColumn can only represent a column of type 'DRAWING' - if (column.type(uniqueName) != 'DRAWING') throw new Error("'uniqueName' parameter must point to a 'DRAWING' type node"); - //MessageBox.information("getting an instance of $.oDrawingColumn for column : "+uniqueName) - var instance = $.oColumn.call(this, uniqueName, oAttributeObject); - if (instance) return instance; -} - - -// extends $.oColumn and can use its methods -$.oDrawingColumn.prototype = Object.create($.oColumn.prototype); -$.oDrawingColumn.prototype.constructor = $.oColumn; - - -/** - * Retrieve and set the drawing element attached to the column. - * @name $.oDrawingColumn#element - * @type {$.oElement} - */ -Object.defineProperty($.oDrawingColumn.prototype, 'element', { - get : function(){ - return new this.$.oElement(column.getElementIdOfDrawing( this.uniqueName), this); - }, - - set : function(oElementObject){ - column.setElementIdOfDrawing( this.uniqueName, oElementObject.id ); - oElementObject.column = this; - } -}) - - -/** - * Extends the exposure of the drawing's keyframes by the specified amount. - * @param {$.oFrame[]} [exposures] The exposures to extend. If not specified, extends all keyframes. - * @param {int} [amount] The number of frames to add to each exposure. If not specified, will extend frame up to the next one. - * @param {bool} [replace=false] Setting this to false will insert frames as opposed to overwrite existing ones.(currently unsupported)) - */ -$.oDrawingColumn.prototype.extendExposures = function( exposures, amount, replace){ - // if amount is undefined, extend function below will automatically fill empty frames - if (typeof exposures === 'undefined') var exposures = this.getKeyframes(); - - this.$.debug("extendingExposures "+exposures.map(function(x){return x.frameNumber})+" by "+amount, this.$.DEBUG_LEVEL.DEBUG) - - // can't extend blank exposures, so we remove them from the list to extend - exposures = exposures.filter(function(x){return !x.isBlank}) - - for (var i in exposures) { - exposures[i].extend(amount, replace); - } -} - - -/** - * Duplicates a Drawing column. - * @param {bool} [duplicateElement=true] Whether to also duplicate the element. Default is true. - * @param {$.oAttribute} [newAttribute] Whether to link the new column to an attribute at this point. - * - * @return {$.oColumn} The created column. - */ -$.oDrawingColumn.prototype.duplicate = function(newAttribute, duplicateElement) { - // duplicate element? - if (typeof duplicateElement === 'undefined') var duplicateElement = true; - var _duplicateElement = duplicateElement?this.element.duplicate():this.element; - - var _duplicateColumn = this.$.scene.addColumn(this.type, this.name, _duplicateElement); - - // linking to an attribute if one is provided - if (typeof newAttribute !== 'undefined'){ - newAttribute.column = _duplicateColumn; - _duplicateColumn.attributeObject = newAttribute; - } - - var _frames = this.frames; - for (var i in _frames){ - var _duplicateFrame = _duplicateColumn.frames[i]; - _duplicateFrame.value = _frames[i].value; - if (_frames[i].isKeyframe) _duplicateFrame.isKeyframe = true; - } - - return _duplicateColumn; -} - - -/** - * Renames the column's exposed drawings according to the frame they are first displayed at. - * @param {string} [prefix] a prefix to add to all names. - * @param {string} [suffix] a suffix to add to all names. - */ -$.oDrawingColumn.prototype.renameAllByFrame = function(prefix, suffix){ - if (typeof prefix === 'undefined') var prefix = ""; - if (typeof suffix === 'undefined') var suffix = ""; - - // get exposed drawings - var _displayedDrawings = this.getExposedDrawings(); - this.$.debug("Column "+this.name+" has drawings : "+_displayedDrawings.map(function(x){return x.value}), this.$.DEBUG_LEVEL.LOG); - - // remove duplicates - var _seen = []; - for (var i=0; i<_displayedDrawings.length; i++){ - var _drawing = _displayedDrawings[i].value; - - if (_seen.indexOf(_drawing.name) == -1){ - _seen.push(_drawing.name); - }else{ - _displayedDrawings.splice(i,1); - i--; - } - } - - // rename - for (var i in _displayedDrawings){ - var _frameNum = _displayedDrawings[i].frameNumber; - var _drawing = _displayedDrawings[i].value; - this.$.debug("renaming drawing "+_drawing+" of column "+this.name+" to "+prefix+_frameNum+suffix, this.$.DEBUG_LEVEL.LOG); - _drawing.name = prefix+_frameNum+suffix; - } -} - - -/** - * Removes unused drawings from the column. - * @param {$.oFrame[]} exposures The exposures to extend. If UNDEFINED, extends all keyframes. - */ -$.oDrawingColumn.prototype.removeUnexposedDrawings = function(){ - var _element = this.element; - var _displayedDrawings = this.getExposedDrawings().map(function(x){return x.value.name;}); - var _element = this.element; - var _drawings = _element.drawings; - - for (var i=_drawings.length-1; i>=0; i--){ - this.$.debug("removing drawing "+_drawings[i].name+" of column "+this.name+"? "+(_displayedDrawings.indexOf(_drawings[i].name) == -1), this.$.DEBUG_LEVEL.LOG); - if (_displayedDrawings.indexOf(_drawings[i].name) == -1) _drawings[i].remove(); - } -} - -$.oDrawingColumn.prototype.getExposedDrawings = function (){ - return this.keyframes.filter(function(x){return x.value != null}); -} - - -/** - * @private - */ - $.oDrawingColumn.prototype.toString = function(){ - return "<$.oDrawingColumn '"+this.name+"'>"; -} diff --git a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_database.js b/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_database.js deleted file mode 100644 index 5440b92875..0000000000 --- a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_database.js +++ /dev/null @@ -1,135 +0,0 @@ -////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// -// -// openHarmony Library -// -// -// Developed by Mathieu Chaptel, Chris Fourney -// -// -// This library is an open source implementation of a Document Object Model -// for Toonboom Harmony. It also implements patterns similar to JQuery -// for traversing this DOM. -// -// Its intended purpose is to simplify and streamline toonboom scripting to -// empower users and be easy on newcomers, with default parameters values, -// and by hiding the heavy lifting required by the official API. -// -// This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is guaranteed to work. Feel free to contribute -// improvements to its official github. If you do make sure you follow the provided -// template and naming conventions and document your new methods properly. -// -// This library doesn't overwrite any of the objects and classes of the official -// Toonboom API which must remains available. -// -// This library is made available under the Mozilla Public license 2.0. -// https://www.mozilla.org/en-US/MPL/2.0/ -// -// The repository for this library is available at the address: -// https://github.com/cfourney/OpenHarmony/ -// -// -// For any requests feel free to contact m.chaptel@gmail.com -// -// -// -// -////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oDataBase class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * The constructor for the $.oDataBase. - * @classdesc - * A class to access the contents of the Harmony database from a scene. - * @constructor - */ -$.oDatabase = function(){ -} - - -/** - * Function to query the database using the dbu utility. - * @private - */ -$.oDatabase.prototype.query = function(args){ - var dbbin = specialFolders.bin+"/dbu"; - var p = new $.oProcess(dbbin, args); - var result = p.execute(); - - result = result.split("Name:").join("").split("\r\n"); - - return result; -} - -/** - * Lists the environments existing on the local database - * @return {string[]} The list of names of environments - */ -$.oDatabase.prototype.getEnvironments = function(){ - var dbFile = new this.$.oFile("/USA_DB/envs/env.db"); - if (!dbFile.exists){ - this.$.debug("Can't access Harmony Database at address : /USA_DB/envs/env.db", this.$.DEBUG_LEVEL.ERROR); - return null; - } - var dbqueryArgs = ["-l", "-sh", "Name", dbFile.path]; - var envs = this.query(dbqueryArgs); - return envs; -} - - -/** - * Lists the jobs in the given environment in the local database - * @param {string} [environment] The name of the environment to return the jobs from. Returns the jobs from the current environment by default. - * @return {string[]} The list of job names in the environment. - */ -$.oDatabase.prototype.getJobs = function(environment){ - if (typeof environment === 'undefined' && this.$.scene.online) { - var environment = this.$.scene.environment; - }else{ - return null; - } - - var dbFile = new this.$.oFile("/USA_DB/online_jobs/jobs.db"); - if (!dbFile.exists){ - this.$.debug("Can't access Harmony Database at address : /USA_DB/online_jobs/jobs.db", this.$.DEBUG_LEVEL.ERROR); - return null; - } - var dbqueryArgs = ["-l", "-sh", "Name", "-search", "Env == "+environment, dbFile.path]; - var jobs = this.query(dbqueryArgs); - return jobs; -} - - -/** - * Lists the scenes in the given environment in the local database - * @param {string} [job] The name of the jobs to return the scenes from. Returns the scenes from the current job by default. - * @return {string[]} The list of scene names in the job. - */ -$.oDatabase.prototype.getScenes = function(job){ - if (typeof job === 'undefined' && this.$.scene.online){ - var job = this.$.scene.job; - }else{ - return null; - } - - var dbFile = new this.$.oFile("/USA_DB/db_jobs/"+job+"/scene.db"); - if (!dbFile.exists){ - this.$.debug("Can't access Harmony Database at address : /USA_DB/db_jobs/"+job+"/scene.db", this.$.DEBUG_LEVEL.ERROR); - return null; - } - var dbqueryArgs = ["-l", "-sh", "Name", dbFile.path]; - var scenes = this.query(dbqueryArgs); - return scenes; -} diff --git a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_dialog.js b/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_dialog.js deleted file mode 100644 index 3ab78b87d6..0000000000 --- a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_dialog.js +++ /dev/null @@ -1,1545 +0,0 @@ -"use strict" -////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// -// -// openHarmony Library -// -// -// Developed by Mathieu Chaptel, Chris Fourney -// -// -// This library is an open source implementation of a Document Object Model -// for Toonboom Harmony. It also implements patterns similar to JQuery -// for traversing this DOM. -// -// Its intended purpose is to simplify and streamline toonboom scripting to -// empower users and be easy on newcomers, with default parameters values, -// and by hiding the heavy lifting required by the official API. -// -// This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is guaranteed to work. Feel free to contribute -// improvements to its official github. If you do make sure you follow the provided -// template and naming conventions and document your new methods properly. -// -// This library doesn't overwrite any of the objects and classes of the official -// Toonboom API which must remains available. -// -// This library is made available under the Mozilla Public license 2.0. -// https://www.mozilla.org/en-US/MPL/2.0/ -// -// The repository for this library is available at the address: -// https://github.com/cfourney/OpenHarmony/ -// -// -// For any requests feel free to contact m.chaptel@gmail.com -// -// -// -// -////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oDialog class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * The base class for the $.oDialog. - * @classdesc - * $.oDialog Base Class -- helper class for showing GUI content. - * @constructor - */ -$.oDialog = function( ){ -} - - -/** - * Prompts with a confirmation dialog (yes/no choice). - * @name $.oDialog#confirm - * @function - * @param {string} [labelText] The label/internal text of the dialog. - * @param {string} [title] The title of the confirmation dialog. - * @param {string} [okButtonText] The text on the OK button of the dialog. - * @param {string} [cancelButtonText] The text on the CANCEL button of the dialog. - * - * @return {bool} Result of the confirmation dialog. - */ - -$.oDialog.prototype.confirm = function( labelText, title, okButtonText, cancelButtonText ){ - if (this.$.batchMode) { - this.$.debug("$.oDialog.confirm not supported in batch mode", this.$.DEBUG_LEVEL.WARNING) - return; - } - - if (typeof labelText === 'undefined') var labelText = false; - if (typeof title === 'undefined') var title = "Confirmation"; - if (typeof okButtonText === 'undefined') var okButtonText = "OK"; - if (typeof cancelButtonText === 'undefined') var cancelButtonText = "Cancel"; - - var d = new Dialog(); - d.title = title; - d.okButtonText = okButtonText; - d.cancelButtonText = cancelButtonText; - - if( labelText ){ - var label = new Label; - label.text = labelText; - } - - d.add( label ); - - if ( !d.exec() ){ - return false; - } - - return true; -} - - -/** - * Prompts with an alert dialog (informational). - * @param {string} [labelText] The label/internal text of the dialog. - * @param {string} [title] The title of the confirmation dialog. - * @param {string} [okButtonText] The text on the OK button of the dialog. - * - */ -$.oDialog.prototype.alert = function( labelText, title, okButtonText ){ - if (this.$.batchMode) { - this.$.debug("$.oDialog.alert not supported in batch mode", this.$.DEBUG_LEVEL.WARNING) - return; - } - - if (typeof labelText === 'undefined') var labelText = "Alert!"; - if (typeof title === 'undefined') var title = "Alert"; - if (typeof okButtonText === 'undefined') var okButtonText = "OK"; - - this.$.debug(labelText, this.$.DEBUG_LEVEL.LOG) - - var d = new QMessageBox( false, title, labelText, QMessageBox.Ok ); - d.setWindowTitle( title ); - - d.buttons()[0].text = okButtonText; - - if( labelText ){ - d.text = labelText; - } - - if ( !d.exec() ){ - return; - } -} - - -/** - * Prompts with an alert dialog with a text box which can be selected (informational). - * @param {string} [labelText] The label/internal text of the dialog. - * @param {string} [title] The title of the confirmation dialog. - * @param {string} [okButtonText="OK"] The text on the OK button of the dialog. - * @param {bool} [htmlSupport=false] - */ -$.oDialog.prototype.alertBox = function( labelText, title, okButtonText, htmlSupport){ - if (this.$.batchMode) { - this.$.debug("$.oDialog.alert not supported in batch mode", this.$.DEBUG_LEVEL.WARNING) - return; - } - - if (typeof labelText === 'undefined') var labelText = ""; - if (typeof title === 'undefined') var title = ""; - if (typeof okButtonText === 'undefined') var okButtonText = "OK"; - if (typeof htmlSupport === 'undefined') var htmlSupport = false; - - this.$.debug(labelText, this.$.DEBUG_LEVEL.LOG) - - var d = new QDialog(); - - if (htmlSupport){ - var label = new QTextEdit(labelText + ""); - }else{ - var label = new QPlainTextEdit(labelText + ""); - } - label.readOnly = true; - - var button = new QPushButton(okButtonText); - - var layout = new QVBoxLayout(d); - layout.addWidget(label, 1, Qt.Justify); - layout.addWidget(button, 0, Qt.AlignHCenter); - - d.setWindowTitle( title ); - button.clicked.connect(d.accept); - - d.exec(); -} - - -/** - * Prompts with an toast alert. This is a small message that can't be clicked and only stays on the screen for the duration specified. - * @param {string} labelText The label/internal text of the dialog. - * @param {$.oPoint} [position] The position on the screen where the toast will appear (by default, slightly under the middle of the screen). - * @param {float} [duration=2000] The duration of the display (in milliseconds). - * @param {$.oColorValue} [color="#000000"] The color of the background (a 50% alpha value will be applied). - */ -$.oDialog.prototype.toast = function(labelText, position, duration, color){ - if (this.$.batchMode) { - this.$.debug("$.oDialog.alert not supported in batch mode", this.$.DEBUG_LEVEL.WARNING); - return; - } - - if (typeof duration === 'undefined') var duration = 2000; - if (typeof color === 'undefined') var color = new $.oColorValue(0,0,0); - if (typeof position === 'undefined'){ - var center = QApplication.desktop().screen().rect.center(); - var position = new $.oPoint(center.x(), center.y()+UiLoader.dpiScale(150)) - } - - var toast = new QWidget() - var flags = new Qt.WindowFlags(Qt.Popup|Qt.FramelessWindowHint|Qt.WA_TransparentForMouseEvents); - toast.setWindowFlags(flags); - toast.setAttribute(Qt.WA_TranslucentBackground); - toast.setAttribute(Qt.WA_DeleteOnClose); - - var styleSheet = "QWidget {" + - "background-color: rgba("+color.r+", "+color.g+", "+color.b+", 50%); " + - "color: white; " + - "border-radius: "+UiLoader.dpiScale(10)+"px; " + - "padding: "+UiLoader.dpiScale(10)+"px; " + - "font-family: Arial; " + - "font-size: "+UiLoader.dpiScale(12)+"pt;}" - - toast.setStyleSheet(styleSheet); - - var layout = new QHBoxLayout(toast); - layout.addWidget(new QLabel(labelText), 0, Qt.AlignHCenter); - - var timer = new QTimer() - timer.singleShot = true; - timer.timeout.connect(this, function(){ - toast.close(); - }) - - toast.show(); - - toast.move(position.x-toast.width/2, position.y); - - timer.start(duration); -} - - -/** - * Prompts for a user input. - * @param {string} [labelText] The label/internal text of the dialog. - * @param {string} [title] The title of the confirmation dialog. - * @param {string} [prefilledText] The text to display in the input area. - * - */ -$.oDialog.prototype.prompt = function( labelText, title, prefilledText){ - if (typeof labelText === 'undefined') var labelText = "enter value :"; - if (typeof title === 'undefined') var title = "Prompt"; - if (typeof prefilledText === 'undefined') var prefilledText = ""; - return Input.getText(labelText, prefilledText, title); -} - - -/** - * Prompts with a file selector window - * @param {string} [text="Select a file:"] The title of the confirmation dialog. - * @param {string} [filter="*"] The filter for the file type and/or file name that can be selected. Accepts wildcard character "*". - * @param {string} [getExisting=true] Whether to select an existing file or a save location - * @param {string} [acceptMultiple=false] Whether or not selecting more than one file is ok. Is ignored if getExisting is falses. - * @param {string} [startDirectory] The directory showed at the opening of the dialog. - * - * @return {string[]} The list of selected Files, 'undefined' if the dialog is cancelled - */ -$.oDialog.prototype.browseForFile = function( text, filter, getExisting, acceptMultiple, startDirectory){ - if (this.$.batchMode) { - this.$.debug("$.oDialog.browseForFile not supported in batch mode", this.$.DEBUG_LEVEL.WARNING) - return; - } - - if (typeof title === 'undefined') var title = "Select a file:"; - if (typeof filter === 'undefined') var filter = "*" - if (typeof getExisting === 'undefined') var getExisting = true; - if (typeof acceptMultiple === 'undefined') var acceptMultiple = false; - - - if (getExisting){ - if (acceptMultiple){ - var _files = QFileDialog.getOpenFileNames(0, text, startDirectory, filter); - }else{ - var _files = QFileDialog.getOpenFileName(0, text, startDirectory, filter); - } - }else{ - var _files = QFileDialog.getSaveFileName(0, text, startDirectory, filter); - } - - for (var i in _files){ - _files[i] = _files[i].replace(/\\/g, "/"); - } - - this.$.debug(_files); - return _files; -} - - -/** - * Prompts with a browse for folder dialog (informational). - * @param {string} [text] The title of the confirmation dialog. - * @param {string} [startDirectory] The directory showed at the opening of the dialog. - * - * @return {string} The path of the selected folder, 'undefined' if the dialog is cancelled - */ -$.oDialog.prototype.browseForFolder = function(text, startDirectory){ - if (this.$.batchMode) { - this.$.debug("$.oDialog.browseForFolder not supported in batch mode", this.$.DEBUG_LEVEL.WARNING) - return; - } - - if (typeof title === 'undefined') var title = "Select a folder:"; - - var _folder = QFileDialog.getExistingDirectory(0, text, startDirectory); - _folder = _folder.split("\\").join("/"); - // this.$.alert(_folder) - return _folder; -} - - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oProgressDialog class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * The $.oProgressDialog constructor. - * @name $.oProgressDialog - * @constructor - * @classdesc An simple progress dialog to display the progress of a task. - * To react to the user clicking the cancel button, connect a function to $.oProgressDialog.canceled() signal. - * When $.batchmode is true, the progress will be outputted as a "Progress : value/range" string to the Harmony stdout. - * @param {string} [labelText] The text displayed above the progress bar. - * @param {string} [range=100] The maximum value that represents a full progress bar. - * @param {string} [title] The title of the dialog - * @param {bool} [show=false] Whether to immediately show the dialog. - * - * @property {bool} wasCanceled Whether the progress bar was cancelled. - * @property {$.oSignal} canceled A Signal emitted when the dialog is canceled. Can be connected to a callback. - */ -$.oProgressDialog = function( labelText, range, title, show ){ - if (typeof title === 'undefined') var title = "Progress"; - if (typeof range === 'undefined') var range = 100; - if (typeof labelText === 'undefined') var labelText = ""; - - this._value = 0; - this._range = range; - this._title = title; - this._labelText = labelText; - - this.canceled = new this.$.oSignal(); - this.wasCanceled = false; - - if (!this.$.batchMode) { - this.progress = new QProgressDialog(); - this.progress.title = this._title; - this.progress.setLabelText( this._labelText ); - this.progress.setRange( 0, this._range ); - this.progress.setWindowFlags(Qt.Popup|Qt.WindowStaysOnTopHint) - - this.progress["canceled()"].connect( this, function(){this.wasCanceled = true; this.canceled.emit()} ); - - if (show) this.show(); - } -} - - -// legacy compatibility -$.oDialog.Progress = $.oProgressDialog; - - -/** - * The text displayed by the window. - * @name $.oProgressDialog#label - * @type {string} - */ -Object.defineProperty( $.oProgressDialog.prototype, 'label', { - get: function(){ - return this._labelText; - }, - set: function( val ){ - this._labelText = val; - if (!this.$.batchMode) this.progress.setLabelText( val ); - } -}); - - -/** - * The maximum value that can be displayed by the progress dialog (equivalent to "finished") - * @name $.oProgressDialog#range - * @type {int} - */ -Object.defineProperty( $.oProgressDialog.prototype, 'range', { - get: function(){ - return this._range; - }, - set: function( val ){ - this._range = val; - if (!this.$.batchMode) this.progress.setRange( 0, val ); - } -}); - - -/** - * The current value of the progress bar. Setting this to the value of 'range' will close the dialog. - * @name $.oProgressDialog#value - * @type {int} - */ -Object.defineProperty( $.oProgressDialog.prototype, 'value', { - get: function(){ - return this._value; - }, - set: function( val ){ - if (val > this.range) val = this.range; - this._value = val; - if (this.$.batchMode) { - this.$.log("Progress : "+val+"/"+this._range) - }else { - this.progress.value = val; - } - - // update the widget appearance - QCoreApplication.processEvents(); - } -}); - - -/** - * Whether the Progress Dialog was cancelled by the user. - * @name $.oProgressDialog#cancelled - * @deprecated use $.oProgressDialog.wasCanceled to get the cancel status, or connect a function to the "canceled" signal. - */ -Object.defineProperty( $.oProgressDialog.prototype, 'cancelled', { - get: function(){ - return this.wasCanceled; - } -}); - - -// oProgressDialog Class Methods - -/** - * Shows the dialog. - */ -$.oProgressDialog.prototype.show = function(){ - if (this.$.batchMode) { - this.$.debug("$.oProgressDialog not supported in batch mode", this.$.DEBUG_LEVEL.ERROR) - return; - } - - this.progress.show(); -} - -/** - * Closes the dialog. - */ -$.oProgressDialog.prototype.close = function(){ - this.value = this.range; - this.$.log("Progress : "+this.value+"/"+this._range) - - if (this.$.batchMode) { - this.$.debug("$.oProgressDialog not supported in batch mode", this.$.DEBUG_LEVEL.ERROR) - return; - } - - this.canceled.blocked = true; - this.progress.close(); - this.canceled.blocked = false; -} - - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oPieMenu class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * The $.oPieMenu constructor. - * @name $.oPieMenu - * @constructor - * @classdesc A type of menu with nested levels that appear around the mouse - * @param {string} name The name for this pie Menu. - * @param {QWidget[]} [widgets] The widgets to display in the menu. - * @param {bool} [show=false] Whether to immediately show the dialog. - * @param {float} [minAngle] The low limit of the range of angles used by the menu, in multiples of PI (0 : left, 0.5 : top, 1 : right, -0.5 : bottom) - * @param {float} [maxAngle] The high limit of the range of angles used by the menu, in multiples of PI (0 : left, 0.5 : top, 1 : right, -0.5 : bottom) - * @param {float} [radius] The radius of the menu. - * @param {$.oPoint} [position] The central position of the menu. - * - * @property {string} name The name for this pie Menu. - * @property {QWidget[]} widgets The widgets to display in the menu. - * @property {float} minAngle The low limit of the range of angles used by the menu, in multiples of PI (0 : left, 0.5 : top, 1 : right, -0.5 : bottom) - * @property {float} maxAngle The high limit of the range of angles used by the menu, in multiples of PI (0 : left, 0.5 : top, 1 : right, -0.5 : bottom) - * @property {float} radius The radius of the menu. - * @property {$.oPoint} position The central position of the menu or button position for imbricated menus. - * @property {QWidget} menuWidget The central position of the menu or button position for imbricated menus. - * @property {QColor} sliceColor The color of the slices. Can set to any fill type accepted by QBrush - * @property {QColor} backgroundColor The background of the menu. Can set to any fill type accepted by QBrush - * @property {QColor} linesColor The color of the lines. - * @example -// This example function creates a menu full of generated push buttons with callbacks, but any type of widget can be added. -// Normally it doesn't make sense to create buttons this way, and they will be created one by one to cater to specific needs, -// such as launching Harmony actions, or scripts, etc. Assign this function to a shortcut by creating a Harmony Package for it. - -function openMenu(){ - MessageLog.clearLog() - - // we create a list of tool widgets for our submenu - var toolSubMenuWidgets = [ - new $.oToolButton("select"), - new $.oToolButton("brush"), - new $.oToolButton("pencil"), - new $.oToolButton("eraser"), - ]; - // we initialise our submenu - var toolSubMenu = new $.oPieSubMenu("tools", toolSubMenuWidgets); - - // we create a list of tool widgets for our submenu - // (check out the scripts from http://raindropmoment.com and http://www.cartoonflow.com, they are great!) - var ScriptSubMenuWidgets = [ - new $.oScriptButton(specialFolders.userScripts + "/CF_CopyPastePivots_1.0.1.js", "CF_CopyPastePivots" ), - new $.oScriptButton(specialFolders.userScripts + "/ANM_Paste_In_Place.js", "ANM_Paste_In_Place"), - new $.oScriptButton(specialFolders.userScripts + "/ANM_Set_Layer_Pivots_At_Center_Of_Drawings.js", "ANM_Set_Layer_Pivots_At_Center_Of_Drawings"), - new $.oScriptButton(specialFolders.userScripts + "/DEF_Copy_Deformation_Values_To_Resting.js", "DEF_Copy_Deformation_Values_To_Resting"), - ]; - var scriptsSubMenu = new $.oPieSubMenu("scripts", ScriptSubMenuWidgets); - - // we create a list of color widgets for our submenu - var colorSubMenuWidgets = [] - var currentPalette = $.scn.selectedPalette - var colors = currentPalette.colors - for (var i in colors){ - colorSubMenuWidgets.push(new $.oColorButton(currentPalette.name, colors[i].name)); - } - var colorSubMenu = new $.oPieSubMenu("colors", colorSubMenuWidgets); - - onionSkinSlider = new QSlider(Qt.Horizontal) - onionSkinSlider.minimum = 0; - onionSkinSlider.maximum = 256; - onionSkinSlider.valueChanged.connect(function(value){ - preferences.setDouble("DRAWING_ONIONSKIN_MAX_OPACITY", - value/256.0); - view.refreshViews(); - }) - - // widgets that will appear in the main menu - var mainWidgets = [ - onionSkinSlider, - toolSubMenu, - colorSubMenu, - scriptsSubMenu - ] - - // we initialise our main menu. The numerical values are for the minimum and maximum angle of the - // circle in multiples of Pi. Going clockwise, 0 is right, 1 is left, -0.5 is the bottom from the right, - // and 1.5 is the bottom from the left side. 0.5 is the top of the circle. - var menu = new $.oPieMenu("menu", mainWidgets, false, -0.2, 1.2); - - // configurating the look of it - // var backgroundGradient = new QRadialGradient (menu.center, menu.maxRadius); - // var menuBg = menu.backgroundColor - // backgroundGradient.setColorAt(1, new QColor(menuBg.red(), menuBg.green(), menuBg.blue(), 255)); - // backgroundGradient.setColorAt(0, menuBg); - - // var sliceGradient = new QRadialGradient (menu.center, menu.maxRadius); - // var menuColor = menu.sliceColor - // sliceGradient.setColorAt(1, new QColor(menuColor.red(), menuColor.green(), menuColor.blue(), 20)); - // sliceGradient.setColorAt(0, menuColor); - - // menu.backgroundColor = backgroundGradient - // menu.sliceColor = sliceGradient - - // we show it! - menu.show(); -}*/ -$.oPieMenu = function( name, widgets, show, minAngle, maxAngle, radius, position, parent){ - this.name = name; - this.widgets = widgets; - - if (typeof minAngle === 'undefined') var minAngle = 0; - if (typeof maxAngle === 'undefined') var maxAngle = 1; - if (typeof radius === 'undefined') var radius = this.getMenuRadius(); - if (typeof position === 'undefined') var position = this.$.app.globalMousePosition; - if (typeof show === 'undefined') var show = false; - if (typeof parent === 'undefined') var parent = this.$.app.mainWindow; - this._parent = parent; - - // close all previously opened piemenu widgets - if (!$._piemenu) $._piemenu = [] - while ($._piemenu.length){ - var pie = $._piemenu.pop(); - if (pie){ - // a menu was already open, we close it - pie.closeMenu() - } - } - - QWidget.call(this, parent) - this.objectName = "pieMenu_" + name; - $._piemenu.push(this) - - this.radius = radius; - this.minAngle = minAngle; - this.maxAngle = maxAngle; - this.globalCenter = position; - - // how wide outside the icons is the slice drawn - this._circleMargin = 30; - - // set these values before calling show() to customize the menu appearance - this.sliceColor = new QColor(0, 200, 255, 200); - this.backgroundColor = new QColor(40, 40, 40, 180); - this.linesColor = new QColor(0,0,0,0); - - // create main button - this.button = this.buildButton() - - // add buildWidget call before show(), - // for some reason show() is not in QWidget.prototype ? - this.qWidgetShow = this.show - this.show = function(){ - this.buildWidget() - } - - this.focusPolicy = Qt.StrongFocus; - this.focusOutEvent = function(){ - this.deactivate() - } - - var menu = this; - this.button.clicked.connect(function(){return menu.deactivate()}) - - if (show) this.show(); -} -$.oPieMenu.prototype = Object.create(QWidget.prototype); - - -/** - * function run when the menu button is clicked - */ -$.oPieMenu.prototype.deactivate = function(){ - this.closeMenu() -} - -/** - * Closes the menu and all its subWidgets - * @private - */ -$.oPieMenu.prototype.closeMenu = function(){ - for (var i in this.widgets){ - this.widgets[i].close() - } - this.close(); -} - -/** - * The top left point of the entire widget - * @name $.oPieMenu#anchor - * @type {$.oPoint} - */ -Object.defineProperty($.oPieMenu.prototype, "anchor", { - get: function(){ - var point = this.globalCenter.add(-this.center.x, -this.center.y); - return point; - } -}) - - -/** - * The center of the entire widget - * @name $.oPieMenu#center - * @type {$.oPoint} - */ -Object.defineProperty($.oPieMenu.prototype, "center", { - get: function(){ - return new this.$.oPoint(this.widgetSize/2, this.widgetSize/2) - } -}) - - -/** - * The min radius of the pie background - * @name $.oPieMenu#minRadius - * @type {int} - */ -Object.defineProperty($.oPieMenu.prototype, "minRadius", { - get: function(){ - return this._circleMargin; - } -}) - - -/** - * The max radius of the pie background - * @name $.oPieMenu#maxRadius - * @type {int} - */ -Object.defineProperty($.oPieMenu.prototype, "maxRadius", { - get: function(){ - return this.radius + this._circleMargin; - } -}) - -/** - * The widget size of the pie background (it's a square so it's both the width and the height.) - * @name $.oPieMenu#widgetSize - * @type {int} - */ - Object.defineProperty($.oPieMenu.prototype, "widgetSize", { - get: function(){ - return this.maxRadius*4; - } -}) - - -/** - * Builds the menu's main button. - * @returns {$.oPieButton} - */ -$.oPieMenu.prototype.buildButton = function(){ - // add main button in constructor because it needs to exist before show() - var icon = specialFolders.resource + "/icons/brushpreset/defaultpresetellipse/ellipse03.svg" - button = new this.$.oPieButton(icon, "", this); - button.objectName = this.name+"_button"; - button.parentMenu = this; - - return button; -} - -/** - * Build and show the pie menu and its widgets. - * @private - */ -$.oPieMenu.prototype.buildWidget = function(){ - // match the widget geometry with the main window/parent - var anchor = this.anchor - this.move(anchor.x, anchor.y); - this.minimumHeight = this.maximumHeight = this.widgetSize; - this.minimumWidth = this.maximumWidth = this.widgetSize; - - var flags = new Qt.WindowFlags(Qt.Popup|Qt.FramelessWindowHint|Qt.WA_TransparentForMouseEvents); - this.setWindowFlags(flags); - this.setAttribute(Qt.WA_TranslucentBackground); - this.setAttribute(Qt.WA_DeleteOnClose); - - // draw background pie slice - this.slice = this.drawSlice(); - this.qWidgetShow() - // arrange widgets into half a circle around the center - var center = this.center; - - for (var i=0; i < this.widgets.length; i++){ - var widget = this.widgets[i]; - widget.pieIndex = i; - widget.setParent(this); - - var itemPosition = this.getItemPosition(i); - var widgetPosition = new this.$.oPoint(center.x + itemPosition.x, center.y + itemPosition.y); - - widget.show(); - widget.move(widgetPosition.x - widget.width/2, widgetPosition.y - widget.height/2); - } - - this.button.show(); - this.button.move(center.x - (this.button.width/2), center.y - (this.button.height/2)); -} - - -/** - * draws a background transparent slice and set up the mouse tracking. - * @param {int} [minRadius] specify a minimum radius for the slice - * @private - */ -$.oPieMenu.prototype.drawSlice = function(){ - var index = 0; - - // get the slice and background geometry - var center = this.center; - var angleSlice = this.getItemAngleRange(index); - var slicePath = this.getSlicePath(center, angleSlice[0], angleSlice[1], this.minRadius, this.maxRadius); - var contactPath = this.getSlicePath(center, this.minAngle, this.maxAngle, this.minRadius, this.maxRadius); - - // create a widget to paint into - var sliceWidget = new QWidget(this); - sliceWidget.objectName = "slice"; - // make widget background invisible - sliceWidget.setStyleSheet("background-color: rgba(0, 0, 0, 0.5%);"); - var flags = new Qt.WindowFlags(Qt.FramelessWindowHint); - sliceWidget.setWindowFlags(flags) - sliceWidget.minimumHeight = this.height; - sliceWidget.minimumWidth = this.width; - sliceWidget.lower(); - - var sliceWidth = angleSlice[1]-angleSlice[0]; - - // painting the slice on sliceWidget.update() - var sliceColor = this.sliceColor; - var backgroundColor = this.backgroundColor; - var linesColor = this.linesColor; - - sliceWidget.paintEvent = function(){ - var painter = new QPainter(); - painter.save(); - painter.begin(sliceWidget); - - // draw background - painter.setRenderHint(QPainter.Antialiasing); - painter.setPen(new QPen(linesColor)); - painter.setBrush(new QBrush(backgroundColor)); - - painter.drawPath(contactPath); - - // draw slice and rotate around widget center - painter.translate(center.x, center.y); - painter.rotate(sliceWidth*index*(-180)); - painter.translate(-center.x, -center.y); - painter.setPen(new QPen(linesColor)); - painter.setBrush(new QBrush(sliceColor)); - painter.drawPath(slicePath); - painter.end(); - painter.restore(); - } - - //set up automatic following of the mouse - sliceWidget.mouseTracking = true; - - var pieMenu = this; - var currentDistance = false; - sliceWidget.mouseMoveEvent = function(mousePos){ - // work out the index based on relative position to the center - var position = new pieMenu.$.oPoint(mousePos.x(), mousePos.y()); - var angle = -position.add(-center.x, -center.y).polarCoordinates.angle/Math.PI; - if (angle < (-0.5)) angle += 2; // our coordinates system uses continuous angle values with cutoff at the bottom (1.5/-0.5) - var currentIndex = pieMenu.getIndexAtAngle(angle); - var distance = position.distance(center); - - // on distance value change, if the distance is greater than the maxRadius, activate the widget - var indexChanged = (index != currentIndex) - var indexWithinRange = (currentIndex >= 0 && currentIndex < pieMenu.widgets.length) - var distanceWithinRange = (distance > pieMenu.minRadius && distance < pieMenu.maxRadius) - var distanceChanged = (distanceWithinRange != currentDistance) - - // react to distance/angle change when the mouse moves on the pieMenu - if (indexWithinRange){ - var indexWidget = pieMenu.widgets[currentIndex]; - - if (indexChanged && distance < pieMenu.maxRadius){ - index = currentIndex; - sliceWidget.update(); - indexWidget.setFocus(true); - } - - if (distanceChanged){ - currentDistance = distanceWithinRange; - if (distance > pieMenu.maxRadius){ - // activate the button - if (indexWidget.activate) indexWidget.activate(); - }else if (distance < pieMenu.minRadius){ - // cursor reentered the widget: close the subMenu - if (indexWidget.deactivate) indexWidget.deactivate(); - } - if (distance < pieMenu.minRadius){ - if (pieMenu.deactivate) pieMenu.deactivate(); - } - } - } - } - - return sliceWidget; -} - - -/** - * Generate a pie slice path to draw based on parameters - * @param {$.oPoint} center the center of the slice - * @param {float} minAngle a value between -0.5 and 1.5 for the lowest angle value for the pie slice - * @param {float} maxAngle a value between -0.5 and 1.5 for the highest angle value for the pie slice - * @param {float} minRadius the smallest circle radius - * @param {float} maxRadius the largest circle radius - * @private - */ -$.oPieMenu.prototype.getSlicePath = function(center, minAngle, maxAngle, minRadius, maxRadius){ - // work out the geometry - var smallArcBoundingBox = new QRectF(center.x-minRadius, center.y-minRadius, minRadius*2, minRadius*2); - var smallArcStart = new this.$.oPoint(); - smallArcStart.polarCoordinates = {radius: minRadius, angle:minAngle*(-Math.PI)} - smallArcStart.translate(center.x, center.y); - var smallArcAngleStart = minAngle*180; - var smallArcSweep = (maxAngle-minAngle)*180; // convert values from 0-2 (radiant angles in multiples of pi) to degrees - - var bigArcBoundingBox = new QRectF(center.x-maxRadius, center.y-maxRadius, maxRadius*2, maxRadius*2); - var bigArcAngleStart = maxAngle*180; - var bigArcSweep = -smallArcSweep; - - // we draw the slice path - var slicePath = new QPainterPath; - slicePath.moveTo(new QPointF(smallArcStart.x, smallArcStart.y)); - slicePath.arcTo(smallArcBoundingBox, smallArcAngleStart, smallArcSweep); - slicePath.arcTo(bigArcBoundingBox, bigArcAngleStart, bigArcSweep); - - return slicePath; -} - - -/** - * Get the angle range for the item pie slice based on index. - * @private - * @param {int} index the index of the widget - * @return {float[]} - */ -$.oPieMenu.prototype.getItemAngleRange = function(index){ - var length = this.widgets.length; - var angleStart = this.minAngle+(index/length)*(this.maxAngle-this.minAngle); - var angleEnd = this.minAngle+((index+1)/length)*(this.maxAngle-this.minAngle); - - return [angleStart, angleEnd]; -} - -/** - * Get the angle for the item widget based on index. - * @private - * @param {int} index the index of the widget - * @return {float} - */ -$.oPieMenu.prototype.getItemAngle = function(index){ - var angleRange = this.getItemAngleRange(index, this.minAngle, this.maxAngle); - var angle = (angleRange[1] - angleRange[0])/2+angleRange[0] - - return angle; -} - - -/** - * Get the widget index for the angle value. - * @private - * @param {float} angle the index of the widget - * @return {float} - */ -$.oPieMenu.prototype.getIndexAtAngle = function(angle){ - var angleRange = (this.maxAngle-this.minAngle)/this.widgets.length - return Math.floor((angle-this.minAngle)/angleRange); -} - - -/** - * Get the position from the center for the item based on index. - * @private - * @param {int} index the index of the widget - * @return {$.oPoint} - */ -$.oPieMenu.prototype.getItemPosition = function(index){ - // we add pi to the angle because of the inverted Y axis of widgets coordinates - var pi = Math.PI; - var angle = this.getItemAngle(index, this.minAngle, this.maxAngle)*(-pi); - var _point = new this.$.oPoint(); - _point.polarCoordinates = {radius:this.radius, angle:angle} - - return _point; -} - - -/** - * Get a pie menu radius setting for a given amount of items. - * @private - * @return {float} - */ -$.oPieMenu.prototype.getMenuRadius = function(){ - var itemsNumber = this.widgets.length - var _maxRadius = UiLoader.dpiScale(200); - var _minRadius = UiLoader.dpiScale(30); - var _speed = 10; // the higher the value, the slower the progression - - // hyperbolic tangent function to determine the radius - var exp = Math.exp(2*itemsNumber/_speed); - var _radius = ((exp-1)/(exp+1))*_maxRadius+_minRadius; - - return _radius; -} - - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oPieSubMenu class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * The $.oPieSubMenu constructor. - * @name $.oPieSubMenu - * @constructor - * @classdesc A menu with more options that opens/closes when the user clicks on the button. - * @param {string} name The name for this pie Menu. - * @param {QWidget[]} [widgets] The widgets to display in the menu. - * - * @property {string} name The name for this pie Menu. - * @property {string} widgets The widgets to display in the menu. - * @property {string} menu The oPieMenu Object containing the widgets for the submenu - * @property {string} itemAngle a set angle for each items instead of spreading them across the entire circle - * @property {string} extraRadius using a set radius between each submenu levels - * @property {$.oPieMenu} parentMenu the parent menu for this subMenu. Set during initialisation of the menu. - */ -$.oPieSubMenu = function(name, widgets) { - this.menuIcon = specialFolders.resource + "/icons/toolbar/menu.svg"; - this.closeIcon = specialFolders.resource + "/icons/toolbar/collapseopen.png"; - - // min/max angle and radius will be set from parent during buildWidget() - this.$.oPieMenu.call(this, name, widgets, false); - - // change these settings before calling show() to modify the look of the pieSubMenu - this.itemAngle = 0.06; - this.extraRadius = UiLoader.dpiScale(80); - this.parentMenu = undefined; - - this.focusOutEvent = function(){} // delete focusOutEvent response from submenu -} -$.oPieSubMenu.prototype = Object.create($.oPieMenu.prototype) - - -/** - * function called when main button is clicked - */ -$.oPieSubMenu.prototype.deactivate = function(){ - this.toggleMenu() -} - -/** - * The top left point of the entire widget - * @name $.oPieSubMenu#anchor - * @type {$.oPoint} - */ -Object.defineProperty($.oPieSubMenu.prototype, "anchor", { - get: function(){ - var center = this.parentMenu.globalCenter; - return center.add(-this.widgetSize/2, -this.widgetSize/2); - } -}) - - -/** - * The min radius of the pie background - * @name $.oPieSubMenu#minRadius - * @type {int} - */ -Object.defineProperty($.oPieSubMenu.prototype, "minRadius", { - get: function(){ - return this.parentMenu.maxRadius; - } -}) - - -/** - * The max radius of the pie background - * @name $.oPieSubMenu#maxRadius - * @type {int} - */ -Object.defineProperty($.oPieSubMenu.prototype, "maxRadius", { - get: function(){ - return this.minRadius + this.extraRadius; - } -}) - - -/** - * activate the menu button when activate() is called on the menu - * @private - */ -$.oPieSubMenu.prototype.activate = function(){ - this.showMenu(true); - this.setFocus(true) -} - - -/** - * In order for pieSubMenus to behave like other pie widgets, we reimplement - * move() so that it only moves the button, and the slice will remain aligned with - * the parent. - * @param {int} x The x coordinate for the button relative to the piewidget - * @param {int} y The x coordinate for the button relative to the piewidget - * @private - */ -$.oPieSubMenu.prototype.move = function(x, y){ - // move the actual widget to its anchor, but move the button instead - QWidget.prototype.move.call(this, this.anchor.x, this.anchor.y); - - // calculate the actual position for the button as if it was a child of the pieMenu - // whereas it uses global coordinates - var buttonPos = new this.$.oPoint(x, y) - var parentAnchor = this.parentMenu.anchor; - var anchorDiff = parentAnchor.add(-this.anchor.x, -this.anchor.y) - var localPos = buttonPos.add(anchorDiff.x, anchorDiff.y) - - // move() is used by the pieMenu with half the widget size to center the button, so we have to cancel it out - this.button.move(localPos.x+this.widgetSize/2-this.button.width/2, localPos.y+this.widgetSize/2-this.button.height/2 ); -} - - -/** - * sets a parent and assigns it to this.parentMenu. - * using the normal setParent from QPushButton creates a weird bug - * where calling parent() returns a QWidget and not a $.oPieButton - * @private - */ -$.oPieSubMenu.prototype.setParent = function(parent){ - $.oPieMenu.prototype.setParent.call(this, parent); - this.parentMenu = parent; -} - - -/** - * build the main button for the menu - * @private - * @returns {$.oPieButton} - */ -$.oPieSubMenu.prototype.buildButton = function(){ - // add main button in constructor because it needs to exist before show() - var button = new this.$.oPieButton(this.menuIcon, this.name, this); - button.objectName = this.name+"_button"; - - return button; -} - - -/** - * Shows or hides the menu itself (not the button) - * @param {*} visibility - */ -$.oPieSubMenu.prototype.showMenu = function(visibility){ - this.slice.visible = visibility; - for (var i in this.widgets){ - this.widgets[i].visible = visibility; - } - var icon = visibility?this.closeIcon:this.menuIcon; - UiLoader.setSvgIcon(this.button, icon); -} - - -/** - * toggles the display of the menu - */ -$.oPieSubMenu.prototype.toggleMenu = function(){ - this.showMenu(!this.slice.visible); -} - -/** - * Function to initialise the widgets for the submenu - * @private - */ -$.oPieSubMenu.prototype.buildWidget = function(){ - if (!this.parentMenu){ - throw new Error("must set parent first before calling $.oPieMenu.buildWidget()") - } - parentWidget = this.parentMenu; - - // submenu widgets calculate their range from to go on both sides of the button, at a fixed angle - // (in order to keep the span of submenu options centered around the menu button) - var widgetNum = this.widgets.length/2; - var angle = parentWidget.getItemAngle(this.pieIndex); - - // create the submenu on top of the main menu - this.radius = parentWidget.radius+this.extraRadius; - this.minAngle = angle-widgetNum*this.itemAngle; - this.maxAngle = angle+widgetNum*this.itemAngle; - - $.oPieMenu.prototype.buildWidget.call(this); - - this.showMenu(false) -} - - - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oPieButton class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * The constructor for $.oPieButton - * @constructor - * @classdesc This subclass of QPushButton provides an easy way to create a button for a PieMenu.
- * - * This class is a subclass of QPushButton and all the methods from that class are available to modify this button. - * @param {string} iconFile The icon file for the button - * @param {string} text A text to display next to the icon - * @param {QWidget} parent The parent QWidget for the button. Automatically set during initialisation of the menu. - * - */ - $.oPieButton = function(iconFile, text, parent) { - // if icon isnt provided - if (typeof parent === 'undefined') var parent = $.app.mainWindow - if (typeof text === 'undefined') var text = "" - if (typeof iconFile === 'undefined') var iconFile = specialFolders.resource+"/icons/script/qtgeneric.svg" - - QPushButton.call(this, text, parent); - - this.minimumHeight = 24; - this.minimumWidth = 24; - - // set during addition to the pie Menu - this.pieIndex = undefined; - - UiLoader.setSvgIcon(this, iconFile) - this.setIconSize(new QSize(this.minimumWidth, this.minimumHeight)); - this.cursor = new QCursor(Qt.PointingHandCursor); - - var styleSheet = "QPushButton{ background-color: rgba(0, 0, 0, 1%); }" + - "QPushButton:hover{ background-color: rgba(0, 200, 255, 80%); }"+ - "QToolTip{ background-color: rgba(0, 255, 255, 100%); }" - this.setStyleSheet(styleSheet); - - var button = this; - this.clicked.connect(function(){button.activate()}) -} -$.oPieButton.prototype = Object.create(QPushButton.prototype); - - -/** - * Closes the parent menu of the button and all its subWidgets. - */ -$.oPieButton.prototype.closeMenu = function(){ - var menu = this.parentMenu; - while (menu && menu.parentMenu){ - menu = menu.parentMenu; - } - menu.closeMenu() -} - -/** - * Reimplement this function in order to activate the button and also close the menu. - */ -$.oPieButton.prototype.activate = function(){ - // reimplement to change the behavior when the button is activated. - // by default, will just close the menu. - this.closeMenu(); -} - - -/** - * sets a parent and assigns it to this.parentMenu. - * using the normal setParent from QPushButton creates a weird bug - * where calling parent() returns a QWidget and not a $.oPieButton - * @private - */ -$.oPieButton.prototype.setParent = function(parent){ - QPushButton.prototype.setParent.call(this, parent); - this.parentMenu = parent; -} - - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oToolButton class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * The constructor for $.oToolButton - * @name $.oToolButton - * @constructor - * @classdescription This subclass of QPushButton provides an easy way to create a button for a tool. - * This class is a subclass of QPushButton and all the methods from that class are available to modify this button. - * @param {string} toolName The path to the script file that will be launched - * @param {string} scriptFunction The function name to launch from the script - * @param {QWidget} parent The parent QWidget for the button. Automatically set during initialisation of the menu. - * - */ - $.oToolButton = function(toolName, iconFile, parent) { - this.toolName = toolName; - - if (typeof iconFile === "undefined"){ - // find an icon for the function in the script-icons folder - var scriptIconsFolder = new this.$.oFolder(specialFolders.resource+"/icons/drawingtool"); - var iconFiles = scriptIconsFolder.getFiles(toolName.replace(" ", "").toLowerCase() + ".*"); - - if (iconFiles.length > 0){ - var iconFile = iconFiles[0].path; - }else{ - // choose default toonboom "missing icon" script icon - // currently svg icons seem unsupported? - var iconFile = specialFolders.resource+"/icons/script/qtgeneric.svg"; - } - } - this.$.oPieButton.call(this, iconFile, parent); - - this.toolTip = this.toolName; -} -$.oToolButton.prototype = Object.create($.oPieButton.prototype); - - -$.oToolButton.prototype.activate = function(){ - this.$.app.currentTool = this.toolName; - this.closeMenu() -} - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oActionButton class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * The constructor for $.oActionButton - * @name $.oActionButton - * @constructor - * @classdescription This subclass of QPushButton provides an easy way to create a button for a tool. - * This class is a subclass of QPushButton and all the methods from that class are available to modify this button. - * @param {string} actionName The action string that will be executed with Action.perform - * @param {string} responder The responder for the action - * @param {string} text A text for the button display. - * @param {string} iconFile An icon path for the button. - * @param {QWidget} parent The parent QWidget for the button. Automatically set during initialisation of the menu. - */ - $.oActionButton = function(actionName, responder, text, iconFile, parent) { - this.action = actionName; - this.responder = responder; - - if (typeof text === 'undefined') var text = "action"; - - if (typeof iconFile === 'undefined') var iconFile = specialFolders.resource+"/icons/old/exec.png"; - - this.$.oPieButton.call(this, iconFile, text, parent); - this.toolTip = this.toolName; -} -$.oActionButton.prototype = Object.create($.oPieButton.prototype); - - -$.oActionButton.prototype.activate = function(){ - if (this.responder){ - // log("Validating : "+ this.actionName + " ? "+ Action.validate(this.actionName, this.responder).enabled) - if (Action.validate(this.action, this.responder).enabled){ - Action.perform(this.action, this.responder); - } - }else{ - if (Action.Validate(this.action).enabled){ - Action.perform(this.action); - } - } - view.refreshViews(); - this.closeMenu() -} - - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oColorButton class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * The constructor for $.oColorButton - * @name $.oColorButton - * @constructor - * @classdescription This subclass of QPushButton provides an easy way to create a button to choose a color from a palette. - * This class is a subclass of QPushButton and all the methods from that class are available to modify this button. - * @param {string} paletteName The name of the palette that contains the color - * @param {string} colorName The name of the color (if more than one is present, will pick the first match) - * @param {bool} showName Whether to display the name of the color on the button - * @param {QWidget} parent The parent QWidget for the button. Automatically set during initialisation of the menu. - * - */ - $.oColorButton = function(paletteName, colorName, showName, parent) { - this.paletteName = paletteName; - this.colorName = colorName; - - if (typeof showName === "undefined") var showName = false; - - this.$.oPieButton.call(this, "", showName?colorName:"", parent); - - var palette = this.$.scn.getPaletteByName(paletteName); - var color = palette.getColorByName(colorName); - var colorValue = color.value - - var iconMap = new QPixmap(this.minimumHeight,this.minimumHeight) - iconMap.fill(new QColor(colorValue.r, colorValue.g, colorValue.b, colorValue.a)) - var icon = new QIcon(iconMap); - - this.icon = icon; - - this.toolTip = this.paletteName + ": " + this.colorName; -} -$.oColorButton.prototype = Object.create($.oPieButton.prototype); - - -$.oColorButton.prototype.activate = function(){ - var palette = this.$.scn.getPaletteByName(this.paletteName); - var color = palette.getColorByName(this.colorName); - - this.$.scn.currentPalette = palette; - palette.currentColor = color; - this.closeMenu() -} - - - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oScriptButton class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * The constructor for $.oScriptButton - * @name $.oScriptButton - * @constructor - * @classdescription This subclass of QPushButton provides an easy way to create a button for a widget that will launch a function from another script file.
- * The buttons created this way automatically load the icon named after the script if it finds one named like the function in a script-icons folder next to the script file.
- * It will also automatically set the callback to lanch the function from the script.
- * This class is a subclass of QPushButton and all the methods from that class are available to modify this button. - * @param {string} scriptFile The path to the script file that will be launched - * @param {string} scriptFunction The function name to launch from the script - * @param {QWidget} parent The parent QWidget for the button. Automatically set during initialisation of the menu. - */ -$.oScriptButton = function(scriptFile, scriptFunction, parent) { - this.scriptFile = scriptFile; - this.scriptFunction = scriptFunction; - - // find an icon for the function in the script-icons folder - var scriptFile = new this.$.oFile(scriptFile) - var scriptIconsFolder = new this.$.oFolder(scriptFile.folder.path+"/script-icons"); - var iconFiles = scriptIconsFolder.getFiles(scriptFunction+".*"); - if (iconFiles.length > 0){ - var iconFile = iconFiles[0].path; - }else{ - // choose default toonboom "missing icon" script icon - // currently svg icons seem unsupported? - var iconFile = specialFolders.resource+"/icons/script/qtgeneric.svg"; - } - - this.$.oPieButton.call(this, iconFile, "", parent); - - this.toolTip = this.scriptFunction; -} -$.oScriptButton.prototype = Object.create($.oPieButton.prototype); - -$.oScriptButton.prototype.activate = function(){ - include(this.scriptFile); - eval(this.scriptFunction)(); - this.closeMenu() -} - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oPrefButton class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * The constructor for $.oPrefButton - * @name $.oPrefButton - * @constructor - * @classdescription This subclass of QPushButton provides an easy way to create a button to change a boolean preference. - * This class is a subclass of QPushButton and all the methods from that class are available to modify this button. - * @param {string} preferenceString The name of the preference to show/change. - * @param {string} text A text for the button display. - * @param {string} iconFile An icon path for the button. - * @param {QWidget} parent The parent QWidget for the button. Automatically set during initialisation of the menu. - */ -$.oPrefButton = function(preferenceString, text, iconFile, parent) { - this.preferenceString = preferenceString; - - if (typeof iconFile === 'undefined') var iconFile = specialFolders.resource+"/icons/toolproperties/settings.svg"; - this.checkable = true; - this.checked = preferences.getBool(preferenceString, true); - - $.oPieButton.call(this, iconFile, text, parent); - - this.toolTip = this.preferenceString; -} -$.oPrefButton.prototype = Object.create($.oPieButton.prototype); - - -$.oPrefButton.prototype.activate = function(){ - var value = preferences.getBool(this.preferenceString, true); - this.checked != value; - preferences.setBool(this.preferenceString, value); - this.closeMenu() -} - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oStencilButton class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -// not currently working -$.oStencilButton = function(stencilName, parent) { - this.stencilName = stencilName; - - var iconFile = specialFolders.resource+"/icons/brushpreset/default.svg"; - - $.oPieButton.call(this, iconFile, stencilName, parent); - - this.toolTip = stencilName; -} -$.oStencilButton.prototype = Object.create($.oPieButton.prototype); - -$.oStencilButton.prototype.activate = function(){ - this.$.app.currentStencil = this.stencilName; - - this.closeMenu() -} diff --git a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_drawing.js b/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_drawing.js deleted file mode 100644 index 6f2bc19c0c..0000000000 --- a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_drawing.js +++ /dev/null @@ -1,2181 +0,0 @@ -////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// -// -// openHarmony Library -// -// -// Developed by Mathieu Chaptel, Chris Fourney -// -// -// This library is an open source implementation of a Document Object Model -// for Toonboom Harmony. It also implements patterns similar to JQuery -// for traversing this DOM. -// -// Its intended purpose is to simplify and streamline toonboom scripting to -// empower users and be easy on newcomers, with default parameters values, -// and by hiding the heavy lifting required by the official API. -// -// This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is guaranteed to work. Feel free to contribute -// improvements to its official github. If you do make sure you follow the provided -// template and naming conventions and document your new methods properly. -// -// This library doesn't overwrite any of the objects and classes of the official -// Toonboom API which must remains available. -// -// This library is made available under the Mozilla Public license 2.0. -// https://www.mozilla.org/en-US/MPL/2.0/ -// -// The repository for this library is available at the address: -// https://github.com/cfourney/OpenHarmony/ -// -// -// For any requests feel free to contact m.chaptel@gmail.com -// -// -// -// -////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oDrawing class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * The $.oDrawing constructor. - * @constructor - * @classdesc The $.oDrawing Class represents a single drawing from an element. - * @param {int} name The name of the drawing. - * @param {$.oElement} oElementObject The element object associated to the element. - * - * @property {int} name The name of the drawing. - * @property {$.oElement} element The element object associated to the element. - */ -$.oDrawing = function (name, oElementObject) { - this._type = "drawing"; - this._name = name; - this.element = oElementObject; - - this._key = Drawing.Key({ - elementId: oElementObject.id, - exposure: name - }); - - //log(JSON.stringify(this._key)) - - this._overlay = new this.$.oArtLayer(3, this); - this._lineArt = new this.$.oArtLayer(2, this); - this._colorArt = new this.$.oArtLayer(1, this); - this._underlay = new this.$.oArtLayer(0, this); - this._artLayers = [this._underlay, this._colorArt, this._lineArt, this._overlay]; -} - - -/** - * The different types of lines ends. - * @name $.oDrawing#LINE_END_TYPE - * @enum - */ -$.oDrawing.LINE_END_TYPE = { - ROUND: 1, - FLAT: 2, - BEVEL: 3 -}; - - -/** - * The reference to the art layers to use with oDrawing.setAsActiveDrawing() - * @name $.oDrawing#ART_LAYER - * @enum - */ -$.oDrawing.ART_LAYER = { - OVERLAY: 8, - LINEART: 4, - COLORART: 2, - UNDERLAY: 1 -}; - - -/** - * The name of the drawing. - * @name $.oDrawing#name - * @type {string} - */ -Object.defineProperty($.oDrawing.prototype, 'name', { - get: function () { - return this._name; - }, - - set: function (newName) { - if (this._name == newName) return; - - var _column = this.element.column.uniqueName; - // this ripples recursively - - if (Drawing.isExists(this.element.id, newName)) this.element.getDrawingByName(newName).name = newName + "_1"; - column.renameDrawing(_column, this._name, newName); - this._name = newName; - } -}) - - -/** - * The internal Id used to identify drawings. - * @name $.oDrawing#id - * @readonly - * @type {int} - */ -Object.defineProperty($.oDrawing.prototype, 'id', { - get: function () { - return this._key.drawingId; - } -}) - - -/** - * The folder path of the drawing on the filesystem. - * @name $.oDrawing#path - * @readonly - * @type {string} - */ -Object.defineProperty($.oDrawing.prototype, 'path', { - get: function () { - return fileMapper.toNativePath(Drawing.filename(this.element.id, this.name)) - } -}) - - -/** - * The drawing pivot of the drawing. - * @name $.oDrawing#pivot - * @type {$.oPoint} - */ -Object.defineProperty($.oDrawing.prototype, 'pivot', { - get: function () { - if (this.$.batchMode){ - throw new Error("oDrawing.pivot is not available in batch mode.") - } - - var _pivot = Drawing.getPivot({ "drawing": this._key }); - return new this.$.oPoint(_pivot.x, _pivot.y, 0); - }, - - set: function (newPivot) { - var _pivot = { x: newPivot.x, y: newPivot.y }; - Drawing.setPivot({ drawing: this._key, pivot: _pivot }); - } -}) - - -/** - * The color Ids present on the drawing. - * @name $.oDrawing#usedColorIds - * @type {string[]} - */ -Object.defineProperty($.oDrawing.prototype, 'usedColorIds', { - get: function () { - var _colorIds = DrawingTools.getDrawingUsedColors(this._key); - return _colorIds; - } -}) - - -/** - * The bounding box of the drawing, in drawing space coordinates. (null if the drawing is empty.) - * @name $.oDrawing#boundingBox - * @readonly - * @type {$.oBox} - */ -Object.defineProperty($.oDrawing.prototype, 'boundingBox', { - get: function () { - if (this.$.batchMode){ - throw new Error("oDrawing.boudingBox is not available in batch mode.") - } - - var _box = new this.$.oBox() - for (var i in this.artLayers) { - var _layerBox = this.artLayers[i].boundingBox - if (_layerBox) _box.include(_layerBox) - } - - return _box - } -}) - - -/** - * Access the underlay art layer's content through this object. - * @name $.oDrawing#underlay - * @readonly - * @type {$.oArtLayer} - */ -Object.defineProperty($.oDrawing.prototype, 'underlay', { - get: function () { - return this._underlay; - } -}) - - -/** - * Access the color art layer's content through this object. - * @name $.oDrawing#colorArt - * @readonly - * @type {$.oArtLayer} - */ -Object.defineProperty($.oDrawing.prototype, 'colorArt', { - get: function () { - return this._colorArt; - } -}) - - -/** - * Access the line art layer's content through this object. - * @name $.oDrawing#lineArt - * @readonly - * @type {$.oArtLayer} - */ -Object.defineProperty($.oDrawing.prototype, 'lineArt', { - get: function () { - return this._lineArt; - } -}) - - -/** - * Access the overlay art layer's content through this object. - * @name $.oDrawing#overlay - * @readonly - * @type {$.oArtLayer} - */ -Object.defineProperty($.oDrawing.prototype, 'overlay', { - get: function () { - return this._overlay; - } -}) - - -/** - * The list of artLayers of this drawing. - * @name $.oDrawing#artLayers - * @readonly - * @type {$.oArtLayer[]} - */ -Object.defineProperty($.oDrawing.prototype, 'artLayers', { - get: function () { - return this._artLayers; - } -}) - - - -/** - * the shapes contained amongst all artLayers of this drawing. - * @name $.oDrawing#shapes - * @readonly - * @type {$.oShape[]} - */ -Object.defineProperty($.oDrawing.prototype, 'shapes', { - get: function () { - var _shapes = []; - for (var i in this.artLayers) { - _shapes = _shapes.concat(this.artLayers[i].shapes); - } - - return _shapes; - } -}) - - -/** - * the strokes contained amongst all artLayers of this drawing. - * @name $.oDrawing#strokes - * @readonly - * @type {$.oStroke[]} - */ -Object.defineProperty($.oDrawing.prototype, 'strokes', { - get: function () { - var _strokes = []; - for (var i in this.artLayers) { - _strokes = _strokes.concat(this.artLayers[i].strokes); - } - - return _strokes; - } -}) - - -/** - * The contours contained amongst all the shapes of the artLayer. - * @name $.oDrawing#contours - * @type {$.oContour[]} - */ - Object.defineProperty($.oDrawing.prototype, 'contours', { - get: function () { - var _contours = [] - - for (var i in this.artLayers) { - _contours = _contours.concat(this.artLayers[i].contours) - } - - return _contours - } -}) - - - -/** - * the currently active art layer of this drawing. - * @name $.oDrawing#activeArtLayer - * @type {$.oArtLayer} - */ -Object.defineProperty($.oDrawing.prototype, 'activeArtLayer', { - get: function () { - var settings = Tools.getToolSettings(); - if (!settings.currentDrawing) return null; - - return this.artLayers[settings.activeArt] - }, - set: function (newArtLayer) { - var layers = this.$.oDrawing.ART_LAYER - var index = layers[newArtLayer.name.toUpperCase()] - this.setAsActiveDrawing(index); - } -}) - - -/** - * the selected shapes on this drawing - * @name $.oDrawing#selectedShapes - * @type {$.oShape} - */ -Object.defineProperty($.oDrawing.prototype, 'selectedShapes', { - get: function () { - var _selectedShapes = []; - for (var i in this.artLayers) { - _selectedShapes = _selectedShapes.concat(this.artLayers[i].selectedShapes); - } - - return _selectedShapes; - } -}) - - -/** - * the selected shapes on this drawing - * @name $.oDrawing#selectedStrokes - * @type {$.oShape} - */ -Object.defineProperty($.oDrawing.prototype, 'selectedStrokes', { - get: function () { - var _selectedStrokes = []; - for (var i in this.artLayers) { - _selectedStrokes = _selectedStrokes.concat(this.artLayers[i].selectedStrokes); - } - - return _selectedStrokes; - } -}) - - -/** - * the selected shapes on this drawing - * @name $.oDrawing#selectedContours - * @type {$.oShape} - */ -Object.defineProperty($.oDrawing.prototype, 'selectedContours', { - get: function () { - var _selectedContours = []; - for (var i in this.artLayers) { - _selectedContours = _selectedContours.concat(this.artLayers[i].selectedContours); - } - - return _selectedContours; - } -}) - - -/** - * all the data from this drawing. For internal use. - * @name $.oDrawing#drawingData - * @type {Object} - * @readonly - * @private - */ -Object.defineProperty($.oDrawing.prototype, 'drawingData', { - get: function () { - var _data = Drawing.query.getData({drawing: this._key}); - if (!_data) throw new Error("Data unavailable for drawing "+this.name) - return _data; - } -}) - - - - -// $.oDrawing Class methods - -/** - * Import a given file into an existing drawing. - * @param {$.oFile} file The path to the file - * @param {bool} [convertToTvg=false] Whether to convert the bitmap to the tvg format (this doesn't vectorise the drawing) - * - * @return { $.oFile } the oFile object pointing to the drawing file after being it has been imported into the element folder. - */ -$.oDrawing.prototype.importBitmap = function (file, convertToTvg) { - var _path = new this.$.oFile(this.path); - if (!(file instanceof this.$.oFile)) file = new this.$.oFile(file); - if (!file.exists) throw new Error ("Can't import bitmap "+file.path+", file doesn't exist"); - - if (convertToTvg && file.extension.toLowerCase() != "tvg"){ - // use utransform binary to perform conversion - var _bin = specialFolders.bin + "/utransform"; - - var tempFolder = this.$.scn.tempFolder; - - var _convertedFilePath = tempFolder.path + "/" + file.name + ".tvg"; - var _convertProcess = new this.$.oProcess(_bin, ["-outformat", "TVG", "-debug", "-scale", "1", "-bboxtvgincrease","0" , "-outfile", _convertedFilePath, file.path]); - log(_convertProcess.execute()) - - var convertedFile = new this.$.oFile(_convertedFilePath); - if (!convertedFile.exists) throw new Error ("Converting " + file.path + " to TVG has failed."); - - file = convertedFile; - } - - return file.copy(_path.folder, _path.name, true); -} - - -/** - * @returns {int[]} The frame numbers at which this drawing appears. - */ -$.oDrawing.prototype.getVisibleFrames = function () { - var _element = this.element; - var _column = _element.column; - - if (!_column) { - this.$.debug("Column missing: can't get visible frames for drawing " + this.name + " of element " + _element.name, this.$.DEBUG_LEVEL.ERROR); - return null; - } - - var _frames = []; - var _keys = _column.keyframes; - for (var i in _keys) { - if (_keys[i].value == this.name) _frames.push(_keys[i].frameNumber); - } - - return _frames; -} - - -/** - * Remove the drawing from the element. - */ -$.oDrawing.prototype.remove = function () { - var _element = this.element; - var _column = _element.column; - - if (!_column) { - throw new Error ("Column missing: impossible to delete drawing " + this.name + " of element " + _element.name); - } - - var _frames = _column.frames; - var _lastFrame = _frames.pop(); - - var _thisDrawing = this; - - // we have to expose the drawing on the column to delete it. Exposing at the last frame... - this.$.debug("deleting drawing " + _thisDrawing + " from element " + _element.name, this.$.DEBUG_LEVEL.LOG); - var _lastDrawing = _lastFrame.value; - var _keyFrame = _lastFrame.isKeyFrame; - _lastFrame.value = _thisDrawing; - - column.deleteDrawingAt(_column.uniqueName, _lastFrame.frameNumber); - - // resetting the last frame - _lastFrame.value = _lastDrawing; - _lastFrame.isKeyFrame = _keyFrame; -} - - - -/** - * refresh the preview of the drawing. - */ -$.oDrawing.prototype.refreshPreview = function () { - if (this.element.format == "TVG") return; - - var _path = new this.$.oFile(this.path); - var _elementFolder = _path.folder; - var _previewFiles = _elementFolder.getFiles(_path.name + "-*.tga"); - - for (var i in _previewFiles) { - _previewFiles[i].remove(); - } -} - - -/** -* Change the currently active drawing. Can specify an art Layer -* Doesn't work in batch mode. -* @param {oDrawing.ART_LAYER} [artLayer] activate the given art layer -* @return {bool} success of setting the drawing as current -*/ -$.oDrawing.prototype.setAsActiveDrawing = function (artLayer) { - if (this.$.batchMode) { - this.$.debug("Setting as active drawing not available in batch mode", this.$.DEBUG_LEVEL.ERROR); - return false; - } - - var _column = this.element.column; - if (!_column) { - this.$.debug("Column missing: impossible to set as active drawing " + this.name + " of element " + _element.name, this.$.DEBUG_LEVEL.ERROR); - return false; - } - - var _frame = this.getVisibleFrames(); - if (_frame.length == 0) { - this.$.debug("Drawing not exposed: impossible to set as active drawing " + this.name + " of element " + _element.name, this.$.DEBUG_LEVEL.ERROR); - return false; - } - - DrawingTools.setCurrentDrawingFromColumnName(_column.uniqueName, _frame[0]); - - if (artLayer) DrawingTools.setCurrentArt(artLayer); - - return true; -} - - -/** - * Duplicates the drawing to the given frame, and renames the drawing with the given name. - * @param {int} [frame] the frame at which to create the drawing. By default, the current frame. - * @param {string} [newName] A new name for the drawing. By default, the name will be the number of the frame. - * @returns {$.oDrawing} the newly created drawing - */ -$.oDrawing.prototype.duplicate = function(frame, newName){ - var _element = this.element - if (typeof frame ==='undefined') var frame = this.$.scn.currentFrame; - if (typeof newName === 'undefined') var newName = frame; - var newDrawing = _element.addDrawing(frame, newName, this.path) - return newDrawing; -} - -/** - * Replaces a color Id present on the drawing by another. - * @param {string} currentId - * @param {string} newId - */ -$.oDrawing.prototype.replaceColorId = function (currentId, newId){ - DrawingTools.recolorDrawing( this._key, [{from:currentId, to:newId}]); -} - - -/** - * Copies the contents of the Drawing into the clipboard - * @param {oDrawing.ART_LAYER} [artLayer] Specify to only copy the contents of the specified artLayer - */ -$.oDrawing.prototype.copyContents = function (artLayer) { - - var _current = this.setAsActiveDrawing(artLayer); - if (!_current) { - this.$.debug("Impossible to copy contents of drawing " + this.name + " of element " + _element.name + ", the drawing cannot be set as active.", this.DEBUG_LEVEL.ERROR); - return; - } - ToolProperties.setApplyAllArts(!artLayer); - Action.perform("deselect()", "cameraView"); - Action.perform("onActionChooseSelectTool()"); - Action.perform("selectAll()", "cameraView"); - - if (Action.validate("copy()", "cameraView").enabled) Action.perform("copy()", "cameraView"); -} - - -/** - * Pastes the contents of the clipboard into the Drawing - * @param {oDrawing.ART_LAYER} [artLayer] Specify to only paste the contents onto the specified artLayer - */ -$.oDrawing.prototype.pasteContents = function (artLayer) { - - var _current = this.setAsActiveDrawing(artLayer); - if (!_current) { - this.$.debug("Impossible to copy contents of drawing " + this.name + " of element " + _element.name + ", the drawing cannot be set as active.", this.DEBUG_LEVEL.ERROR); - return; - } - ToolProperties.setApplyAllArts(!artLayer); - Action.perform("deselect()", "cameraView"); - Action.perform("onActionChooseSelectTool()"); - if (Action.validate("paste()", "cameraView").enabled) Action.perform("paste()", "cameraView"); -} - - -/** -* Converts the line ends of the Drawing object to the defined type. -* Doesn't work in batch mode. This function modifies the selection. -* -* @param {oDrawing.LINE_END_TYPE} endType the type of line ends to set. -* @param {oDrawing.ART_LAYER} [artLayer] only apply to provided art Layer. -*/ -$.oDrawing.prototype.setLineEnds = function (endType, artLayer) { - if (this.$.batchMode) { - this.$.debug("setting line ends not available in batch mode", this.DEBUG_LEVEL.ERROR); - return; - } - - var _current = this.setAsActiveDrawing(artLayer); - if (!_current) { - this.$.debug("Impossible to change line ends on drawing " + this.name + " of element " + _element.name + ", the drawing cannot be set as active.", this.DEBUG_LEVEL.ERROR); - return; - } - - // apply to all arts only if art layer not specified - ToolProperties.setApplyAllArts(!artLayer); - Action.perform("deselect()", "cameraView"); - Action.perform("onActionChooseSelectTool()"); - Action.perform("selectAll()", "cameraView"); - - var widget = $.getHarmonyUIWidget("pencilShape", "frameBrushParameters"); - if (widget) { - widget.onChangeTipStart(endType); - widget.onChangeTipEnd(endType); - widget.onChangeJoin(endType); - } - Action.perform("deselect()", "cameraView"); -} - - -/** -* Converts the Drawing object to a string of the drawing name. -* @return: { string } The name of the drawing. -*/ -$.oDrawing.prototype.toString = function () { - return this.name; -} - - - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oArtLayer class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * The constructor for the $.oArtLayer class. - * @constructor - * @classdesc $.oArtLayer represents art layers, as described by the artlayer toolbar. Access the drawing contents of the layers through this class. - * @param {int} index The artLayerIndex (0: underlay, 1: line art, 2: color art, 3:overlay). - * @param {$.oDrawing} oDrawingObject The oDrawing this layer belongs to. - */ -$.oArtLayer = function (index, oDrawingObject) { - this._layerIndex = index; - this._drawing = oDrawingObject; - //log(this._drawing._key) - this._key = { "drawing": this._drawing._key, "art": index } -} - - -/** - * The name of the artLayer (lineArt, colorArt, etc) - * @name $.oArtLayer#name - * @type {string} - */ -Object.defineProperty($.oArtLayer.prototype, 'name', { - get: function(){ - var names = ["underlay", "colorArt", "lineArt", "overlay"]; - return names[this._layerIndex]; - } -}) - - -/** - * The shapes contained on the artLayer. - * @name $.oArtLayer#shapes - * @type {$.oShape[]} - */ -Object.defineProperty($.oArtLayer.prototype, 'shapes', { - get: function () { - if (!this.hasOwnProperty("_shapes")){ - var _shapesNum = Drawing.query.getNumberOfLayers(this._key); - var _shapes = []; - for (var i = 0; i < _shapesNum; i++) { - _shapes.push(this.getShapeByIndex(i)); - } - this._shapes = _shapes; - } - return this._shapes; - } -}) - - -/** - * The strokes contained amongst all the shapes of the artLayer. - * @name $.oArtLayer#strokes - * @type {$.oStroke[]} - */ -Object.defineProperty($.oArtLayer.prototype, 'strokes', { - get: function () { - var _strokes = []; - - var _shapes = this.shapes; - for (var i in _shapes) { - _strokes = _strokes.concat(_shapes[i].strokes); - } - - return _strokes; - } -}) - - -/** - * The contours contained amongst all the shapes of the artLayer. - * @name $.oArtLayer#contours - * @type {$.oContour[]} - */ -Object.defineProperty($.oArtLayer.prototype, 'contours', { - get: function () { - var _contours = []; - - var _shapes = this.shapes; - for (var i in _shapes) { - _contours = _contours.concat(_shapes[i].contours); - } - - return _contours; - } -}) - - -/** - * The bounds of the layer, in drawing space coordinates. (null if the drawing is empty.) - * @name $.oArtLayer#boundingBox - * @type {$.oBox} - */ -Object.defineProperty($.oArtLayer.prototype, 'boundingBox', { - get: function () { - var _box = Drawing.query.getBox(this._key); - if (_box.empty) return null; - - var _boundingBox = new $.oBox(_box.x0, _box.y0, _box.x1, _box.y1); - return _boundingBox; - } -}) - - -/** - * the currently selected shapes on the ArtLayer. - * @name $.oArtLayer#selectedShapes - * @type {$.oShape[]} - */ -Object.defineProperty($.oArtLayer.prototype, 'selectedShapes', { - get: function () { - var _shapes = Drawing.selection.get(this._key).selectedLayers; - var _artLayer = this; - return _shapes.map(function (x) { return _artLayer.getShapeByIndex(x) }); - } -}) - - - -/** - * the currently selected strokes on the ArtLayer. - * @name $.oArtLayer#selectedStrokes - * @type {$.oStroke[]} - */ -Object.defineProperty($.oArtLayer.prototype, 'selectedStrokes', { - get: function () { - var _shapes = this.selectedShapes; - var _strokes = []; - - for (var i in _shapes) { - _strokes = _strokes.concat(_shapes[i].strokes); - } - - return _strokes; - } -}) - - -/** - * the currently selected contours on the ArtLayer. - * @name $.oArtLayer#selectedContours - * @type {$.oContour[]} - */ -Object.defineProperty($.oArtLayer.prototype, 'selectedContours', { - get: function () { - var _shapes = this.selectedShapes; - var _contours = []; - - for (var i in _shapes) { - _contours = _contours.concat(_shapes[i].contours); - } - - return _contours; - } -}) - - - -/** - * all the data from this artLayer. For internal use. - * @name $.oArtLayer#drawingData - * @type {$.oStroke[]} - * @readonly - * @private - */ -Object.defineProperty($.oArtLayer.prototype, 'drawingData', { - get: function () { - var _data = this._drawing.drawingData - for (var i in _data.arts){ - if (_data.arts[i].art == this._layerIndex) { - return _data.arts[i]; - } - } - - // in case of empty layerArt, return a default object - return {art:this._layerIndex, artName:this.name, layers:[]}; - } -}) - - -/** - * Draws a circle on the artLayer. - * @param {$.oPoint} center The center of the circle - * @param {float} radius The radius of the circle - * @param {$.oLineStyle} [lineStyle] Provide a $.oLineStyle object to specify how the line will look - * @param {object} [fillStyle=null] The fill information to fill the circle with. - * @returns {$.oShape} the created shape containing the circle. -*/ -$.oArtLayer.prototype.drawCircle = function(center, radius, lineStyle, fillStyle){ - if (typeof fillStyle === 'undefined') var fillStyle = null; - - var arg = { - x: center.x, - y: center.y, - radius: radius - }; - var _path = Drawing.geometry.createCircle(arg); - - return this.drawShape(_path, lineStyle, fillStyle); -} - -/** - * Draws the given path on the artLayer. - * @param {$.oVertex[]} path an array of $.oVertex objects that describe a path. - * @param {$.oLineStyle} [lineStyle] the line style to draw with. (By default, will use the current stencil selection) - * @param {$.oFillStyle} [fillStyle] the fill information for the path. (By default, will use the current palette selection) - * @param {bool} [polygon] Whether bezier handles should be created for the points in the path (ignores "onCurve" properties of oVertex from path) - * @param {bool} [createUnderneath] Whether the new shape will appear on top or underneath the contents of the layer. (not working yet) - */ -$.oArtLayer.prototype.drawShape = function(path, lineStyle, fillStyle, polygon, createUnderneath){ - if (typeof fillStyle === 'undefined') var fillStyle = new this.$.oFillStyle(); - if (typeof lineStyle === 'undefined') var lineStyle = new this.$.oLineStyle(); - if (typeof polygon === 'undefined') var polygon = false; - if (typeof createUnderneath === 'undefined') var createUnderneath = false; - - var index = this.shapes.length; - - var _lineStyle = {}; - - if (lineStyle){ - _lineStyle.pencilColorId = lineStyle.colorId; - _lineStyle.thickness = { - "minThickness": lineStyle.minThickness, - "maxThickness": lineStyle.maxThickness, - "thicknessPath": 0 - }; - } - - if (fillStyle) _lineStyle.shaderLeft = 0; - if (polygon) _lineStyle.polygon = true; - _lineStyle.under = createUnderneath; - _lineStyle.stroke = !!lineStyle; - - var strokeDesciption = _lineStyle; - strokeDesciption.path = path; - strokeDesciption.closed = !!fillStyle; - - var shapeDescription = {} - if (fillStyle) shapeDescription.shaders = [{ colorId : fillStyle.colorId }] - shapeDescription.strokes = [strokeDesciption] - if (lineStyle) shapeDescription.thicknessPaths = [lineStyle.stencil.thicknessPath] - - var config = { - label: "draw shape", - drawing: this._key.drawing, - art: this._key.art, - layers: [shapeDescription] - }; - - - var layers = DrawingTools.createLayers(config); - - var newShape = this.getShapeByIndex(index); - this._shapes.push(newShape); - return newShape; -}; - - -/** - * Draws the given path on the artLayer. - * @param {$.oVertex[]} path an array of $.oVertex objects that describe a path. - * @param {$.oLineStyle} lineStyle the line style to draw with. - * @returns {$.oShape} the shape containing the added stroke. - */ -$.oArtLayer.prototype.drawStroke = function(path, lineStyle){ - return this.drawShape(path, lineStyle, null); -}; - - -/** - * Draws the given path on the artLayer as a contour. - * @param {$.oVertex[]} path an array of $.oVertex objects that describe a path. - * @param {$.oFillStyle} fillStyle the fill style to draw with. - * @returns {$.oShape} the shape newly created from the path. - */ -$.oArtLayer.prototype.drawContour = function(path, fillStyle){ - return this.drawShape(path, null, fillStyle); -}; - - -/** - * Draws a rectangle on the artLayer. - * @param {float} x the x coordinate of the top left corner. - * @param {float} y the y coordinate of the top left corner. - * @param {float} width the width of the rectangle. - * @param {float} height the height of the rectangle. - * @param {$.oLineStyle} lineStyle a line style to use for the rectangle stroke. - * @param {$.oFillStyle} fillStyle a fill style to use for the rectangle fill. - * @returns {$.oShape} the shape containing the added stroke. - */ -$.oArtLayer.prototype.drawRectangle = function(x, y, width, height, lineStyle, fillStyle){ - if (typeof fillStyle === 'undefined') var fillStyle = null; - - var path = [ - {x:x,y:y,onCurve:true}, - {x:x+width,y:y,onCurve:true}, - {x:x+width,y:y-height,onCurve:true}, - {x:x,y:y-height,onCurve:true}, - {x:x,y:y,onCurve:true} - ]; - - return this.drawShape(path, lineStyle, fillStyle); -} - - - -/** - * Draws a line on the artLayer - * @param {$.oPoint} startPoint - * @param {$.oPoint} endPoint - * @param {$.oLineStyle} lineStyle - * @returns {$.oShape} the shape containing the added line. - */ -$.oArtLayer.prototype.drawLine = function(startPoint, endPoint, lineStyle){ - var path = [{x:startPoint.x,y:startPoint.y,onCurve:true},{x:endPoint.x,y:endPoint.y,onCurve:true}]; - - return this.drawShape(path, lineStyle, null); -} - - -/** - * Removes the contents of the art layer. - */ -$.oArtLayer.prototype.clear = function(){ - var _shapes = this.shapes; - this.$.debug(_shapes, this.$.DEBUG_LEVEL.DEBUG); - for (var i=_shapes.length - 1; i>=0; i--){ - _shapes[i].remove(); - } -} - - -/** - * get a shape from the artLayer by its index - * @param {int} index - * - * @return {$.oShape} - */ -$.oArtLayer.prototype.getShapeByIndex = function (index) { - return new this.$.oShape(index, this); -} - - -/** - * @private - */ -$.oArtLayer.prototype.toString = function(){ - return "Object $.oArtLayer ["+this.name+"]"; -} - - - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oLineStyle class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * The constructor for the $.oLineStyle class. - * @constructor - * @classdesc - * The $.oLineStyle class describes a lineStyle used to describe the appearance of strokes and perform drawing operations.
- * Initializing a $.oLineStyle without any parameters attempts to get the current pencil thickness settings and color. - * @param {string} colorId the color Id to paint the line with. - * @param {$.oStencil} stencil the stencil object representing the thickness keys - */ -$.oLineStyle = function (colorId, stencil) { - if (typeof minThickness === 'undefined') var minThickness = PenstyleManager.getCurrentPenstyleMinimumSize(); - if (typeof maxThickness === 'undefined') { - var maxThickness = PenstyleManager.getCurrentPenstyleMaximumSize(); - if (!maxThickness && !minThickness) maxThickness = 1; - } - if (typeof stencil === 'undefined') { - var stencil = new $.oStencil("", "pencil", {maxThickness:maxThickness, minThickness:minThickness, keys:[]}); - } - - if (typeof colorId === 'undefined'){ - var _palette = this.$.scn.selectedPalette; - if (_palette) { - var _color = this.$.scn.selectedPalette.currentColor; - if (_color) { - var colorId = _color.id; - } else{ - var colorId = "0000000000000003"; - } - } - } - - this.colorId = colorId; - this.stencil = stencil; - - // this.$.debug(colorId+" "+minThickness+" "+maxThickness+" "+stencil, this.$.DEBUG_LEVEL.DEBUG) -} - - -/** - * The minimum thickness of the line using this lineStyle - * @name $.oLineStyle#minThickness - * @type {float} - */ -Object.defineProperty($.oLineStyle.prototype, "minThickness", { - get: function(){ - return this.stencil.minThickness; - }, - - set: function(newMinThickness){ - this.stencil.minThickness = newMinThickness; - } -}) - - -/** - * The minimum thickness of the line using this lineStyle - * @name $.oLineStyle#maxThickness - * @type {float} - */ -Object.defineProperty($.oLineStyle.prototype, "maxThickness", { - get: function(){ - return this.stencil.maxThickness; - }, - - set: function(newMaxThickness){ - this.stencil.maxThickness = newMaxThickness; - } -}) - - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oShape class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * The constructor for the $.oShape class. These types of objects are not supported for harmony versions < 16 - * @constructor - * @classdesc $.oShape represents shapes drawn on the art layer. Strokes, colors, line styles, can be accessed through this class.
Warning, Toonboom stores strokes by index, so stroke objects may become obsolete when modifying the contents of the drawing. - * @param {int} index The index of the shape on the artLayer - * @param {$.oArtLayer} oArtLayerObject The oArtLayer this layer belongs to. - * - * @property {int} index the index of the shape in the parent artLayer - * @property {$.oArtLayer} artLayer the art layer that contains this shape - */ -$.oShape = function (index, oArtLayerObject) { - this.index = index; - this.artLayer = oArtLayerObject; -} - - -/** - * the toonboom key object identifying this shape. - * @name $.oShape#_key - * @type {object} - * @private - * @readonly - */ -Object.defineProperty($.oShape.prototype, '_key', { - get: function () { - var _key = this.artLayer._key; - return { drawing: _key.drawing, art: _key.art, layers: [this.index] }; - } -}) - - -/** - * The underlying data describing the shape. - * @name $.oShape#_data - * @type {$.oShape[]} - * @readonly - * @private - */ -Object.defineProperty($.oShape.prototype, '_data', { - get: function () { - return this.artLayer.drawingData.layers[this.index]; - } -}) - - -/** - * The strokes making up the shape. - * @name $.oShape#strokes - * @type {$.oShape[]} - * @readonly - */ -Object.defineProperty($.oShape.prototype, 'strokes', { - get: function () { - if (!this.hasOwnProperty("_strokes")) { - var _data = this._data; - - if (!_data.hasOwnProperty("strokes")) return []; - - var _shape = this; - var _strokes = _data.strokes.map(function (x, idx) { return new _shape.$.oStroke(idx, x, _shape) }) - this._strokes = _strokes; - } - return this._strokes; - } -}) - - -/** - * The contours (invisible strokes that can delimit colored areas) making up the shape. - * @name $.oShape#contours - * @type {$.oContour[]} - * @readonly - */ - Object.defineProperty($.oShape.prototype, 'contours', { - get: function () { - if (!this.hasOwnProperty("_contours")) { - var _data = this._data - - if (!_data.hasOwnProperty("contours")) return []; - - var _shape = this; - var _contours = _data.contours.map(function (x, idx) { return new this.$.oContour(idx, x, _shape) }) - this._contours = _contours; - } - return this._contours; - } -}) - - -/** - * The fills styles contained in the shape - * @name $.oShape#fills - * @type {$.oFillStyle[]} - * @readonly - */ -Object.defineProperty($.oShape.prototype, 'fills', { - get: function () { - if (!this.hasOwnProperty("_fills")) { - var _data = this._data - - if (!_data.hasOwnProperty("contours")) return []; - - var _fills = _data.contours.map(function (x) { return new this.$.oFillStyle(x.colorId, x.matrix) }) - this._fills = _fills; - } - return this._fills; - } -}) - -/** - * The stencils used by the shape. - * @name $.oShape#stencils - * @type {$.oStencil[]} - * @readonly - */ -Object.defineProperty($.oShape.prototype, 'stencils', { - get: function () { - if (!this.hasOwnProperty("_stencils")) { - var _data = this._data; - var _shape = this; - var _stencils = _data.thicknessPaths.map(function (x) { return new _shape.$.oStencil("", "pencil", x) }) - this._stencils = _stencils; - } - return this._stencils; - } -}) - - -/** - * The bounding box of the shape. - * @name $.oShape#bounds - * @type {$.oBox} - * @readonly - */ -Object.defineProperty($.oShape.prototype, 'bounds', { - get: function () { - var _bounds = new this.$.oBox(); - var _contours = this.contours; - var _strokes = this.strokes; - - for (var i in _contours){ - _bounds.include(_contours[i].bounds); - } - - for (var i in _strokes){ - _bounds.include(_strokes[i].bounds); - } - - return _bounds; - } -}) - -/** - * The x coordinate of the shape. - * @name $.oShape#x - * @type {float} - * @readonly - */ -Object.defineProperty($.oShape.prototype, 'x', { - get: function () { - return this.bounds.left; - } -}) - - -/** - * The x coordinate of the shape. - * @name $.oShape#x - * @type {float} - * @readonly - */ -Object.defineProperty($.oShape.prototype, 'y', { - get: function () { - return this.bounds.top; - } -}) - - -/** - * The width of the shape. - * @name $.oShape#width - * @type {float} - * @readonly - */ -Object.defineProperty($.oShape.prototype, 'width', { - get: function () { - return this.bounds.width; - } -}) - - -/** - * The height coordinate of the shape. - * @name $.oShape#height - * @type {float} - * @readonly - */ -Object.defineProperty($.oShape.prototype, 'height', { - get: function () { - return this.bounds.height; - } -}) - - -/** - * Retrieve and set the selected status of each shape. - * @name $.oShape#selected - * @type {bool} - */ -Object.defineProperty($.oShape.prototype, 'selected', { - get: function () { - var _selection = this.artLayer._selectedShapes; - var _indices = _selection.map(function (x) { return x.index }); - return (_indices.indexOf(this.index) != -1) - }, - set: function (newSelectedState) { - var _key = this.artLayer._key; - - var currentSelection = Drawing.selection.get(_key); - var config = {drawing:_key.drawing, art:_key.art}; - - if (newSelectedState){ - // adding elements to selection - config.selectedLayers = currentSelection.selectedLayers.concat([this.index]); - config.selectedStrokes = currentSelection.selectedStrokes; - }else{ - config.selectedLayers = currentSelection.selectedLayers; - config.selectedStrokes = currentSelection.selectedStrokes; - - // remove current element from selection before setting again - for (var i=config.selectedLayers.length-1; i>=0; i--){ - if (config.selectedLayers[i] == this.index) config.selectedLayers.splice(i, 1); - } - for (var i=config.selectedStrokes.length-1; i>=0; i--){ - if (config.selectedStrokes[i].layer == this.index) config.selectedStrokes.splice(i, 1); - } - } - - Drawing.selection.set(config); - } -}) - - -/** - * Deletes the shape from its artlayer. - * Updates the index of all other oShapes on the artLayer in order to - * keep tracking all of them without having to query the drawing again. - */ -$.oShape.prototype.remove = function(){ - DrawingTools.deleteLayers(this._key); - - // update shapes list for this artLayer - var shapes = this.artLayer.shapes - for (var i in shapes){ - if (i > this.index){ - shapes[i].index--; - } - } - shapes.splice(this.index, 1); -} - - -/** - * Deletes the shape from its artlayer. - * Warning : Because shapes are referenced by index, deleting a shape - * that isn't at the end of the list of shapes from this layer - * might render other shape objects from this layer obsolete. - * Get them again with artlayer.shapes. - * @deprecated use oShape.remove instead - */ -$.oShape.prototype.deleteShape = function(){ - this.remove(); -} - - -/** - * Gets a stroke from this shape by its index - * @param {int} index - * - * @returns {$.oStroke} - */ -$.oShape.prototype.getStrokeByIndex = function (index) { - return this.strokes[index]; -} - - -$.oShape.prototype.toString = function (){ - return "" -} - - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oFillStyle class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * The constructor for the $.oFillStyle class. - * @constructor - * @classdesc - * The $.oFillStyle class describes a fillStyle used to describe the appearance of filled in color areas and perform drawing operations.
- * Initializing a $.oFillStyle without any parameters attempts to get the current color id. - * @param {string} colorId the color Id to paint the line with. - * @param {object} fillMatrix - */ -$.oFillStyle = function (colorId, fillMatrix) { - if (typeof fillMatrix === 'undefined') var fillMatrix = { - "ox": 1, - "oy": 1, - "xx": 1, - "xy": 0, - "yx": 0, - "yy": 1 - } - - if (typeof colorId === 'undefined'){ - var _palette = this.$.scn.selectedPalette; - if (_palette) { - var _color = this.$.scn.selectedPalette.currentColor; - if (_color) { - var colorId = _color.id; - } else{ - var colorId = "0000000000000003"; - } - } - } - - this.colorId = colorId; - this.fillMatrix = fillMatrix; - - this.$.log("new fill created: " + colorId + " " + JSON.stringify(this.fillMatrix)) -} - - -$.oFillStyle.prototype.toString = function(){ - return ""; -} - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oStroke class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * The constructor for the $.oStroke class. These types of objects are not supported for harmony versions < 16 - * @constructor - * @classdesc The $.oStroke class models the strokes that make up the shapes visible on the Drawings. - * @param {int} index The index of the stroke in the shape. - * @param {object} strokeObject The stroke object descriptor that contains the info for the stroke - * @param {oShape} oShapeObject The parent oShape - * - * @property {int} index the index of the stroke in the parent shape - * @property {$.oShape} shape the shape that contains this stroke - * @property {$.oArtLayer} artLayer the art layer that contains this stroke - */ -$.oStroke = function (index, strokeObject, oShapeObject) { - this.index = index; - this.shape = oShapeObject; - this.artLayer = oShapeObject.artLayer; - this._data = strokeObject; -} - - -/** - * The $.oVertex (including bezier handles) making up the complete path of the stroke. - * @name $.oStroke#path - * @type {$.oVertex[]} - * @readonly - */ -Object.defineProperty($.oStroke.prototype, "path", { - get: function () { - // path vertices get cached - if (!this.hasOwnProperty("_path")){ - var _stroke = this; - var _path = this._data.path.map(function(point, index){ - return new _stroke.$.oVertex(_stroke, point.x, point.y, point.onCurve, index); - }) - - this._path = _path; - } - return this._path; - } -}) - - -/** - * The oVertex that are on the stroke (Bezier handles excluded.) - * The first is repeated at the last position when the stroke is closed. - * @name $.oStroke#points - * @type {$.oVertex[]} - * @readonly - */ -Object.defineProperty($.oStroke.prototype, "points", { - get: function () { - return this.path.filter(function(x){return x.onCurve}); - } -}) - - -/** - * The segments making up the stroke. Each segment is a slice of the path, starting and stopping with oVertex present on the curve, and includes the bezier handles oVertex. - * @name $.oStroke#segments - * @type {$.oVertex[][]} - * @readonly - */ -Object.defineProperty($.oStroke.prototype, "segments", { - get: function () { - var _points = this.points; - var _path = this.path; - var _segments = []; - - for (var i=0; i<_points.length-1; i++){ - var _indexStart = _points[i].index; - var _indexStop = _points[i+1].index; - var _segment = _path.slice(_indexStart, _indexStop+1); - _segments.push(_segment); - } - - return _segments; - } -}) - - -/** - * The index of the stroke in the shape - * @name $.oStroke#index - * @type {int} - */ -Object.defineProperty($.oStroke.prototype, "index", { - get: function () { - this.$.debug("stroke object : "+JSON.stringify(this._stroke, null, " "), this.$.DEBUG_LEVEL.DEBUG); - return this._data.strokeIndex; - } -}) - - -/** - * The style of the stroke. null if the stroke is invisible - * @name $.oStroke#style - * @type {$.oLineStyle} - */ -Object.defineProperty($.oStroke.prototype, "style", { - get: function () { - if (this._data.invisible){ - return null; - } - var _colorId = this._data.pencilColorId; - var _stencil = this.shape.stencils[this._data.thickness]; - - return new this.$.oLineStyle(_colorId, _stencil); - } -}) - - -/** - * whether the stroke is a closed shape. - * @name $.oStroke#closed - * @type {bool} - */ -Object.defineProperty($.oStroke.prototype, "closed", { - get: function () { - var _path = this.path; - $.log(_path) - $.log(_path[_path.length-1].strokePosition) - return _path[_path.length-1].strokePosition == 0; - } -}) - - -/** - * The bounding box of the stroke. - * @name $.oStroke#bounds - * @type {$.oBox} - * @readonly - */ - Object.defineProperty($.oStroke.prototype, 'bounds', { - get: function () { - var _bounds = new this.$.oBox(); - // since Harmony doesn't allow natively to calculate the bounding box of a string, - // we convert the bezier into a series of points and calculate the box from it - var points = Drawing.geometry.discretize({precision: 1, path : this.path}); - for (var j in points){ - var point = points [j] - var pointBox = new this.$.oBox(point.x, point.y, point.x, point.y); - _bounds.include(pointBox); - } - return _bounds; - } -}) - - -/** - * The intersections on this stroke. Each intersection is an object with stroke ($.oStroke), point($.oPoint), strokePoint(float) and ownPoint(float) - * One of these objects describes an intersection by giving the stroke it intersects with, the coordinates of the intersection and two values which represent the place on the stroke at which the point is placed, with a value between 0 (start) and 1(end) - * @param {$.oStroke} [stroke] Specify a stroke to find intersections specific to it. If no stroke is specified, - * @return {Object[]} - * @example -// get the selected strokes on the active drawing -var sel = $.scn.activeDrawing.selectedStrokes; - -for (var i in sel){ - // get intersections with all other elements of the drawing - var intersections = sel[i].getIntersections(); - - for (var j in intersections){ - log("intersection : " + j); - log("point : " + intersections[j].point); // the point coordinates - log("strokes index : " + intersections[j].stroke.index); // the index of the intersecting strokes in their own shape - log("own point : " + intersections[j].ownPoint); // how far the intersection is on the stroke itself - log("stroke point : " + intersections[j].strokePoint); // how far the intersection is on the intersecting stroke - } -} - */ -$.oStroke.prototype.getIntersections = function (stroke){ - if (typeof stroke !== 'undefined'){ - // get intersection with provided stroke only - var _key = { "path0": [{ path: this.path }], "path0": [{ path: stroke.path }] }; - var intersections = Drawing.query.getIntersections(_key)[0]; - }else{ - // get all intersections on the stroke - var _drawingKey = this.artLayer._key; - var _key = { "drawing": _drawingKey.drawing, "art": _drawingKey.art, "paths": [{ path: this.path }] }; - var intersections = Drawing.query.getIntersections(_key)[0]; - } - - var result = []; - for (var i in intersections) { - var _shape = this.artLayer.getShapeByIndex(intersections[i].layer); - var _stroke = _shape.getStrokeByIndex(intersections[i].strokeIndex); - - for (var j in intersections[i].intersections){ - var points = intersections[i].intersections[j]; - - var point = new this.$.oVertex(this, points.x0, points.y0, true); - var intersection = { stroke: _stroke, point: point, ownPoint: points.t0, strokePoint: points.t1 }; - - result.push(intersection); - } - } - - return result; -} - - - -/** - * Adds points on the stroke without moving them, at the distance specified (0=start vertice, 1=end vertice) - * @param {float[]} pointsToAdd an array of float value between 0 and the number of current points on the curve - * @returns {$.oVertex[]} the points that were created (if points already existed, they will be returned) - * @example -// get the selected stroke and create points where it intersects with the other two strokes -var sel = $.scn.activeDrawing.selectedStrokes[0]; - -var intersections = sel.getIntersections(); - -// get the two intersections -var intersection1 = intersections[0]; -var intersection2 = intersections[1]; - -// add the points at the intersections on the intersecting strokes -intersection1.stroke.addPoints([intersection1.strokePoint]); -intersection2.stroke.addPoints([intersection2.strokePoint]); - -// add the points on the stroke -sel.addPoints([intersection1.ownPoint, intersection2.ownPoint]); -*/ -$.oStroke.prototype.addPoints = function (pointsToAdd) { - // calculate the points that will be created - var points = Drawing.geometry.insertPoints({path:this._data.path, params : pointsToAdd}); - - // find the newly added points amongst the returned values - for (var i in this.path){ - var pathPoint = this.path[i]; - - // if point is found in path, it's not newly created - for (var j = points.length-1; j >=0; j--){ - var point = points[j]; - if (point.x == pathPoint.x && point.y == pathPoint.y) { - points.splice(j, 1); - break - } - } - } - - // actually add the points - var config = this.artLayer._key; - config.label = "addPoint"; - config.strokes = [{layer:this.shape.index, strokeIndex:this.index, insertPoints: pointsToAdd }]; - - DrawingTools.modifyStrokes(config); - this.updateDefinition(); - - var newPoints = []; - // find the points for the coordinates from the new path - for (var i in points){ - var point = points[i]; - - for (var j in this.path){ - var pathPoint = this.path[j]; - if (point.x == pathPoint.x && point.y == pathPoint.y) newPoints.push(pathPoint); - } - } - - if (newPoints.length != pointsToAdd.length) throw new Error ("some points in " + pointsToAdd + " were not created."); - return newPoints; -} - - -/** - * fetch the stroke information again to update it after modifications. - * @returns {object} the data definition of the stroke, for internal use. - */ -$.oStroke.prototype.updateDefinition = function(){ - var _key = this.artLayer._key; - var strokes = Drawing.query.getStrokes(_key); - this._data = strokes.layers[this.shape.index].strokes[this.index]; - - // remove cache for path - delete this._path; - - return this._data; -} - - -/** - * Gets the closest position of the point on the stroke (float value) from a point with x and y coordinates. - * @param {oPoint} point - * @return {float} the strokePosition of the point on the stroke (@see $.oVertex#strokePosition) - */ -$.oStroke.prototype.getPointPosition = function(point){ - var arg = { - path : this.path, - points: [{x:point.x, y:point.y}] - } - var strokePoint = Drawing.geometry.getClosestPoint(arg)[0].closestPoint; - if (!strokePoint) return 0; // the only time this fails is when the point is the origin of the stroke - - return strokePoint.t; -} - - -/** - * Get the coordinates of the point on the stroke from its strokePosition (@see $.oVertex#strokePosition). - * Only works until a distance of 600 drawing vector units. - * @param {float} position - * @return {$.oPoint} an oPoint object containing the coordinates. - */ -$.oStroke.prototype.getPointCoordinates = function(position){ - var arg = { - path : this.path, - params : [ position ] - }; - var point = Drawing.geometry.evaluate(arg)[0]; - - return new $.oPoint(point.x, point.y); -} - - -/** - * projects a point onto a stroke and returns the closest point belonging to the stroke. - * Only works until a distance of 600 drawing vector units. - * @param {$.oPoint} point - * @returns {$.oPoint} - */ -$.oStroke.prototype.getClosestPoint = function (point){ - var arg = { - path : this.path, - points: [{x:point.x, y:point.y}] - }; - - // returns an array of length 1 with an object containing - // the original query and a "closestPoint" key that contains the information. - var _result = Drawing.geometry.getClosestPoint(arg)[0]; - - return new $.oPoint(_result.closestPoint.x, _result.closestPoint.y); -} - - -/** - * projects a point onto a stroke and returns the distance between the point and the stroke. - * Only works until a distance of 600 drawing vector units. - * @param {$.oPoint} point - * @returns {float} - */ -$.oStroke.prototype.getPointDistance = function (point){ - var arg = { - path : this.path, - points: [{x:point.x, y:point.y}] - }; - - // returns an array of length 1 with an object containing - // the original query and a "closestPoint" key that contains the information. - var _result = Drawing.geometry.getClosestPoint(arg)[0].closestPoint; - - return _result.distance; -} - - -/** - * @private - */ -$.oStroke.prototype.toString = function(){ - return "" -} - - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oContour class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * The constructor for the $.oContour class. These types of objects are not supported for harmony versions < 16 - * @constructor - * @classdesc The $.oContour class models the strokes that make up the shapes visible on the Drawings.
- * $.oContour is a subclass of $.oSroke and shares its properties, but represents a stroke with a fill. - * @extends $.oStroke - * @param {int} index The index of the contour in the shape. - * @param {object} contourObject The stroke object descriptor that contains the info for the stroke - * @param {oShape} oShapeObject The parent oShape - * - * @property {int} index the index of the stroke in the parent shape - * @property {$.oShape} shape the shape that contains this stroke - * @property {$.oArtLayer} artLayer the art layer that contains this stroke - */ -$.oContour = function (index, contourObject, oShapeObject) { - this.$.oStroke.call(this, index, contourObject, oShapeObject) -} -$.oContour.prototype = Object.create($.oStroke.prototype) - - -/** - * The information about the fill of this contour - * @name $.oContour#fill - * @type {$.oFillStyle} - */ -Object.defineProperty($.oContour.prototype, "fill", { - get: function () { - var _data = this._data; - return new this.$.oFillStyle(_data.colorId, _data.matrix); - } -}) - - -/** - * The bounding box of the contour. - * @name $.oContour#bounds - * @type {$.oBox} - * @readonly - */ - Object.defineProperty($.oContour.prototype, 'bounds', { - get: function () { - var _data = this._data; - var _box = _data.box; - var _bounds = new this.$.oBox(_box.x0,_box.y0, _box.x1, _box.y1); - return _bounds; - } -}) - -/** - * @private - */ -$.oContour.prototype.toString = function(){ - return "" -} - - - - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oVertex class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * The constructor for the $.oVertex class - * @constructor - * @classdesc - * The $.oVertex class represents a single control point on a stroke. This class is used to get the index of the point in the stroke path sequence, as well as its position as a float along the stroke's length. - * The onCurve property describes whether this control point is a bezier handle or a point on the curve. - * - * @param {$.oStroke} stroke the stroke that this vertex belongs to - * @param {float} x the x coordinate of the vertex, in drawing space - * @param {float} y the y coordinate of the vertex, in drawing space - * @param {bool} onCurve whether the point is a bezier handle or situated on the curve - * @param {int} index the index of the point on the stroke - * - * @property {$.oStroke} stroke the stroke that this vertex belongs to - * @property {float} x the x coordinate of the vertex, in drawing space - * @property {float} y the y coordinate of the vertex, in drawing space - * @property {bool} onCurve whether the point is a bezier handle or situated on the curve - * @property {int} index the index of the point on the stroke - */ -$.oVertex = function(stroke, x, y, onCurve, index){ - if (typeof onCurve === 'undefined') var onCurve = false; - if (typeof index === 'undefined') var index = stroke.getPointPosition({x:x, y:y}); - - this.x = x; - this.y = y; - this.onCurve = onCurve; - this.stroke = stroke; - this.index = index -} - - -/** - * The position of the point on the curve, from 0 to the maximum number of points - * @name $.oVertex#strokePosition - * @type {float} - * @readonly - */ -Object.defineProperty($.oVertex.prototype, 'strokePosition', { - get: function(){ - var _position = this.stroke.getPointPosition(this); - return _position; - } -}) - - -/** - * The position of the point on the drawing, as an oPoint - * @name $.oVertex#position - * @type {oPoint} - * @readonly - */ -Object.defineProperty($.oVertex.prototype, 'position', { - get: function(){ - var _position = new this.$.oPoint(this.x, this.y, 0); - return _position; - } -}) - - -/** - * The angle of the curve going through this vertex, compared to the x axis, counterclockwise. - * (In degrees, or null if the stroke is open ended on the right.) - * @name $.oVertex#angleRight - * @type {float} - * @readonly - */ -Object.defineProperty($.oVertex.prototype, 'angleRight', { - get: function(){ - var _index = this.index+1; - var _path = this.stroke.path; - - // get the next point by looping around if the stroke is closed - if (_index >= _path.length){ - if (this.stroke.closed){ - var _nextPoint = _path[1]; - }else{ - return null; - } - }else{ - var _nextPoint = _path[_index]; - } - - var vector = this.$.oVector.fromPoints(this, _nextPoint); - var angle = vector.degreesAngle; - // if (angle < 0) angle += 360 //ensuring only positive values - return angle - } -}) - - -/** - * The angle of the line or bezier handle on the left of this vertex, compared to the x axis, counterclockwise. - * (In degrees, or null if the stroke is open ended on the left.) - * @name $.oVertex#angleLeft - * @type {float} - * @readonly - */ -Object.defineProperty($.oVertex.prototype, 'angleLeft', { - get: function(){ - var _index = this.index-1; - var _path = this.stroke.path; - - // get the next point by looping around if the stroke is closed - if (_index < 0){ - if (this.stroke.closed){ - var _nextPoint = _path[_path.length-2]; //first and last points are the same when the stroke is closed - }else{ - return null; - } - }else{ - var _nextPoint = _path[_index]; - } - - var vector = this.$.oVector.fromPoints(_nextPoint, this); - var angle = vector.degreesAngle; - // if (angle < 0) angle += 360 //ensuring only positive values - return angle - } -}) - - -/** - * @private - */ -$.oVertex.prototype.toString = function(){ - return "oVertex : { index:"+this.index+", x: "+this.x+", y: "+this.y+", onCurve: "+this.onCurve+", strokePosition: "+this.strokePosition+" }" -} - - - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oStencil class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * The constructor for the $.oStencil class. - * @constructor - * @classdesc The $.oStencil class allows access to some of the settings, name and type of the stencils available in the Harmony UI.
- * Harmony stencils can have the following types: "pencil", "penciltemplate", "brush", "texture", "bitmapbrush" and "bitmaperaser". Each type is only available to specific tools.
- * Access the main size information of the brush with the mainBrushShape property. - * @param {string} xmlDescription the part of the penstyles.xml file between tags that describe a stencils. - * @property {string} name the display name of the stencil - * @property {string} type the type of stencil - * @property {Object} thicknessPathObject the description of the shape of the stencil - */ -$.oStencil = function (name, type, thicknessPathObject) { - this.name = name; - this.type = type; - this.thicknessPathObject = thicknessPathObject; - // log("thicknessPath: " + JSON.stringify(this.thicknessPathObject)) -} - - -/** - * The minimum thickness of the line using this stencil - * @name $.oStencil#minThickness - * @type {float} - */ -Object.defineProperty($.oStencil.prototype, "minThickness", { - get: function(){ - return this.thicknessPathObject.minThickness; - }, - set: function(newMinThickness){ - this.thicknessPathObject.minThickness = newMinThickness; - // TODO: also change in thicknessPath.keys - } -}) - - -/** - * The maximum thickness of the line using this stencil - * @name $.oStencil#maxThickness - * @type {float} - */ -Object.defineProperty($.oStencil.prototype, "maxThickness", { - get: function(){ - return this.thicknessPathObject.maxThickness; - }, - set: function(newMaxThickness){ - this.thicknessPathObject.maxThickness = newMaxThickness; - // TODO: also change in thicknessPath.keys - } -}) - - -/** - * Parses the xml string of the stencil xml description to create an object with all the information from it. - * @private - */ -$.oStencil.getFromXml = function (xmlString) { - var object = this.prototype.$.oStencil.getSettingsFromXml(xmlString) - - var maxThickness = object.mainBrushShape.sizeRange.maxValue - var minThickness = object.mainBrushShape.sizeRange.minPercentage * maxThickness - - var thicknessPathObject = { - maxThickness:maxThickness, - minThickness:minThickness, - keys: [ - {t:0}, - {t:1} - ] - } - - var _stencil = new this.$.oStencil(object.name, object.style, thicknessPathObject) - for (var i in object) { - try{ - // attempt to set values from the object - _stencil[i] = _settings[i]; - }catch(err){ - this.$.log(err) - } - } - return _stencil; -} - - -/** - * Parses the xml string of the stencil xml description to create an object with all the information from it. - * @private - */ -$.oStencil.getSettingsFromXml = function (xmlString) { - var object = {}; - var objectRE = /<(\w+)>([\S\s]*?)<\/\1>/igm - var match; - var string = xmlString + ""; - while (match = objectRE.exec(xmlString)) { - object[match[1]] = this.prototype.$.oStencil.getSettingsFromXml(match[2]); - // remove the match from the string to parse the rest as properties - string = string.replace(match[0], ""); - } - - var propsRE = /<(\w+) value="([\S\s]*?)"\/>/igm - var match; - while (match = propsRE.exec(string)) { - // try to convert the value to int, float or bool - var value = match[2]; - var intValue = parseInt(value, 10); - var floatValue = parseFloat(value); - if (value == "true" || value == "false") { - value = !!value; - } else if (!isNaN(floatValue)) { - if (intValue == floatValue) { - value = intValue; - } else { - value = floatValue; - } - } - - object[match[1]] = match[2]; - } - - return object; -} - -$.oStencil.prototype.toString = function (){ - return "$.oStencil: '" + this.name + "'" -} \ No newline at end of file diff --git a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_element.js b/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_element.js deleted file mode 100644 index b64c8169ec..0000000000 --- a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_element.js +++ /dev/null @@ -1,285 +0,0 @@ -////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// -// -// openHarmony Library v0.01 -// -// -// Developed by Mathieu Chaptel, Chris Fourney... -// -// -// This library is an open source implementation of a Document Object Model -// for Toonboom Harmony. It also implements patterns similar to JQuery -// for traversing this DOM. -// -// Its intended purpose is to simplify and streamline toonboom scripting to -// empower users and be easy on newcomers, with default parameters values, -// and by hiding the heavy lifting required by the official API. -// -// This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is guaranteed to work. Feel free to contribute -// improvements to its official github. If you do make sure you follow the provided -// template and naming conventions and document your new methods properly. -// -// This library doesn't overwrite any of the objects and classes of the official -// Toonboom API which must remains available. -// -// This library is made available under the MIT license. -// https://opensource.org/licenses/mit -// -// The repository for this library is available at the address: -// https://github.com/cfourney/OpenHarmony/ -// -// -// For any requests feel free to contact m.chaptel@gmail.com -// -// -// -// -////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oElement class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * The base class for the $.oElement.
Elements hold the drawings displayed by a "READ" Node or Drawing Node. They can be used to create new drawings, rename them, etc. - * @constructor - * @classdesc $.oElement Class - * @param {int} id The element ID. - * @param {$.oColumn} oColumnObject The column object associated to the element. - * - * @property {int} id The element ID. - * @property {$.oColumn} oColumnObject The column object associated to the element. - */ -$.oElement = function( id, oColumnObject){ - this._type = "element"; - - this.id = id; - this.column = oColumnObject; -} - -// $.oElement Object Properties - -/** - * The name of the element. - * @name $.oElement#name - * @type {string} - */ -Object.defineProperty($.oElement.prototype, 'name', { - get : function(){ - return element.getNameById(this.id) - }, - - set : function(newName){ - element.renameById(this.id, newName); - } -}) - - -/** - * The folder path of the element on the filesystem. - * @name $.oElement#path - * @type {string} - */ -Object.defineProperty($.oElement.prototype, 'path', { - get : function(){ - return fileMapper.toNativePath(element.completeFolder(this.id)) - } -}) - - -/** - * The drawings available in the element. - * @name $.oElement#drawings - * @type {$.oDrawing[]} - */ -Object.defineProperty($.oElement.prototype, 'drawings', { - get : function(){ - var _drawingsNumber = Drawing.numberOf(this.id); - var _drawings = []; - for (var i=0; i<_drawingsNumber; i++){ - _drawings.push( new this.$.oDrawing(Drawing.name(this.id, i), this) ); - } - return _drawings; - } -}) - - -/** - * The file format of the element. - * @name $.oElement#format - * @type {string} - */ -Object.defineProperty($.oElement.prototype, 'format', { - get : function(){ - var _type = element.pixmapFormat(this.id); - if (element.vectorType(this.id)) _type = "TVG"; - return _type; - } -}) - - -/** - * The palettes linked to this element. - * @name $.oElement#palettes - * @type {$.oPalette[]} - */ -Object.defineProperty($.oElement.prototype, 'palettes', { - get: function(){ - var _paletteList = PaletteObjectManager.getPaletteListByElementId(this.id); - var _palettes = []; - for (var i=0; i<_paletteList.numPalettes; i++){ - _palettes.push( new this.$.oPalette( _paletteList.getPaletteByIndex(i), _paletteList ) ); - } - - return _palettes; - } -}) - - -// $.oElement Class methods - -/** - * Adds a drawing to the element. Provide a filename to import an external file as a drawing. - * @param {int} [atFrame=1] The frame at which to add the drawing on the $.oDrawingColumn. Values < 1 create no exposure. - * @param {name} [name] The name of the drawing to add. - * @param {string} [filename] Optionally, a path for a drawing file to use for this drawing. Can pass an oFile object as well. - * @param {bool} [convertToTvg=false] If the filename isn't a tvg file, specify if you want it converted (this doesn't vectorize the drawing). - * - * @return {$.oDrawing} The added drawing - */ -$.oElement.prototype.addDrawing = function( atFrame, name, filename, convertToTvg ){ - if (typeof atFrame === 'undefined') var atFrame = 1; - if (typeof filename === 'undefined') var filename = null; - var nameByFrame = this.$.app.preferences.XSHEET_NAME_BY_FRAME; - if (typeof name === 'undefined') var name = nameByFrame?atFrame:1; - var name = name +""; // convert name to string - - // ensure a new drawing is always created by incrementing depending on preference - var _drawingNames = this.drawings.map(function(x){return x.name}); // index of existing names - var _nameFormat = /(.*?)_(\d+)$/ - while (_drawingNames.indexOf(name) != -1){ - if (nameByFrame || isNaN(name)){ - var nameGroups = name.match(_nameFormat); - if (nameGroups){ - // increment the part after the underscore - name = nameGroups[1] + "_" + (parseInt(nameGroups[2])+1); - }else{ - name += "_1"; - } - }else{ - name = parseInt(name, 10); - if (isNaN(name)) name = 0; - name = name + 1 + ""; // increment and convert back to string - } - } - - if (!(filename instanceof this.$.oFile)) filename = new this.$.oFile(filename); - var _fileExists = filename.exists; - Drawing.create (this.id, name, _fileExists, true); - - var _drawing = new this.$.oDrawing( name, this ); - - if (_fileExists) _drawing.importBitmap(filename, convertToTvg); - - // place drawing on the column at the provided frame - if (this.column != null || this.column != undefined && atFrame >= 1){ - column.setEntry(this.column.uniqueName, 1, atFrame, name); - } - - return _drawing; -} - - -/** - * Gets a drawing object by the name. - * @param {string} name The name of the drawing to get. - * - * @return {$.oDrawing} The drawing found by the search - */ -$.oElement.prototype.getDrawingByName = function ( name ){ - var _drawings = this.drawings; - for (var i in _drawings){ - if (_drawings[i].name == name) return _drawings[i]; - } - return null; -} - - -/** - * Link a provided palette to an element as an Element palette. - * @param {$.oPalette} oPaletteObject The oPalette object to link - * @param {int} [listIndex] The index in the element palette list at which to add the newly linked palette - * @return {$.oPalette} The linked element palette. - */ -$.oElement.prototype.linkPalette = function ( oPaletteObject , listIndex){ - var _paletteList = PaletteObjectManager.getPaletteListByElementId(this.id); - if (typeof listIndex === 'undefined') var listIndex = _paletteList.numPalettes; - - var _palettePath = oPaletteObject.path.path.replace(".plt", ""); - - var _palette = new this.$.oPalette(_paletteList.insertPalette (_palettePath, listIndex), _paletteList); - return _palette; -} - - -/** - * If the palette passed as a parameter is linked to this element, it will be unlinked, and moved to the scene palette list. - * @param {$.oPalette} oPaletteObject - * @return {bool} the success of the unlinking process. - */ -$.oElement.prototype.unlinkPalette = function (oPaletteObject) { - var _palettes = this.palettes; - var _ids = _palettes.map(function(x){return x.id}); - var _paletteId = oPaletteObject.id; - var _paletteIndex = _ids.indexOf(_paletteId); - - if (_paletteIndex == -1) return; // palette already isn't linked - - var _palette = _palettes[_paletteIndex]; - try{ - _palette.remove(false); - return true; - }catch(err){ - this.$.debug("Failed to unlink palette "+_palette.name+" from element "+this.name); - return false; - } -} - - - -/** - * Duplicate an element. - * @param {string} [name] The new name for the duplicated element. - * @return {$.oElement} The duplicate element - */ -$.oElement.prototype.duplicate = function(name){ - if (typeof name === 'undefined') var name = this.name; - - var _fieldGuide = element.fieldChart(this.id); - var _scanType = element.scanType(this.id); - - var _duplicateElement = this.$.scene.addElement(name, this.format, _fieldGuide, _scanType); - - var _drawings = this.drawings; - var _elementFolder = new this.$.oFolder(_duplicateElement.path); - - for (var i in _drawings){ - var _drawingFile = new this.$.oFile(_drawings[i].path); - try{ - var duplicateDrawing = _duplicateElement.addDrawing(0, _drawings[i].name, _drawingFile); - _drawingFile.copy(_elementFolder, duplicateDrawing.name, true); - }catch(err){ - this.debug("could not copy drawing file "+drawingFile.name+" into element "+_duplicateElement.name, this.DEBUG_LEVEL.ERROR); - } - } - return _duplicateElement; -} \ No newline at end of file diff --git a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_file.js b/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_file.js deleted file mode 100644 index 50e4b0d475..0000000000 --- a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_file.js +++ /dev/null @@ -1,855 +0,0 @@ -////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// -// -// openHarmony Library -// -// -// Developed by Mathieu Chaptel, Chris Fourney -// -// -// This library is an open source implementation of a Document Object Model -// for Toonboom Harmony. It also implements patterns similar to JQuery -// for traversing this DOM. -// -// Its intended purpose is to simplify and streamline toonboom scripting to -// empower users and be easy on newcomers, with default parameters values, -// and by hiding the heavy lifting required by the official API. -// -// This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is guaranteed to work. Feel free to contribute -// improvements to its official github. If you do make sure you follow the provided -// template and naming conventions and document your new methods properly. -// -// This library doesn't overwrite any of the objects and classes of the official -// Toonboom API which must remains available. -// -// This library is made available under the Mozilla Public license 2.0. -// https://www.mozilla.org/en-US/MPL/2.0/ -// -// The repository for this library is available at the address: -// https://github.com/cfourney/OpenHarmony/ -// -// -// For any requests feel free to contact m.chaptel@gmail.com -// -// -// -// -////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oFolder class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * The $.oFolder helper class -- providing utilities for folder manipulation and access. - * @constructor - * @classdesc $.oFolder Base Class - * @param {string} path The path to the folder. - * - * @property {string} path The path to the folder. - */ -$.oFolder = function(path){ - this._type = "folder"; - this._path = fileMapper.toNativePath(path).split("\\").join("/"); - - // fix lowercase drive letter - var path_components = this._path.split("/"); - if (path_components[0] && about.isWindowsArch()){ - // local path that starts with a drive letter - path_components[0] = path_components[0].toUpperCase() - this._path = path_components.join("/"); - } -} - - -/** - * The path of the folder. Setting a path doesn't move the file, only changes where the file object is pointing. - * @name $.oFolder#path - * @type {string} - */ -Object.defineProperty($.oFolder.prototype, 'path', { - get: function(){ - return this._path; - }, - set: function( newPath ){ - this._path = fileMapper.toNativePath( newPath ).split("\\").join("/"); - } -}); - - -/** - * The path of the file encoded as a toonboom relative path. - * @name $.oFile#toonboomPath - * @readonly - * @type {string} - */ -Object.defineProperty( $.oFolder.prototype, 'toonboomPath', { - get: function(){ - var _path = this._path; - if (!this.$.scene.online) return _path; - if (_path.slice(0,2) != ("//")) return _path; - - var _pathComponents = _path.replace("//", "").split("/"); - var _drive = (_pathComponents[1]=="usadata000")?_pathComponents[1]:_pathComponents[1].toUpperCase(); - var _path = _pathComponents.slice(2); - - return ["",_drive].concat(_path).join("/"); - } -}); - - -/** - * The name of the folder. - * @name $.oFolder#name - * @type {string} - */ -Object.defineProperty($.oFolder.prototype, 'name', { - get: function(){ - var _name = this.path.split("/"); - _name = _name.pop(); - return _name; - }, - set: function(newName){ - this.rename(newName) - } -}); - - -/** - * The parent folder. - * @name $.oFolder#folder - * @type {$.oFolder} - */ -Object.defineProperty($.oFolder.prototype, 'folder', { - get: function(){ - var _folder = this.path.slice(0,this.path.lastIndexOf("/", this.path.length-2)); - return new this.$.oFolder(_folder); - } -}); - - -/** - * The parent folder. - * @name $.oFolder#exists - * @type {string} - */ -Object.defineProperty($.oFolder.prototype, 'exists', { - get: function(){ - var dir = new QDir; - dir.setPath(this.path) - return dir.exists(); - } -}); - - -/** - * The files in the folder. - * @name $.oFolder#files - * @type {$.oFile[]} - * @deprecated use oFolder.getFiles() instead to specify filter - */ -Object.defineProperty($.oFolder.prototype, 'files', { - get: function(){ - var dir = new QDir; - dir.setPath(this.path); - dir.setFilter( QDir.Files ); - - if (!dir.exists) throw new Error("can't get files from folder "+this.path+" because it doesn't exist"); - - return dir.entryList().map(function(x){return new this.$.oFile(dir.path()+"/"+x)}); - } -}); - - -/** - * The folders within this folder. - * @name $.oFolder#folders - * @type {$.oFile[]} - * @deprecated oFolder.folder is the containing parent folder, it can't also mean the children folders - */ -Object.defineProperty($.oFolder.prototype, 'folders', { - get: function(){ - var _dir = new QDir; - _dir.setPath(this.path); - if (!_dir.exists) throw new Error("can't get files from folder "+this.path+" because it doesn't exist"); - _dir.setFilter(QDir.Dirs); - var _folders = _dir.entryList(); - - for (var i = _folders.length-1; i>=0; i--){ - if (_folders[i] == "." || _folders[i] == "..") _folders.splice(i,1); - } - - return _folders.map(function(x){return new this.$.oFolder( _dir.path() + "/" + x )}); - } -}); - - -/** - * The content within the folder -- both folders and files. - * @name $.oFolder#content - * @type {$.oFile/$.oFolder[] } - */ -Object.defineProperty($.oFolder.prototype, 'content', { - get: function(){ - var content = this.files; - content = content.concat( this.folders ); - return content; - } -}); - - -/** - * Lists the file names contained inside the folder. - * @param {string} [filter] Filter wildcards for the content of the folder. - * - * @returns {string[]} The names of the files contained in the folder that match the filter. - */ -$.oFolder.prototype.listFiles = function(filter){ - if (typeof filter === 'undefined') var filter = "*"; - - var _dir = new QDir; - _dir.setPath(this.path); - if (!_dir.exists) throw new Error("can't get files from folder "+this.path+" because it doesn't exist"); - _dir.setNameFilters([filter]); - _dir.setFilter( QDir.Files); - var _files = _dir.entryList(); - - return _files; -} - - -/** - * get the files from the folder - * @param {string} [filter] Filter wildcards for the content of the folder. - * - * @returns {$.oFile[]} A list of files contained in the folder as oFile objects. - */ -$.oFolder.prototype.getFiles = function( filter ){ - if (typeof filter === 'undefined') var filter = "*"; - // returns the list of $.oFile in a directory that match a filter - - var _path = this.path; - - var _files = []; - var _file_list = this.listFiles(filter); - for( var i in _file_list){ - _files.push( new this.$.oFile( _path+'/'+_file_list[i] ) ); - } - - return _files; -} - - -/** - * lists the folder names contained inside the folder. - * @param {string} [filter="*.*"] Filter wildcards for the content of the folder. - * - * @returns {string[]} The names of the files contained in the folder that match the filter. - */ -$.oFolder.prototype.listFolders = function(filter){ - - if (typeof filter === 'undefined') var filter = "*"; - - var _dir = new QDir; - _dir.setPath(this.path); - - if (!_dir.exists){ - this.$.debug("can't get files from folder "+this.path+" because it doesn't exist", this.$.DEBUG_LEVEL.ERROR); - return []; - } - - _dir.setNameFilters([filter]); - _dir.setFilter(QDir.Dirs); //QDir.NoDotAndDotDot not supported? - var _folders = _dir.entryList(); - - _folders = _folders.filter(function(x){return x!= "." && x!= ".."}) - - return _folders; -} - - -/** - * gets the folders inside the oFolder - * @param {string} [filter] Filter wildcards for the content of the folder. - * - * @returns {$.oFolder[]} A list of folders contained in the folder, as oFolder objects. - */ -$.oFolder.prototype.getFolders = function( filter ){ - if (typeof filter === 'undefined') var filter = "*"; - // returns the list of $.oFile in a directory that match a filter - - var _path = this.path; - - var _folders = []; - var _folders_list = this.listFolders(filter); - for( var i in _folders_list){ - _folders.push( new this.$.oFolder(_path+'/'+_folders_list[i])); - } - - return _folders; -} - - - /** - * Creates the folder, if it doesn't already exist. - * @returns { bool } The existence of the newly created folder. - */ -$.oFolder.prototype.create = function(){ - if( this.exists ){ - this.$.debug("folder "+this.path+" already exists and will not be created", this.$.DEBUG_LEVEL.WARNING) - return true; - } - - var dir = new QDir(this.path); - - dir.mkpath(this.path); - if (!this.exists) throw new Error ("folder " + this.path + " could not be created.") -} - - -/** - * Copy the folder and its contents to another path. - * @param {string} folderPath The path to an existing folder in which to copy this folder. (Can provide an oFolder) - * @param {string} [copyName] Optionally, a name for the folder copy, if different from the original - * @param {bool} [overwrite=false] Whether to overwrite the files that are already present at the copy location. - * @returns {$.oFolder} the oFolder describing the newly created copy. - */ -$.oFolder.prototype.copy = function( folderPath, copyName, overwrite ){ - // TODO: it should propagate errors from the recursive copy and throw them before ending? - if (typeof overwrite === 'undefined') var overwrite = false; - if (typeof copyName === 'undefined' || !copyName) var copyName = this.name; - if (!(folderPath instanceof this.$.oFolder)) folderPath = new $.oFolder(folderPath); - if (this.name == copyName && folderPath == this.folder.path) copyName += "_copy"; - - if (!folderPath.exists) throw new Error("Target folder " + folderPath +" doesn't exist. Can't copy folder "+this.path) - - var nextFolder = new $.oFolder(folderPath.path + "/" + copyName); - nextFolder.create(); - var files = this.getFiles(); - for (var i in files){ - var _file = files[i]; - var targetFile = new $.oFile(nextFolder.path + "/" + _file.fullName); - - // deal with overwriting - if (targetFile.exists && !overwrite){ - this.$.debug("File " + targetFile + " already exists, skipping copy of "+ _file, this.$.DEBUG_LEVEL.ERROR); - continue; - } - - _file.copy(nextFolder, undefined, overwrite); - } - var folders = this.getFolders(); - for (var i in folders){ - folders[i].copy(nextFolder, undefined, overwrite); - } - - return nextFolder; -} - - -/** - * Move this folder to the specified path. - * @param {string} destFolderPath The new complete path of the folder after the move - * @param {bool} [overwrite=false] Whether to overwrite the target. - * - * @return { bool } The result of the move. - * @todo implement with Robocopy - */ -$.oFolder.prototype.move = function( destFolderPath, overwrite ){ - if (typeof overwrite === 'undefined') var overwrite = false; - - if (destFolderPath instanceof this.$.oFolder) destFolderPath = destFolderPath.path; - - var dir = new Dir; - dir.path = destFolderPath; - - if (dir.exists && !overwrite) - throw new Error("destination file "+dir.path+" exists and will not be overwritten. Can't move folder."); - - var path = fileMapper.toNativePath(this.path); - var destPath = fileMapper.toNativePath(dir.path+"/"); - - var destDir = new Dir; - try { - destDir.rename( path, destPath ); - this._path = destPath; - - return true; - }catch (err){ - throw new Error ("Couldn't move folder "+this.path+" to new address "+destPath + ": " + err); - } -} - - -/** - * Move this folder to a different parent folder, while retaining its content and base name. - * @param {string} destFolderPath The path of the destination to copy the folder into. - * @param {bool} [overwrite=false] Whether to overwrite the target. Default is false. - * - * @return: { bool } The result of the move. - */ -$.oFolder.prototype.moveToFolder = function( destFolderPath, overwrite ){ - destFolderPath = (destFolderPath instanceof this.$.oFolder)?destFolderPath:new this.$.oFolder(destFolderPath) - - var folder = destFolderPath.path; - var name = this.name; - - this.move(folder+"/"+name, overwrite); -} - - -/** - * Renames the folder - * @param {string} newName - */ -$.oFolder.prototype.rename = function(newName){ - var destFolderPath = this.folder.path+"/"+newName - if ((new this.$.oFolder(destFolderPath)).exists) throw new Error("Can't rename folder "+this.path + " to "+newName+", a folder already exists at this location") - - this.move(destFolderPath) -} - - -/** - * Deletes the folder. - * @param {bool} removeContents Whether to check if the folder contains files before deleting. - */ -$.oFolder.prototype.remove = function (removeContents){ - if (typeof removeContents === 'undefined') var removeContents = false; - - if (this.listFiles.length > 0 && this.listFolders.length > 0 && !removeContents) throw new Error("Can't remove folder "+this.path+", it is not empty.") - var _folder = new Dir(this.path); - _folder.rmdirs(); -} - - -/** - * Get the sub folder or file by name. - * @param {string} name The sub name of a folder or file within a directory. - * @return: {$.oFolder/$.oFile} The resulting oFile or oFolder. - */ -$.oFolder.prototype.get = function( destName ){ - var new_path = this.path + "/" + destName; - var new_folder = new $.oFolder( new_path ); - if( new_folder.exists ){ - return new_folder; - } - - var new_file = new $.oFile( new_path ); - if( new_file.exists ){ - return new_file; - } - - return false; -} - - - /** - * Used in converting the folder to a string value, provides the string-path. - * @return {string} The folder path's as a string. - */ -$.oFolder.prototype.toString = function(){ - return this.path; -} - - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oFile class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * The $.oFile helper class -- providing utilities for file manipulation and access. - * @constructor - * @classdesc $.oFile Base Class - * @param {string} path The path to the file. - * - * @property {string} path The path to the file. - */ -$.oFile = function(path){ - this._type = "file"; - this._path = fileMapper.toNativePath(path).split('\\').join('/'); - - // fix lowercase drive letter - var path_components = this._path.split("/"); - if (path_components[0] && about.isWindowsArch()){ - // local path that starts with a drive letter - path_components[0] = path_components[0].toUpperCase() - this._path = path_components.join("/"); - } -} - - -/** - * The name of the file with extension. - * @name $.oFile#fullName - * @type {string} - */ -Object.defineProperty($.oFile.prototype, 'fullName', { - get: function(){ - var _name = this.path.slice( this.path.lastIndexOf("/")+1 ); - return _name; - } -}); - - -/** - * The name of the file without extension. - * @name $.oFile#name - * @type {string} - */ -Object.defineProperty($.oFile.prototype, 'name', { - get: function(){ - var _fullName = this.fullName; - if (_fullName.indexOf(".") == -1) return _fullName; - - var _name = _fullName.slice(0, _fullName.lastIndexOf(".")); - return _name; - }, - set: function(newName){ - this.rename(newName) - } -}); - - -/** - * The extension of the file. - * @name $.oFile#extension - * @type {string} - */ -Object.defineProperty($.oFile.prototype, 'extension', { - get: function(){ - var _fullName = this.fullName; - if (_fullName.indexOf(".") == -1) return ""; - - var _extension = _fullName.slice(_fullName.lastIndexOf(".")+1); - return _extension; - } -}); - - -/** - * The folder containing the file. - * @name $.oFile#folder - * @type {$.oFolder} - */ -Object.defineProperty($.oFile.prototype, 'folder', { - get: function(){ - var _folder = this.path.slice(0,this.path.lastIndexOf("/")); - return new this.$.oFolder(_folder); - } -}); - - -/** - * Whether the file exists already. - * @name $.oFile#exists - * @type {bool} - */ -Object.defineProperty($.oFile.prototype, 'exists', { - get: function(){ - var _file = new File( this.path ); - return _file.exists; - } -}) - - -/** - * The path of the file. Setting a path doesn't move the file, only changes where the file object is pointing. - * @name $.oFile#path - * @type {string} - */ -Object.defineProperty( $.oFile.prototype, 'path', { - get: function(){ - return this._path; - }, - - set: function( newPath ){ - this._path = fileMapper.toNativePath( newPath ).split("\\").join("/"); - } -}); - - -/** - * The path of the file encoded as a toonboom relative path. - * @name $.oFile#toonboomPath - * @readonly - * @type {string} - */ -Object.defineProperty( $.oFile.prototype, 'toonboomPath', { - get: function(){ - var _path = this._path; - if (!this.$.scene.online) return _path; - if (_path.slice(0,2) != ("//")) return _path; - - var _pathComponents = _path.replace("//", "").split("/"); - var _drive = (_pathComponents[1]=="usadata000")?_pathComponents[1]:_pathComponents[1].toUpperCase(); - var _path = _pathComponents.slice(2); - - return ["",_drive].concat(_path).join("/"); - } -}); - - -//Todo, Size, Date Created, Date Modified - - -/** - * Reads the content of the file. - * - * @return: { string } The contents of the file. - */ -$.oFile.prototype.read = function() { - var file = new File(this.path); - - try { - if (file.exists) { - file.open(FileAccess.ReadOnly); - var string = file.read(); - file.close(); - return string; - } - } catch (err) { - this.$.debug(err, this.DEBUG_LEVEL.ERROR) - return null - } -} - - -/** - * Writes to the file. - * @param {string} content Content to write to the file. - * @param {bool} [append=false] Whether to append to the file. - */ -$.oFile.prototype.write = function(content, append){ - if (typeof append === 'undefined') var append = false - - var file = new File(this.path); - try { - if (append){ - file.open(FileAccess.Append); - }else{ - file.open(FileAccess.WriteOnly); - } - file.write(content); - file.close(); - return true - } catch (err) {return false;} -} - - -/** - * Moves the file to the specified path. - * @param {string} folder destination folder for the file. - * @param {bool} [overwrite=false] Whether to overwrite the file. - * - * @return: { bool } The result of the move. - */ -$.oFile.prototype.move = function( newPath, overwrite ){ - if (typeof overwrite === 'undefined') var overwrite = false; - - if(newPath instanceof this.$.oFile) newPath = newPath.path; - - var _file = new PermanentFile(this.path); - var _dest = new PermanentFile(newPath); - // this.$.alert("moving "+_file.path()+" to "+_dest.path()+" exists?"+_dest.exists()) - - if (_dest.exists()){ - if (!overwrite){ - this.$.debug("destination file "+newPath+" exists and will not be overwritten. Can't move file.", this.$.DEBUG_LEVEL.ERROR); - return false; - }else{ - _dest.remove() - } - } - - var success = _file.move(_dest); - // this.$.alert(success) - if (success) { - this.path = _dest.path() - return this; - } - return false; -} - - - /** - * Moves the file to the folder. - * @param {string} folder destination folder for the file. - * @param {bool} [overwrite=false] Whether to overwrite the file. - * - * @return: { bool } The result of the move. - */ -$.oFile.prototype.moveToFolder = function( folder, overwrite ){ - if (folder instanceof this.$.oFolder) folder = folder.path; - var _fileName = this.fullName; - - return this.move(folder+"/"+_fileName, overwrite) -} - - - /** - * Renames the file. - * @param {string} newName the new name for the file, without the extension. - * @param {bool} [overwrite=false] Whether to replace a file of the same name if it exists in the folder. - * - * @return: { bool } The result of the renaming. - */ -$.oFile.prototype.rename = function( newName, overwrite){ - if (newName == this.name) return true; - if (this.extension != "") newName += "."+this.extension; - return this.move(this.folder.path+"/"+newName, overwrite); -} - - - -/** - * Copies the file to the folder. - * @param {string} [folder] Content to write to the file. - * @param {string} [copyName] Name of the copied file without the extension. If not specified, the copy will keep its name unless another file is present in which case it will be called "_copy" - * @param {bool} [overwrite=false] Whether to overwrite the file. - * - * @return: { bool } The result of the copy. - */ -$.oFile.prototype.copy = function( destfolder, copyName, overwrite){ - if (typeof overwrite === 'undefined') var overwrite = false; - if (typeof copyName === 'undefined') var copyName = this.name; - if (typeof destfolder === 'undefined') var destfolder = this.folder.path; - - var _fileName = this.fullName; - if(destfolder instanceof this.$.oFolder) destfolder = destfolder.path; - - // remove extension from name in case user added it to the param - copyName.replace ("."+this.extension, ""); - if (this.name == copyName && destfolder == this.folder.path) copyName += "_copy"; - - var _fileName = copyName+((this.extension.length>0)?"."+this.extension:""); - - var _file = new PermanentFile(this.path); - var _dest = new PermanentFile(destfolder+"/"+_fileName); - - if (_dest.exists() && !overwrite){ - throw new Error("Destination file "+destfolder+"/"+_fileName+" exists and will not be overwritten. Can't copy file.", this.DEBUG_LEVEL.ERROR); - } - - this.$.debug("copying "+_file.path()+" to "+_dest.path(), this.$.DEBUG_LEVEL.LOG) - - var success = _file.copy(_dest); - if (!success) throw new Error ("Copy of file "+_file.path()+" to location "+_dest.path()+" has failed.", this.$.DEBUG_LEVEL.ERROR) - - return new this.$.oFile(_dest.path()); -} - - -/** - * Removes the file. - * @return: { bool } The result of the removal. - */ -$.oFile.prototype.remove = function(){ - var _file = new PermanentFile(this.path) - if (_file.exists()) return _file.remove() -} - - - -/** - * Parses the file as a XML and returns an object containing the values. - * @example - * // parses the xml file as an object with imbricated hierarchy. - * // each xml node is represented by a simple object with a "children" property containing the children nodes, - * // and a objectName property representing the name of the node. - * // If the node has attributes, those are set as properties on the object. All values are set as strings. - * - * // example: parsing the shortcuts file - * - * var shortcutsFile = (new $.oFile(specialFolders.userConfig+"/shortcuts.xml")).parseAsXml(); - * - * // The returned object will always be a simple document object with a single "children" property containing the document nodes. - * - * var shortcuts = shortcuts.children[0].children // children[0] is the "shortcuts" parent node, we want the nodes contained within - * - * for (var i in shortcuts){ - * log (shortcuts[i].id) - * } - */ -$.oFile.prototype.parseAsXml = function(){ - if (this.extension.toLowerCase() != "xml") return - - // build an object model representation of the contents of the XML by parsing it character by character - var xml = this.read(); - var xmlDocument = new this.$.oXml(xml); - return xmlDocument; -} - - - /** - * Used in converting the file to a string value, provides the string-path. - * @return {string} The file path's as a string. - */ -$.oFile.prototype.toString = function(){ - return this.path; -} - - - - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oXml class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * The constructor for the $.oXml class. - * @classdesc - * The $.oXml class can be used to create an object from a xml string. It will contain a "children" property which is an array that holds all the children node from the main document. - * @constructor - * @param {string} xmlString the string to parse for xml content - * @param {string} objectName "xmlDocument" for the top node, otherwise, the string description of the xml node (ex: ) - * @property {string} objectName - * @property {$.oXml[]} children - */ -$.oXml = function (xmlString, objectName){ - if (typeof objectName === 'undefined') var objectName = "xmlDocument"; - this.objectName = objectName; - this.children = []; - - var string = xmlString+""; - - // matches children xml nodes, multiline or single line, and provides one group for the objectName and one for the insides to parse again. - var objectRE = /<(\w+)[ >?]([\S\s]+?\/\1|[^<]+?\/)>/igm - var match; - while (match = objectRE.exec(xmlString)){ - this.children.push(new this.$.oXml(match[2], match[1])); - // remove the match from the string to parse the rest as properties - string = string.replace(match[0], ""); - } - - // matches a line with name="property" - var propertyRE = /(\w+)="([^\=\<\>]+?)"/igm - var match; - while (match = propertyRE.exec(string)){ - // set the property on the object - this[match[1]] = match[2]; - } -} diff --git a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_frame.js b/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_frame.js deleted file mode 100644 index e1d1dd7fad..0000000000 --- a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_frame.js +++ /dev/null @@ -1,623 +0,0 @@ -////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// -// -// openHarmony Library -// -// -// Developed by Mathieu Chaptel, Chris Fourney -// -// -// This library is an open source implementation of a Document Object Model -// for Toonboom Harmony. It also implements patterns similar to JQuery -// for traversing this DOM. -// -// Its intended purpose is to simplify and streamline toonboom scripting to -// empower users and be easy on newcomers, with default parameters values, -// and by hiding the heavy lifting required by the official API. -// -// This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is guaranteed to work. Feel free to contribute -// improvements to its official github. If you do make sure you follow the provided -// template and naming conventions and document your new methods properly. -// -// This library doesn't overwrite any of the objects and classes of the official -// Toonboom API which must remains available. -// -// This library is made available under the Mozilla Public license 2.0. -// https://www.mozilla.org/en-US/MPL/2.0/ -// -// The repository for this library is available at the address: -// https://github.com/cfourney/OpenHarmony/ -// -// -// For any requests feel free to contact m.chaptel@gmail.com -// -// -// -// -////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oFrame class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * The constructor for the $.oFrame. - * @constructor - * @classdesc Frames describe the frames of a oColumn, and allow to access the value, ease settings, as well as frameNumber. - * @param {int} frameNumber The frame to which this references. - * @param {oColumn} oColumnObject The column to which this frame references. - * @param {int} subColumns The subcolumn index. - * - * @property {int} frameNumber The frame to which this references. - * @property {oColumn} column The oColumnObject to which this frame references. - * @property {oAttribute} attributeObject The oAttributeObject to which this frame references. - * @property {int} subColumns The subcolumn index. - * @example - * // to access the frames of a column, simply call oColumn.frames: - * var myColumn = $.scn.columns[O] // access the first column of the list of columns present in the scene - * - * var frames = myColumn.frames; - * - * // then you can iterate over them to check their properties: - * - * for (var i in frames){ - * $.log(frames[i].isKeyframe); - * $.log(frames[i].continuity); - * } - * - * // you can get and set the value of the frame - * - * frames[1].value = 5; // frame array values and frameNumbers are matched, so this sets the value of frame 1 - */ -$.oFrame = function( frameNumber, oColumnObject, subColumns ){ - this._type = "frame"; - - this.frameNumber = frameNumber; - - if( oColumnObject instanceof $.oAttribute ){ //Direct access to an attribute, when not keyable. We still provide a frame access for consistency. > MCNote ????? - this.column = false; - this.attributeObject = oColumnObject; - }else if( oColumnObject instanceof $.oColumn ){ - this.column = oColumnObject; - - if (this.column && typeof subColumns === 'undefined'){ - var subColumns = this.column.subColumns; - }else{ - var subColumns = { a : 1 }; - } - - this.attributeObject = this.column.attributeObject; - } - - this.subColumns = subColumns; -} - - -// $.oFrame Object Properties -/** - * The value of the frame. Contextual to the attribute type. - * @name $.oFrame#value - * @type {object} - * @todo Include setting values on column that don't have attributes linked? - */ -Object.defineProperty($.oFrame.prototype, 'value', { - get : function(){ - if (this.attributeObject){ - this.$.debug("getting value of frame "+this.frameNumber+" through attribute object : "+this.attributeObject.keyword, this.$.DEBUG_LEVEL.LOG); - return this.attributeObject.getValue(this.frameNumber); - }else{ - this.$.debug("getting value of frame "+this.frameNumber+" through column object : "+this.column.name, this.$.DEBUG_LEVEL.LOG); - return this.column.getValue(this.frameNumber); - } - /* - // this.$.log("Getting value of frame "+this.frameNumber+" of column "+this.column.name) - if (this.attributeObject){ - return this.attributeObject.getValue(this.frameNumber); - }else{ - this.$.debug("getting unlinked column "+this.name+" value at frame "+this.frameNumber, this.$.DEBUG_LEVEL.ERROR); - this.$.debug("warning : getting a value from a column without attribute destroys value fidelity", this.$.DEBUG_LEVEL.ERROR); - if (this. - return column.getEntry (this.name, 1, this.frameNumber); - }*/ - }, - - set : function(newValue){ - if (this.attributeObject){ - return this.attributeObject.setValue(newValue, this.frameNumber); - }else{ - return this.column.setValue(newValue, this.frameNumber); - } - - /*// this.$.log("Setting frame "+this.frameNumber+" of column "+this.column.name+" to value: "+newValue) - if (this.attributeObject){ - this.attributeObject.setValue( newValue, this.frameNumber ); - }else{ - this.$.debug("setting unlinked column "+this.name+" value to "+newValue+" at frame "+this.frameNumber, this.$.DEBUG_LEVEL.ERROR); - this.$.debug("warning : setting a value on a column without attribute destroys value fidelity", this.$.DEBUG_LEVEL.ERROR); - - var _subColumns = this.subColumns; - for (var i in _subColumns){ - column.setEntry (this.name, _subColumns[i], this.frameNumber, newValue); - } - }*/ - } -}); - - -/** - * Whether the frame is a keyframe. - * @name $.oFrame#isKeyframe - * @type {bool} - */ -Object.defineProperty($.oFrame.prototype, 'isKeyframe', { - get : function(){ - if( !this.column ) return true; - if( this.frameNumber == 0 ) return false; // frames array start at 0 but first index is not a real frame - - var _column = this.column.uniqueName; - if (this.column.type == 'DRAWING' || this.column.type == 'TIMING'){ - if( column.getTimesheetEntry){ - return !column.getTimesheetEntry(_column, 1, this.frameNumber).heldFrame; - }else{ - return false; //No valid way to check for keys on a drawing without getTimesheetEntry - } - }else if (['BEZIER', '3DPATH', 'EASE', 'QUATERNION'].indexOf(this.column.type) != -1){ - return column.isKeyFrame(_column, 1, this.frameNumber); - } - return false; - }, - - set : function(keyframe){ - this.$.log("setting keyframe for frame "+this.frameNumber); - var col = this.column; - if( !col ) return; - - var _column = col.uniqueName; - - if( col.type == "DRAWING" ){ - if (keyframe){ - column.addKeyDrawingExposureAt( _column, this.frameNumber ); - }else{ - column.removeKeyDrawingExposureAt( _column, this.frameNumber ); - } - }else{ - if (keyframe){ - //Sanity check, in certain situations, the setKeyframe resets to 0 (specifically if there is no pre-existing key elsewhere.) - //This will check the value prior to the key, set the key, and enforce the value after. - - //var val = 0.0; - // try{ - var val = this.value; - // }catch(err){} - //this.$.log("setting keyframe for frame "+this.frameNumber); - column.setKeyFrame( _column, this.frameNumber ); - - // try{ - //var post_val = this.value; - //if (val != post_val) { - this.value = val; - //} - // }catch(err){} - }else{ - column.clearKeyFrame( _column, this.frameNumber ); - } - } - } -}); - - -/** - * Whether the frame is a keyframe. - * @name $.oFrame#isKeyFrame - * @deprecated For case consistency, keyframe will never have a capital F - * @type {bool} - */ -Object.defineProperty($.oFrame.prototype, 'isKeyFrame', { - get : function(){ - return this.isKeyframe; - }, - - set : function(keyframe){ - this.$.debug("oFrame.isKeyFrame is deprecated. Use oFrame.isKeyframe instead.", this.$.DEBUG_LEVEL.ERROR); - this.isKeyframe = keyframe; - } -}); - - -/** - * Whether the frame is a keyframe. - * @name $.oFrame#isKey - * @type {bool} - */ -Object.defineProperty($.oFrame.prototype, 'isKey', { - get : function(){ - return this.isKeyframe; - }, - - set : function(keyFrame){ - this.isKeyframe = keyFrame; - } -}); - - -/** - * The duration of the keyframe exposure of the frame. - * @name $.oFrame#duration - * @type {int} - */ -Object.defineProperty($.oFrame.prototype, 'duration', { - get : function(){ - var _startFrame = this.startFrame; - var _sceneLength = frame.numberOf() - - if( !this.column ){ - return _sceneLength; - } - - // walk up the frames of the scene to the next keyFrame to determine duration - var _frames = this.column.frames - for (var i=this.frameNumber+1; i<_sceneLength; i++){ - if (_frames[i].isKeyframe) return _frames[i].frameNumber - _startFrame; - } - return _sceneLength - _startFrame; - }, - - set : function( val ){ - throw "Not implemented."; - } -}); - - -/** - * Identifies if the frame is blank/empty. - * @name $.oFrame#isBlank - * @type {int} - */ -Object.defineProperty($.oFrame.prototype, 'isBlank', { - get : function(){ - var col = this.column; - if( !col ){ - return false; - } - - if ( col.type != "DRAWING") return false; - - if( !column.getTimesheetEntry ){ - return (this.value == ""); - } - - return column.getTimesheetEntry( col.uniqueName, 1, this.frameNumber ).emptyCell; - }, - - set : function( val ){ - throw "Not implemented."; - } -}); - - -/** - * Identifies the starting frame of the exposed drawing. - * @name $.oFrame#startFrame - * @type {int} - * @readonly - */ -Object.defineProperty($.oFrame.prototype, 'startFrame', { - get : function(){ - if( !this.column ){ - return 1; - } - - if (this.isKeyframe) return this.frameNumber; - if (this.isBlank) return -1; - - var _frames = this.column.frames; - for (var i=this.frameNumber-1; i>=1; i--){ - if (_frames[i].isKeyframe) return _frames[i].frameNumber; - } - return -1; - } -}); - - -/** - * Returns the drawing types used in the drawing column. K = key drawings, I = inbetween, B = breakdown - * @name $.oFrame#marker - * @type {string} - */ -Object.defineProperty($.oFrame.prototype, 'marker', { - get : function(){ - if( !this.column ){ - return ""; - } - - var _column = this.column; - if (_column.type != "DRAWING") return ""; - return column.getDrawingType(_column.uniqueName, this.frameNumber); - }, - - set: function( marker ){ - if( !this.column ){ - return; - } - - var _column = this.column; - if (_column.type != "DRAWING") throw "can't set 'marker' property on columns that are not 'DRAWING' type" - column.setDrawingType( _column.uniqueName, this.frameNumber, marker ); - } -}); - - -/** - * Find the index of this frame in the corresponding columns keyframes. -1 if unavailable. - * @name $.oFrame#keyframeIndex - * @type {int} - */ -Object.defineProperty($.oFrame.prototype, 'keyframeIndex', { - get : function(){ - var _kf = this.column.getKeyframes().map(function(x){return x.frameNumber}); - var _kfIndex = _kf.indexOf(this.frameNumber); - return _kfIndex; - } -}); - - -/** - * Find the the nearest keyframe to this, on the left. Returns itself if it is a key. - * @name $.oFrame#keyframeLeft - * @type {oFrame} - */ -Object.defineProperty($.oFrame.prototype, 'keyframeLeft', { - get : function(){ - return (new this.$.oFrame(this.startFrame, this.column)); - } -}); - - -/** - * Find the the nearest keyframe to this, on the right. - * @name $.oFrame#keyframeRight - * @type {oFrame} - */ -Object.defineProperty($.oFrame.prototype, 'keyframeRight', { - get : function(){ - return (new this.$.oFrame(this.startFrame+this.duration, this.column)); - } -}); - - -/** - * Access the velocity value of a keyframe from a 3DPATH column. - * @name $.oFrame#velocity - * @type {oFrame} - */ -Object.defineProperty($.oFrame.prototype, 'velocity', { - get : function(){ - if (!this.column) return null; - if (this.column.type != "3DPATH") return null; - var _columnName = this.column.uniqueName; - if (!this.isKeyframe) return column.getEntry(_columnName, 4, this.frameNumber); - - var index = this.keyframeIndex; - - var _y = func.pointY(_columnName, index); - return _y; - }, - - set : function(newVelocity){ - var _curVelocity = this.velocity; - throw new Error("setting oFrame.velocity is not yet implemented") - } -}); - - -/** - * Gets a general ease object for the frame, which can be used to set frames to the same ease values. ease Objects contain the following properties: - * x : frame number - * y : position of the value of the column or velocity for 3dpath - * easeIn : a $.oPoint object representing the left handle for bezier columns, or a {point, ease} object for ease columns. - * easeOut : a $.oPoint object representing the left handle for bezier columns, or a {point, ease} object for ease columns. - * continuity : the type of bezier used by the point. - * constant : whether the frame is interpolated or a held value. - * @name $.oFrame#ease - * @type {oPoint/object} - */ -Object.defineProperty($.oFrame.prototype, 'ease', { - get : function(){ - var _column = this.column; - if (!_column) return null; - if ( !this.isKeyFrame ) return null; - if ( this.isBlank ) return null; - - var _columnName = _column.uniqueName; - var _index = this.keyframeIndex; - - var ease = { - x : func.pointX(_columnName, _index), - y : func.pointY(_columnName, _index), - constant : func.pointConstSeg(_columnName, _index), - continuity : func.pointContinuity(_columnName, _index) - } - - if( _column.easeType == "BEZIER" ){ - ease.easeIn = new this.$.oPoint(func.pointHandleLeftX(_columnName, _index), func.pointHandleLeftY(_columnName, _index),0); - ease.easeOut = new this.$.oPoint(func.pointHandleRightX(_columnName, _index), func.pointHandleRightY(_columnName, _index),0); - } - - if( _column.easeType == "EASE" ){ - ease.easeIn = {point:func.pointEaseIn(_columnName, _index), angle:func.angleEaseIn(_columnName, _index)}; - ease.easeOut = {point:func.pointEaseOut(_columnName, _index), angle:func.angleEaseOut(_columnName, _index)}; - } - - return ease; - }, - - set : function(newEase){ - if ( !this.isKeyFrame ) throw new Error("can't set ease on a non keyframe");; - if (this.isBlank) throw new Error("can't set ease on an empty frame"); - - var _column = this.column; - if (!_column) throw new Error ("Can't set ease on a frame without a column"); - var _columnName = _column.uniqueName; - - if( _column.easeType == "BEZIER" ){ - if (!newEase.hasOwnProperty("x")) throw new Error("Incorrect ease type for a BEZIER column"); - func.setBezierPoint (_columnName, newEase.x, newEase.y, newEase.easeIn.x, newEase.easeIn.y, newEase.easeOut.x, newEase.easeOut.y, newEase.constant, newEase.continuity) - } - - if (_column.easeType == "EASE" ){ - if (!newEase.hasOwnProperty("point")) throw new Error("Incorrect ease type for a EASE column"); - func.setEasePoint(_columnName, newEase.x, newEase.y, newEase.easeIn.point, newEase.easeIn.angle, newEase.easeOut.point, newEase.easeOut.angle, newEase.constant, newEase.continuity) - } - } -}); - - -/** - * Gets the ease parameter of the segment, easing into this frame. - * @name $.oFrame#easeIn - * @type {oPoint/object} - */ -Object.defineProperty($.oFrame.prototype, 'easeIn', { - get : function(){ - return this.ease.easeIn; - }, - - set : function(newEaseIn){ - var _ease = this.ease; - _ease.easeIn = newEaseIn; - - this.ease = ease; - } -}); - - -/** - * Gets the ease parameter of the segment, easing out of this frame. - * @name $.oFrame#easeOut - * @type {oPoint/object} - */ -Object.defineProperty($.oFrame.prototype, 'easeOut', { - get : function(){ - return this.ease.easeOut; - }, - - set : function(newEaseOut){ - var _ease = this.ease; - _ease.easeOut = newEaseOut; - - this.ease = _ease; - } -}); - - -/** - * Determines the frame's continuity setting. Can take the values "CORNER", (two independent bezier handles on each side), "SMOOTH"(handles are aligned) or "STRAIGHT" (no handles and in straight lines). - * @name $.oFrame#continuity - * @type {string} - */ -Object.defineProperty($.oFrame.prototype, 'continuity', { - get : function(){ - var _frame = this.keyframeLeft; //Works on the left keyframe, in the event that this is not a keyframe itself. - - return _frame.ease.continuity; - }, - - set : function( newContinuity ){ - var _frame = this.keyframeLeft; //Works on the left keyframe, in the event that this is not a keyframe itself. - var _ease = _frame.ease; - _ease.continuity = newContinuity; - - _frame.ease = ease; - } -}); - - -/** - * Whether the frame is tweened or constant. Uses nearest keyframe if this frame isnt. - * @name $.oFrame#constant - * @type {string} - */ -Object.defineProperty($.oFrame.prototype, 'constant', { - get : function(){ - var _frame = this.keyframeLeft; //Works on the left keyframe, in the event that this is not a keyframe itself. - - return _frame.ease.constant; - }, - - set : function( newConstant ){ - if( this.column ){ - var _frame = this.keyframeLeft; //Works on the left keyframe, in the event that this is not a keyframe itself. - - var _ease = _frame.ease; - _ease.constant = newConstant; - _frame.ease = _ease; - } - } -}); - - -/** - * Identifies or sets whether there is a tween. Inverse of constant. - * @name $.oFrame#tween - * @type {string} - */ -Object.defineProperty($.oFrame.prototype, 'tween', { - get : function(){ - return !this.constant; - }, - set : function( new_tween ){ - this.constant = !new_tween; - } -}); - - - -// oFrame Class Methods - - -/** - * Extends the frames value to the specified duration, replaces in the event that replace is specified. - * @param {int} duration The duration to extend it to; if no duration specified, extends to the next available keyframe. - * @param {bool} replace Setting this to false will insert frames as opposed to overwrite existing ones. - */ -$.oFrame.prototype.extend = function( duration, replace ){ - if (typeof replace === 'undefined') var replace = true; - // setting this to false will insert frames as opposed to overwrite existing ones - - if( !this.column ){ - return; - } - - var _frames = this.column.frames; - - if (typeof duration === 'undefined'){ - // extend to next non blank keyframe if not set - var duration = 0; - var curFrameEnd = this.startFrame + this.duration; - var sceneLength = this.$.scene.length; - - // find next non blank keyframe - while ((curFrameEnd + duration) <= sceneLength && _frames[curFrameEnd + duration].isBlank){ - duration ++; - } - } - - var _value = this.value; - var startExtending = this.startFrame+this.duration; - - for (var i = 0; i - * Provides a list of values similar to an array, but with simpler filtering and sorting functions provided.
- * It can have any starting index and so can implement lists with a first index of 1 like the $.oColumn.frames returned value. - * @param {object[]} initArray An array to initialize the list. - * @param {int} [startIndex=0] The first index exposed in the list. - * @param {int} [length=0] The length of the list -- the max between this value and the initial array's length is used. - * @param {function} [getFunction=null] The function used to initialize the list when accessing an uninitiated element in the list.
In form function( listItem, index ){ return value; } - * @param {function} [setFunction=null] The function run when setting an entry in the list.
In form function( listItem, index, value ){ return resolvedValue; } -- must return a resolved value. - * @param {function} [sizeFunction=null] The function run when resizing the list.
In form function( listItem, length ){ } - */ -$.oList = function( initArray, startIndex, length, getFunction, setFunction, sizeFunction ){ - if(typeof initArray == 'undefined') var initArray = []; - if(typeof startIndex == 'undefined') var startIndex = 0; - if(typeof getFunction == 'undefined') var getFunction = false; - if(typeof setFunction == 'undefined') var setFunction = false; - if(typeof sizeFunction == 'undefined') var sizeFunction = false; - if(typeof length == 'undefined') var length = 0; - - //Extend the cache if the content has been provided initially. - //Must be not enumerable. . . - // this._initArray = initArray; - // this._cache = []; - - // this._getFunction = getFunction; - // this._setFunction = setFunction; - // this._sizeFunction = sizeFunction; - - // this.startIndex = startIndex; - // this._length = Math.max( initArray.length, startIndex+length ); - // this.currentIndex = startIndex; - - Object.defineProperty( this, '_initArray', { - enumerable : false, writable : true, - value: initArray - }); - - Object.defineProperty( this, '_cache', { - enumerable : false, writable : true, - value: [] - }); - - Object.defineProperty( this, '_getFunction', { - enumerable : false, writable : true, configurable: false, - value: getFunction - }); - - Object.defineProperty( this, '_setFunction', { - enumerable : false, writable : true, configurable: false, - value: setFunction - }); - - Object.defineProperty( this, '_sizeFunction', { - enumerable : false, writable : true, configurable: false, - value: sizeFunction - }); - - Object.defineProperty( this, 'currentIndex', { - enumerable : false, writable : true, configurable: false, - value: startIndex - }); - - Object.defineProperty( this, '_startIndex', { - enumerable : false, writable : true, configurable: false, - value: startIndex - }); - - Object.defineProperty( this, '_length', { - enumerable : false, writable : true, configurable: false, - value: Math.max( initArray.length, startIndex+length ) - }); - - this.createGettersSetters(); -} - - -Object.defineProperty( $.oList.prototype, '_type', { - enumerable : false, writable : false, configurable: false, - value: 'dynList' -}); - - -/** - * The next item in the list, undefined if reaching the end of the list. - * @name $.oList#createGettersSetters - * @private - */ -Object.defineProperty($.oList.prototype, 'createGettersSetters', { - enumerable : false, - value: function(){ - { - //Dynamic getter/setters. - var func_get = function( listItem, index ){ - if( index >= listItem._cache._length ) return null; - if( listItem._cache[index].cacheAvailable ){ - return listItem._cache[index].value; - } - if( listItem._getFunction ){ - listItem._cache[index].cacheAvailable = true; - listItem._cache[index].value = listItem._getFunction( listItem, index ); - return listItem._cache[ index ].value; - } - return null; - }; - - //Either set the cache function directly, or run the setFunction to get a value and set it. - var func_set = function( listItem, index, value ){ - if( index >= listItem._cache._length ){ - if( listItem._sizeFunction ){ - listItem.length = index+1; - }else{ - throw new ReferenceError( 'Index of out of range: '+index+ ' out of ' + listItem._cache._length ) - } - } - - if( listItem._setFunction ){ - listItem._cache[index].cacheAvailable = true; - try{ - listItem._cache[index].value = listItem._setFunction( listItem, index, value ); - }catch(err){} - }else{ - listItem._cache[index].cacheAvailable = true; - listItem._cache[index].value = value; - } - }; - - var setup_length = Math.max( this._length, this._cache.length ); - if( this._cache.length < setup_length ){ - this._cache = this._cache.concat( new Array( setup_length-this._cache.length ) ); - } - - for( var n=0;n=this.startIndex && n< this.length; - - if( currentEnumerable && !this._cache[n].enumerable ){ - Object.defineProperty( this, n, { - enumerable : true, - configurable: true, - set : eval( 'val = function(val){ return func_set( this, '+n+', val ); }' ), - get : eval( 'val = function(){ return func_get( this, '+n+'); }' ) - }); - this._cache[n].enumerable = true; - }else if( !currentEnumerable && this._cache[n].enumerable ){ - Object.defineProperty( this, n, { - enumerable : false, - configurable: true, - value : null - }); - this._cache[n].enumerable = false; - } - } - } - } -}); - - -/** - * The startIndex of the list. - * @name $.oList#startIndex - * @type {int} - */ -Object.defineProperty( $.oList.prototype, 'startIndex', { - enumerable : false, - get: function(){ - return this._startIndex; - }, - - set: function( val ){ - this._startIndex = val; - this.currentIndex = Math.max( this.currentIndex, val ); - - this.createGettersSetters(); - } -}); - - -/** - * The length of the list. - * @name $.oList#length - * @function - * @return {int} The length of the list, considering the startIndex. - */ -Object.defineProperty($.oList.prototype, 'length', { - enumerable : false, - get: function(){ - return this._length; - }, - - set: function( val ){ - //Reset the size as needed. - - var new_val = val+this.startIndex; - if( new_val != this._length ){ - this._length = new_val; - this.createGettersSetters(); - } - - this._sizeFunction( this, this._length ); - } -}); - - -/** - * The first item in the list, resets the iterator to the first entry. - * @name $.oList#first - * @function - * @return {object} The first item in the list. - */ -Object.defineProperty($.oList.prototype, 'first', { - enumerable : false, - value: function(){ - this.currentIndex = this.startIndex; - return this[ this.startIndex ]; - } -}); - -/** - * The next item in the list, undefined if reaching the end of the list. - * @name $.oList#next - * @function - * @return {object} Grabs the next item using the property $.oList.currentIndex, and increase the iterator - * @example - * var myList = new $.oList([1,2,3], 1) - * - * var item = myList.first(); // 1 - * - * while( item != undefined ){ - * $.log(item) // traces the whole array one item at a time : 1,2,3 - * item = myList.next(); - * } - */ -Object.defineProperty($.oList.prototype, 'next', { - enumerable : false, - value: function(){ - this.currentIndex++; - - if( this.currentIndex >= this.length ){ - return; - } - if( !this.hasOwnProperty( this.currentIndex) ) return; // we return undefined so we can check correctly in the case of list of boolean values - - return this[ this.currentIndex ]; - } -}); - - -/** - * The index of the last valid element of the list - * @name $.oList#lastIndex - * @type {int} - */ -Object.defineProperty($.oList.prototype, 'lastIndex', { - enumerable : false, - get: function(){ - return this.length - 1; - } -}); - - -/** - * Similar to Array.push. Adds the value given as parameter to the end of the oList - * @name $.oList#push - * @function - * @param {various} newElement The value to add at the end of the oList - * - * @return {int} Returns the new length of the oList. - */ -Object.defineProperty($.oList.prototype, 'push', { - enumerable : false, - value : function( newElement ){ - var origLength = this.length; - this.length = origLength+1; - - this[ origLength ] = newElement; - return origLength+1; - } -}); - -/** - * Similar to Array.pop. Removes the last value from the array and returns it. It is then removed from the array. - * @name $.oList#pop - * @function - * @return {int} The item popped from the back of the array. - */ -Object.defineProperty($.oList.prototype, 'pop', { - enumerable : false, - value : function( ){ - - var origLength = this.length; - if( !this.hasOwnProperty( origLength-1 ) ){ - return; - } - - var cache = this._cache.pop(); - - this.length = origLength-1; - - return cache.value; - } -}); - - -/** - * Returns an oList object containing only the elements that passed the provided filter function. - * @name $.oList#filterByFunction - * @function - * @param {function} func A function that is used to filter, returns true if it is to be kept in the list. - * - * @return {$.oList} The list represented as an array, filtered given the function. - */ -Object.defineProperty($.oList.prototype, 'filterByFunction', { - enumerable : false, - value : function( func ){ - var _results = []; - for (var i in this){ - if ( func(this[i]) ){ - _results.push( this[i] ); - } - } - - return new this.$.oList( _results ); - } -}); - - -/** - * Returns an oList object containing only the elements that have the same property value as provided. - * @name $.oList#filterByProperty - * @function - * @param {string} property The property to find. - * @param {string} search The value to search for in the property. - * - * @return {$.oList} The list represented as an array, filtered given its properties. - * @example - * var doc = $.s // grab the scene object - * var nodeList = new $.oList(doc.nodes, 1) // get a list of all the nodes, with a first index of 1 - * - * $.log(nodeList) // outputs the list of all the node paths - * - * var readNodes = nodeList.filterByProperty("type", "READ") // get a new list of only the nodes of type 'READ' - * - * $.log(readNodes.extractProperty("name")) // prints the names of the result - * - */ -Object.defineProperty($.oList.prototype, 'filterByProperty', { - enumerable : false, - value : function(property, search){ - var _results = [] - var _lastIndex = this.lastIndex; - for (var i=this.startIndex; i < _lastIndex; i++){ - // this.$.log(i+" "+(property in this[i])+" "+(this[i][property] == search)+_lastIndex) - if ((property in this[i]) && (this[i][property] == search)) _results.push(this[i]) - } - // this.$.log(_results) - return new this.$.oList(_results) - } -}); - - -/** - * Returns an oList object containing only the values of the specified property. - * @name $.oList#extractProperty - * @function - * @param {string} property The property to find. - * - * @return {$.oList} The newly created oList object containing the property values. - */ -Object.defineProperty($.oList.prototype, 'extractProperty', { - enumerable : false, - value : function(property){ - var _results = [] - var _lastIndex = this.lastIndex; - for (var i=this.startIndex; i < _lastIndex; i++){ - _results.push(this[i][property]) - } - return new this.$.oList(_results) - } -}); - - -/** - * Returns an oList object sorted according to the values of the specified property. - * @name $.oList#sortByProperty - * @function - * @param {string} property The property to find. - * @param {bool} [ascending=true] Whether the sort is ascending/descending. - * - * @return {$.oList} The sorted $oList. - */ -Object.defineProperty($.oList.prototype, 'sortByProperty', { - enumerable : false, - value : function( property, ascending ){ - if (typeof ascending === 'undefined') var ascending = true; - - var _array = this.toArray(); - if (ascending){ - var results = _array.sort(function (a,b){return a[property] - b[property]}); - }else{ - var results = _array.sort(function (a,b){return b[property] - a[property]}); - } - - // Sort in place or return a copy? - return new this.$.oList( results, this.startIndex ); - } -}); - - -/** - * Returns an oList object sorted according to the sorting function provided. - * @name $.oList#sortByFunction - * @function - * @param {function} func A function that is used to sort, in form function (a,b){return a - b}. (A positive a-b value will put the element b before a) - * - * @return {$.oList} The sorted $oList. - */ -Object.defineProperty($.oList.prototype, 'sortByFunction', { - enumerable : false, - value : function( func ){ - var _array = this.toArray(); - var results = _array.sort( func ); - - // Sort in place or return a copy? - return new this.$.oList( results, this.startIndex ); - } -}); - - -// Methods must be declared as unenumerable properties this way -/** - * Converts the oList to an array - * @name $.oList#toArray - * @function - * @return {object[]} The list represented as an array. - */ -Object.defineProperty($.oList.prototype, 'toArray', { - enumerable : false, - value : function(){ - var _array = []; - for (var i=0; i this.right) this.right = box.right; - if (box.bottom > this.bottom) this.bottom = box.bottom; -} - - -/** - * Checks whether the box contains another $.oBox. - * @param {$.oBox} box The $.oBox to check for. - * @param {bool} [partial=false] whether to accept partially contained boxes. - */ -$.oBox.prototype.contains = function(box, partial){ - if (typeof partial === 'undefined') var partial = false; - - var fitLeft = (box.left >= this.left); - var fitTop = (box.top >= this.top); - var fitRight =(box.right <= this.right); - var fitBottom = (box.bottom <= this.bottom); - - if (partial){ - return (fitLeft || fitRight) && (fitTop || fitBottom); - }else{ - return fitLeft && fitRight && fitTop && fitBottom; - } - -} - -/** - * Adds the bounds of the nodes to the current $.oBox. - * @param {oNode[]} oNodeArray An array of nodes to include in the box. - */ -$.oBox.prototype.includeNodes = function(oNodeArray){ - // convert to array if only one node is passed - if (!Array.isArray(oNodeArray)) oNodeArray = [oNodeArray]; - - for (var i in oNodeArray){ - var _node = oNodeArray[i]; - var _nodeBox = _node.bounds; - this.include(_nodeBox); - } -} - -/** - * @private - */ -$.oBox.prototype.toString = function(){ - return "{top:"+this.top+", right:"+this.right+", bottom:"+this.bottom+", left:"+this.left+"}" -} - - - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oMatrix class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - -/** - * The $.oMatrix constructor. - * @constructor - * @classdesc The $.oMatrix is a subclass of the native Matrix4x4 object from Harmony. It has the same methods and properties plus the ones listed here. - * @param {Matrix4x4} matrixObject a matrix object to initialize the instance from - */ -$.oMatrix = function(matrixObject){ - Matrix4x4.constructor.call(this); - if (matrixObject){ - log(matrixObject) - this.m00 = matrixObject.m00; - this.m01 = matrixObject.m01; - this.m02 = matrixObject.m02; - this.m03 = matrixObject.m03; - this.m10 = matrixObject.m10; - this.m11 = matrixObject.m11; - this.m12 = matrixObject.m12; - this.m13 = matrixObject.m13; - this.m20 = matrixObject.m20; - this.m21 = matrixObject.m21; - this.m22 = matrixObject.m22; - this.m23 = matrixObject.m23; - this.m30 = matrixObject.m30; - this.m31 = matrixObject.m31; - this.m32 = matrixObject.m32; - this.m33 = matrixObject.m33; - } -} -$.oMatrix.prototype = Object.create(Matrix4x4.prototype) - - -/** - * A 2D array that contains the values from the matrix, rows by rows. - * @name $.oMatrix#values - * @type {Array} - */ -Object.defineProperty($.oMatrix.prototype, "values", { - get:function(){ - return [ - [this.m00, this.m01, this.m02, this.m03], - [this.m10, this.m11, this.m12, this.m13], - [this.m20, this.m21, this.m22, this.m23], - [this.m30, this.m31, this.m32, this.m33], - ] - } -}) - - -/** - * @private - */ -$.oMatrix.prototype.toString = function(){ - return "< $.oMatrix object : \n"+this.values.join("\n")+">"; -} - - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oVector class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * The $.oVector constructor. - * @constructor - * @classdesc The $.oVector is a replacement for the Vector3d objects of Harmony. - * @param {float} x a x coordinate for this vector. - * @param {float} y a y coordinate for this vector. - * @param {float} [z=0] a z coordinate for this vector. If omitted, will be set to 0 and vector will be 2D. - */ -$.oVector = function(x, y, z){ - if (typeof z === "undefined" || isNaN(z)) var z = 0; - - // since Vector3d doesn't have a prototype, we need to cheat to subclass it. - this._vector = new Vector3d(x, y, z); -} - - -/** - * The X Coordinate of the vector. - * @name $.oVector#x - * @type {float} - */ -Object.defineProperty($.oVector.prototype, "x", { - get: function(){ - return this._vector.x; - }, - set: function(newX){ - this._vector.x = newX; - } -}) - - -/** - * The Y Coordinate of the vector. - * @name $.oVector#y - * @type {float} - */ -Object.defineProperty($.oVector.prototype, "y", { - get: function(){ - return this._vector.y; - }, - set: function(newY){ - this._vector.y = newY; - } -}) - - -/** - * The Z Coordinate of the vector. - * @name $.oVector#z - * @type {float} - */ -Object.defineProperty($.oVector.prototype, "z", { - get: function(){ - return this._vector.z; - }, - set: function(newX){ - this._vector.z = newX; - } -}) - - -/** - * The length of the vector. - * @name $.oVector#length - * @type {float} - * @readonly - */ -Object.defineProperty($.oVector.prototype, "length", { - get: function(){ - return this._vector.length(); - } -}) - - -/** - * @static - * A function of the oVector class (not oVector objects) that gives a vector from two points. - */ -$.oVector.fromPoints = function(pointA, pointB){ - return new $.oVector(pointB.x-pointA.x, pointB.y-pointA.y, pointB.z-pointA.z); -} - - -/** - * Adds another vector to this one. - * @param {$.oVector} vector2 - * @returns {$.oVector} returns itself. - */ -$.oVector.prototype.add = function (vector2){ - this.x += vector2.x; - this.y += vector2.y; - this.z += vector2.z; - - return this; -} - - -/** - * Multiply this vector coordinates by a number (scalar multiplication) - * @param {float} num - * @returns {$.oVector} returns itself - */ -$.oVector.prototype.multiply = function(num){ - this.x = num*this.x; - this.y = num*this.y; - this.z = num*this.z; - - return this; -} - - -/** - * The dot product of the two vectors - * @param {$.oVector} vector2 a vector object. - * @returns {float} the resultant vector from the dot product of the two vectors. - */ -$.oVector.prototype.dot = function(vector2){ - var _dot = this._vector.dot(new Vector3d(vector2.x, vector2.y, vector2.z)); - return _dot; -} - -/** - * The cross product of the two vectors - * @param {$.oVector} vector2 a vector object. - * @returns {$.oVector} the resultant vector from the dot product of the two vectors. - */ -$.oVector.prototype.cross = function(vector2){ - var _cross = this._vector.cross(new Vector3d(vector2.x, vector2.y, vector2.z)); - return new this.$.oVector(_cross.x, _cross.y, _cross.z); -} - -/** - * The projected vectors resulting from the operation - * @param {$.oVector} vector2 a vector object. - * @returns {$.oVector} the resultant vector from the projection of the current vector. - */ -$.oVector.prototype.project = function(vector2){ - var _projection = this._vector.project(new Vector3d(vector2.x, vector2.y, vector2.z)); - return new this.$.oVector(_projection.x, _projection.y, _projection.z); -} - -/** - * Normalize the vector. - * @returns {$.oVector} returns itself after normalization. - */ -$.oVector.prototype.normalize = function(){ - this._vector.normalize(); - return this; -} - - -/** - * The angle of this vector in radians. - * @name $.oVector#angle - * @type {float} - * @readonly - */ -Object.defineProperty($.oVector.prototype, "angle", { - get: function(){ - return Math.atan2(this.y, this.x); - } -}) - - -/** - * The angle of this vector in degrees. - * @name $.oVector#degreesAngle - * @type {float} - * @readonly - */ -Object.defineProperty($.oVector.prototype, "degreesAngle", { - get: function(){ - return this.angle * (180 / Math.PI); - } -}) - - -/** - * @private - */ -$.oVector.prototype.toString = function(){ - return "<$.oVector ["+this.x+", "+this.y+", "+this.z+"]>"; -} - diff --git a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_metadata.js b/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_metadata.js deleted file mode 100644 index 29afeb522c..0000000000 --- a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_metadata.js +++ /dev/null @@ -1,282 +0,0 @@ -////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// -// -// openHarmony Library v0.01 -// -// -// Developed by Mathieu Chaptel, Chris Fourney... -// -// -// This library is an open source implementation of a Document Object Model -// for Toonboom Harmony. It also implements patterns similar to JQuery -// for traversing this DOM. -// -// Its intended purpose is to simplify and streamline toonboom scripting to -// empower users and be easy on newcomers, with default parameters values, -// and by hiding the heavy lifting required by the official API. -// -// This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is guaranteed to work. Feel free to contribute -// improvements to its official github. If you do make sure you follow the provided -// template and naming conventions and document your new methods properly. -// -// This library doesn't overwrite any of the objects and classes of the official -// Toonboom API which must remains available. -// -// This library is made available under the MIT license. -// https://opensource.org/licenses/mit -// -// The repository for this library is available at the address: -// https://github.com/cfourney/OpenHarmony/ -// -// -// For any requests feel free to contact m.chaptel@gmail.com -// -// -// -// -////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// - - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oMetadata class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * The constructor for the $.oMetadata class. - * @classdesc Provides access to getting/setting metadata as an object interface.
Given a node as a source, will use provide the metadata associated to that node, - * otherwise provides metadata for the scene. - * @param {$.oNode} source A node as the source of the metadata-- otherwise provides the scene metadata. - * @todo Need to extend this to allow node metadata. - * @constructor - * @example - * var metadata = $.scene.getMetadata(); - * metadata.create( "mySceneMetadataName", {"ref":"thisReferenceValue"} ); - * metadata["mySceneMetadataName"]; //Provides: {"ref":"thisReferenceValue"} - */ -$.oMetadata = function( source ){ - this._type = "metadata"; - if( !source ){ source = 'scene'; } - this.source = source; - - this._metadatas = {}; - - this.refresh(); -} - - -/** - * Refreshes the preferences by re-reading the preference file and ingesting their values appropriately. They are then available as properties of this class.
- * Note, any new preferences will not be available as properties until Harmony saves the preference file at exit. In order to reference new preferences, use the get function. - * @name $.oMetadata#refresh - * @function - */ -$.oMetadata.prototype.refresh = function(){ - - //---------------------------- - //GETTER/SETTERS - var set_val = function( meta, name, val ){ - var metadata = meta._metadatas[ name ]; - - var valtype = false; - var jsonify = false; - switch( typeof val ){ - case 'string': - valtype = 'string'; - break; - case 'number': - if( val%1.0==0.0 ){ - valtype = 'int'; - }else{ - valtype = 'double'; - } - break - case 'boolean': - case 'undefined': - case 'null': - valtype = 'bool'; - break - case 'object': - default: - valtype = 'string'; - jsonify = true; - break - } - - if(jsonify){ - val = 'json('+JSON.stringify( val )+')'; - } - - if( meta.source == "scene" ){ - var type = false; - scene.setMetadata( { - "name" : name, - "type" : valtype, - "creator" : "OpenHarmony", - "version" : "1.0", - "value" : val - } - ); - }else{ - var metaAttr = this.source.attributes["meta"]; - if( metaAttr ){ - metaAttr[ name ] = val; - } - } - - meta.refresh(); - } - - var get_val = function( meta, name ){ - return meta._metadatas[name].value; - } - - //Definition of properties. - var getterSetter_create = function( targ, id, type, value ){ - - if( type == "string" ){ - if( value.slice( 0, 5 ) == "json(" ){ - var obj = value.slice( 5, value.length-1 ); - value = JSON.parse( obj ); - } - } - targ._metadatas[ id ] = { "value": value, "type":type }; - - //Create a getter/setter for it! - Object.defineProperty( targ, id, { - enumerable : true, - configurable: true, - set : eval( 'val = function(val){ set_val( targ, "'+id+'", val ); }' ), - get : eval( 'val = function(){ return get_val( targ, "'+id+'"); }' ) - }); - } - - - //Clear this objects previous getter/setters to make room for new ones. - if( this._metadatas ){ - for( n in this._metadatas ){ //Remove them if they've disappeared. - Object.defineProperty( this, n, { - enumerable : false, - configurable: true, - set : function(){}, - get : function(){} - }); - } - } - this._metadatas = {}; - - if( this.source == "scene" ){ - var metadatas = scene.metadatas(); - - for( var n=0;n0 ){ - for( var i=0;iThe metadata is created on the source to which this metadata object references. - * @name $.oMetadata#create - * @param {string} name The name of the new metadata to create. - * @param {object} val The value of the new metadata created. - */ -$.oMetadata.prototype.create = function( name, val ){ - var name = name.toLowerCase(); - - if( this[ name ] ){ - throw ReferenceError( "Metadata already exists by name: " + name ); - } - - var valtype = false; - var jsonify = false; - switch( typeof val ){ - case 'string': - valtype = 'string'; - break; - case 'number': - if( val%1.0==0.0 ){ - valtype = 'int'; - }else{ - valtype = 'double'; - } - break - case 'boolean': - case 'undefined': - case 'null': - valtype = 'bool'; - break - case 'object': - default: - valtype = 'string'; - jsonify = true; - break - } - - if(jsonify){ - val = 'json('+JSON.stringify( val )+')'; - } - - if( this.source == "scene" ){ - scene.setMetadata( { - "name" : name, - "type" : valtype, - "creator" : "OpenHarmony", - "version" : "1.0", - "value" : val - } - ); - }else{ - var attr = this.source.createAttribute( "meta."+name, valtype, valtype, false ); - if( attr ){ - attr.setValue( val, 1 ); - } - } - this.refresh(); -} - -/** - * Removes a new metadata based on name and value.
The metadata is removed from the source to which this metadata object references. - * @name $.oMetadata#remove - * @param {string} name The name of the metadata to remove. - */ -$.oMetadata.prototype.remove = function( name ){ - var name = name.toLowerCase(); - if( !this.hasOwnProperty( name ) ){ return true; } - - var res = false; - if( this.source == "scene" ){ - if( !scene.removeMetadata ){ - res = scene.removeMetadata( scene.metadata(name), this._metadatas[ name ].type ); - }else{ - throw ReferenceError( "This is supposed to exist, but doesn't seem to be available." ); - } - }else{ - res = this.source.removeAttribute( "meta."+name ); - } - - this.refresh(); - return res; -} \ No newline at end of file diff --git a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_misc.js b/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_misc.js deleted file mode 100644 index 6ef75f5560..0000000000 --- a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_misc.js +++ /dev/null @@ -1,122 +0,0 @@ -////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// -// -// openHarmony Library v0.01 -// -// -// Developed by Mathieu Chaptel, Chris Fourney... -// -// -// This library is an open source implementation of a Document Object Model -// for Toonboom Harmony. It also implements patterns similar to JQuery -// for traversing this DOM. -// -// Its intended purpose is to simplify and streamline toonboom scripting to -// empower users and be easy on newcomers, with default parameters values, -// and by hiding the heavy lifting required by the official API. -// -// This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is guaranteed to work. Feel free to contribute -// improvements to its official github. If you do make sure you follow the provided -// template and naming conventions and document your new methods properly. -// -// This library doesn't overwrite any of the objects and classes of the official -// Toonboom API which must remains available. -// -// This library is made available under the MIT license. -// https://opensource.org/licenses/mit -// -// The repository for this library is available at the address: -// https://github.com/cfourney/OpenHarmony/ -// -// -// For any requests feel free to contact m.chaptel@gmail.com -// -// -// -// -////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// - - -//TODO : view.currentToolManager integration. - - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oUtils class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * The $.oUtils helper class -- providing generic utilities. Doesn't need instantiation. - * @classdesc $.oUtils utility Class - */ -$.oUtils = function(){ - this._type = "utils"; -} - -/** - * Finds the longest common substring between two strings. - * @param {string} str1 - * @param {string} str2 - * @returns {string} the found string - */ -$.oUtils.longestCommonSubstring = function( str1, str2 ){ - if (!str1 || !str2) - return { - length: 0, - sequence: "", - offset: 0 - }; - - var sequence = "", - str1Length = str1.length, - str2Length = str2.length, - num = new Array(str1Length), - maxlen = 0, - lastSubsBegin = 0; - - for (var i = 0; i < str1Length; i++) { - var subArray = new Array(str2Length); - for (var j = 0; j < str2Length; j++) - subArray[j] = 0; - num[i] = subArray; - } - var subsBegin = null; - for (var i = 0; i < str1Length; i++){ - for (var j = 0; j < str2Length; j++){ - if (str1[i] !== str2[j]){ - num[i][j] = 0; - }else{ - if ((i === 0) || (j === 0)){ - num[i][j] = 1; - }else{ - num[i][j] = 1 + num[i - 1][j - 1]; - } - if (num[i][j] > maxlen){ - maxlen = num[i][j]; - subsBegin = i - num[i][j] + 1; - if (lastSubsBegin === subsBegin){//if the current LCS is the same as the last time this block ran - sequence += str1[i]; - }else{ - //this block resets the string builder if a different LCS is found - lastSubsBegin = subsBegin; - sequence= ""; //clear it - sequence += str1.substr(lastSubsBegin, (i + 1) - lastSubsBegin); - } - } - } - } - } - return { - length: maxlen, - sequence: sequence, - offset: subsBegin - }; -} diff --git a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_network.js b/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_network.js deleted file mode 100644 index 2a6aa3519a..0000000000 --- a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_network.js +++ /dev/null @@ -1,424 +0,0 @@ -////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// -// -// openHarmony Library v0.01 -// -// -// Developed by Mathieu Chaptel, Chris Fourney... -// -// -// This library is an open source implementation of a Document Object Model -// for Toonboom Harmony. It also implements patterns similar to JQuery -// for traversing this DOM. -// -// Its intended purpose is to simplify and streamline toonboom scripting to -// empower users and be easy on newcomers, with default parameters values, -// and by hiding the heavy lifting required by the official API. -// -// This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is guaranteed to work. Feel free to contribute -// improvements to its official github. If you do make sure you follow the provided -// template and naming conventions and document your new methods properly. -// -// This library doesn't overwrite any of the objects and classes of the official -// Toonboom API which must remains available. -// -// This library is made available under the MIT license. -// https://opensource.org/licenses/mit -// -// The repository for this library is available at the address: -// https://github.com/cfourney/OpenHarmony/ -// -// -// For any requests feel free to contact m.chaptel@gmail.com -// -// -// -// -////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oNetwork methods // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * Network helper for HTTP methods.
Available under $.network - * @constructor - * @classdesc Network Helper Class - * @param {dom} $ The connection back to the DOM. - * - */ -$.oNetwork = function( ){ - //Expect a path for CURL. - var avail_paths = [ - "c:\\Windows\\System32\\curl.exe" - ]; - if( !about.isWindowsArch() ){ - avail_paths = [ - "/usr/bin/curl", - "/usr/local/bin/curl" - ]; - } - - var curl_path = false; - for( var n=0;nNote, Harmony has issues with HTTPS, useCurl=true prevents this - * @param {string} address The address for the web query. - * @param {function} callback_func Providing a callback function prevents blocking, and will respond on this function. The callback function is in form func( results ){} - * @param {bool} use_json In the event of a JSON api, this will return an object converted from the returned JSON. - * - * @return: {string/object} The resulting object/string from the query -- otherwise a bool as false when an error occurred.. - */ -$.oNetwork.prototype.webQuery = function ( address, callback_func, use_json ){ - if (typeof callback_func === 'undefined') var callback_func = false; - if (typeof use_json === 'undefined') var use_json = false; - - if( this.useCurl && this.curlPath ){ - try{ - var cmdline = [ "-L", address ]; - var p = new QProcess(); - if( !callback_func ){ - p.start( this.curlPath, cmdline ); - p.waitForFinished( 10000 ); - - try{ - var readOut = ( new QTextStream( p.readAllStandardOutput() ) ).readAll(); - if( use_json ){ - readOut = JSON.parse( readOut ); - } - return readOut; - - }catch(err){ - this.$.debug( err + " ("+err.lineNumber+")", this.$.DEBUG_LEVEL["ERROR"] ); - return false; - } - }else{ - p.start( this.curlPath, cmdline ); - - var callback = function( status ){ - var readOut = ( new QTextStream( p.readAllStandardOutput() ) ).readAll(); - if( use_json ){ - readOut = JSON.parse( readOut ); - } - - callback_func( readOut ); - } - p["finished(int)"].connect( this, callback ); - - return true; - } - }catch( err ){ - this.$.debug( err + " ("+err.lineNumber+")", this.$.DEBUG_LEVEL["ERROR"] ); - return false; - } - }else{ - - System.println( callback ); - - var data = new QByteArray( "" ); - var qurl = new QUrl( address ); - var request = new QNetworkRequest( qurl ); - var header = new QByteArray("text/xml;charset=ISO-8859-1"); - var accessManager = new QNetworkAccessManager(); - - request.setHeader( QNetworkRequest.ContentTypeHeader, header ); - request.setHeader( QNetworkRequest.ServerHeader, "application/json" ); - request.setHeader( QNetworkRequest.ContentLengthHeader, data.size() ); - request.setAttribute( QNetworkRequest.CacheLoadControlAttribute, QNetworkRequest.AlwaysNetwork ); - request.setAttribute( QNetworkRequest.FollowRedirectsAttribute, true ); - - if( callback_func ){ - replyRecd = function( reply ){ - try{ - var statusCode = reply.attribute( QNetworkRequest.HttpStatusCodeAttribute ); - var reasonCode = reply.attribute( QNetworkRequest.HttpReasonPhraseAttribute ); - - if( !statusCode ){ - callback_func( false ); - return; - } - - if( statusCode == 301 ){ - callback_func( false ); - return; - } - - var stream = new QTextStream( reply ); - var result = stream.readAll(); - - if( use_json ){ - try{ - result = JSON.parse( result ); - }catch(err){ - this.$.debug( err + " ("+err.lineNumber+")", this.$.DEBUG_LEVEL["ERROR"] ); - callback_func( false ); - } - } - - callback_func( result ); - }catch(err){ - this.$.debug( err + " ("+err.lineNumber+")", this.$.DEBUG_LEVEL["ERROR"] ); - callback_func( false ); - } - } - - error = function( error ){ - switch( ""+error ){ - case "1": - // MessageBox.information( "Connection Refused" ); - break; - - case "2": - // MessageBox.information( "Remote Host Closed" ); - break; - - case "3": - // MessageBox.information( "Host Not Found" ); - break; - - case "4": - // MessageBox.information( "Timeout Error" ); - break; - - case "5": - // MessageBox.information( "Operation Cancelled" ); - break; - - case "6": - // MessageBox.information( "SSL Handshake Failed" ); - break; - } - - callback( false ); - } - - - accessManager["finished(QNetworkReply*)"].connect( this, replyRecd ); - var send_reply = accessManager.get( request ); - send_reply["error(QNetworkReply::NetworkError)"].connect( this, error ); - - return true; - }else{ - System.println( "STARTING" ); - var wait = new QEventLoop(); - var timeout = new QTimer(); - - timeout["timeout"].connect( this, wait["quit"] ); - accessManager["finished(QNetworkReply*)"].connect( this, wait["quit"] ); - - var send_reply = accessManager.get( request ); - timeout.start( 10000 ); - wait.exec(); - timeout.stop(); - - try{ - var statusCode = send_reply.attribute( QNetworkRequest.HttpStatusCodeAttribute ); - var reasonCode = send_reply.attribute( QNetworkRequest.HttpReasonPhraseAttribute ); - - if( !statusCode ){ - return false; - } - - if( statusCode == 301 ){ - return false; - } - - var stream = new QTextStream( send_reply ); - var result = stream.readAll(); - - if( use_json ){ - try{ - result = JSON.parse( result ); - }catch(err){ - this.$.debug( err + " ("+err.lineNumber+")", this.$.DEBUG_LEVEL["ERROR"] ); - } - } - - return( result ); - }catch(err){ - System.println( err ); - this.$.debug( err + " ("+err.lineNumber+")", this.$.DEBUG_LEVEL["ERROR"] ); - } - - return( false ); - } - } -} - - -/** - * Downloads a file from the internet at the given address
Note, only implemented with useCurl=true. - * @param {string} address The address for the file to be downloaded. - * @param {function} path The local file path to save the download. - * @param {bool} replace Replace the file if it exists. - * - * @return: {string/object} The resulting object/string from the query -- otherwise a bool as false when an error occurred.. - */ -$.oNetwork.prototype.downloadSingle = function ( address, path, replace ){ - if (typeof replace === 'undefined') var replace = false; - - try{ - if( this.useCurl && this.curlPath ){ - var file = new this.$.oFile( path ); - if( file.exists ){ - if( replace ){ - file.remove(); - }else{ - this.$.debug( "File already exists- unable to replace: " + path, this.$.DEBUG_LEVEL["ERROR"] ); - return false; - } - } - - var cmdline = [ "-L", "-o", path, address ]; - - var p = new QProcess(); - p.start( this.curlPath, cmdline ); - p.waitForFinished( 10000 ); - - var file = new this.$.oFile( path ); - return file.exists; - - }else{ - this.$.debug( "Downloads without curl are not implemented.", this.$.DEBUG_LEVEL["ERROR"] ); - return false; - } - }catch( err ){ - this.$.debug( err + " ("+err.lineNumber+")", this.$.DEBUG_LEVEL["ERROR"] ); - return false; - } -} - - -/** - * Threads multiple downloads at a time [10 concurrent]. Downloads a from the internet at the given addresses
Note, only implemented with useCurl=true. - * @param {object[]} instructions The instructions for download, in format [ { "path": localPathOnDisk, "url":"DownloadPath" } ] - * @param {bool} replace Replace the file if it exists. - * - * @return: {bool[]} The results of the download, for each file in the instruction bool[] - */ -$.oNetwork.prototype.downloadMulti = function ( address_path, replace ){ - if (typeof replace === 'undefined') var replace = false; - - var progress = new QProgressDialog(); - progress.setLabelText( "Downloading files..." ); - progress.show(); - progress.setRange( 0, address_path.length ); - - var complete_process = function( val ){ - } - - var dload_cnt = 0; - try{ - if( this.useCurl && this.curlPath ){ - var in_proc = []; - var skipped = []; - for( var x=0;x= 10 ){ //Allow 10 concurrent processes. - var procs = []; - for( var n=0;n 0 ){ - procs.push( in_proc[n] ); - }else{ - dload_cnt++; - progress.setValue( dload_cnt ); - } - } - in_proc = procs; - } - - var file = new this.$.oFile( path ); - if( file.exists ){ - if( replace ){ - file.remove(); - }else{ - this.$.debug( "File already exists- unable to replace: " + path, this.$.DEBUG_LEVEL["ERROR"] ); - skipped[x] == true; - continue; - } - } - - var cmdline = [ "-L", "-o", path, url ]; - var p = new QProcess(); - p["finished(int)"].connect( this, complete_process ); - p.start( this.curlPath, cmdline ); - in_proc.push( p ); - - progress.setLabelText( "Downloading file: "+path ); - - QCoreApplication.processEvents(); - }catch(err){ - this.$.debug( err + " : " + err.lineNumber + " : " + err.fileName, this.$.DEBUG_LEVEL["ERROR"] ); - } - } - - while( in_proc.length > 0 ){ //Allow 5 concurrent processes. - var procs = []; - for( var n=0;n 0 ){ - procs.push( in_proc[n] ); - }else{ - dload_cnt++; - progress.setValue( dload_cnt ); - } - - progress.setLabelText( "Downloading "+in_proc.length+" File(s)" ); - } - - in_proc = procs; - } - - progress.accept(); - - var file_results = []; - for( var x=0;x - * It holds the value of its position in the node view, and functions to link to other nodes, as well as set the attributes of the node.

- * It uses a cache system, so a node for a given path will only be created once.
- * If the nodes change path through other means than the openHarmony functions during the execution of the script, use oNode.invalidateCache() to create new nodes again.

- * This constructor should not be invoqued by users, who should use $.scene.getNodeByPath() or $.scene.root.getNodeByName() instead. - * @constructor - * @param {string} path Path to the node in the network. - * @param {$.oScene} [oSceneObject] Access to the oScene object of the DOM. - * @see NodeType - * @example - * // To grab a node object from the scene, it's possible to create a new node object by calling the constructor: - * var myNode = new $.oNode("Top/Drawing", $.scn) - * - * // However, most nodes will be grabbed directly from the scene object. - * var doc = $.scn - * var nodes = doc.nodes; // grabs the list of all the nodes in the scene - * - * // It's possible to grab a single node from the path in the scene - * var myNode = doc.getNodeByPath("Top/Drawing") - * var myNode = doc.$node("Top/Drawing") // short synthax but same function - * - * // depending on the type of node, oNode objects returned by these functions can actually be an instance the subclasses - * // oDrawingNode, oGroupNode, oPegNode... - * - * $.log(myNode instanceof $.oNode) // true - * $.log(myNode instanceof $.oDrawingNode) // true - * - * // These other subclasses of nodes have other methods that are only shared by nodes of a certain type. - * - * // Not documented in this class, oNode objects have attributes which correspond to the values visible in the Layer Properties window. - * // The attributes values can be accessed and set by using the dot notation on the oNode object: - * - * myNode.can_animate = false; - * myNode.position.separate = true; - * myNode.position.x = 10; - * - * // To access the oAttribute objects in the node, call the oNode.attributes object that contains them - * - * var attributes = myNode.attributes; - */ -$.oNode = function( path, oSceneObject ){ - var instance = this.$.getInstanceFromCache.call(this, path); - if (instance) return instance; - - this._path = path; - this.type = node.type(this.path); - this.scene = (typeof oSceneObject === 'undefined')?this.$.scene:oSceneObject; - - this._type = 'node'; - - this.refreshAttributes(); -} - -/** - * Initialize the attribute cache. - * @private - */ -$.oNode.prototype.attributesBuildCache = function (){ - //Cache time can be used at later times, to check for auto-rebuild of caches. Not yet implemented. - this._cacheTime = (new Date()).getTime(); - - var _attributesList = node.getAttrList( this.path, 1 ); - var _attributes = {}; - - for (var i in _attributesList){ - - var _attribute = new this.$.oAttribute(this, _attributesList[i]); - var _keyword = _attribute.keyword; - - _attributes[_keyword] = _attribute; - } - - this._attributes_cached = _attributes; -} - - -/** - * Private function to create attributes setters and getters as properties of the node - * @private - */ -$.oNode.prototype.setAttrGetterSetter = function (attr, context){ - if (typeof context === 'undefined') context = this; - // this.$.debug("Setting getter setters for attribute: "+attr.keyword+" of node: "+this.name, this.$.DEBUG_LEVEL.DEBUG) - - var _keyword = attr.shortKeyword; - - Object.defineProperty( context, _keyword, { - enumerable : true, - configurable : true, - get : function(){ - // MessageLog.trace("getting attribute "+attr.keyword+". animated: "+(attr.column != null)) - var _subAttrs = attr.subAttributes; - if (_subAttrs.length == 0){ - // if attribute has animation, return the frames - if (attr.column != null) return attr.frames; - // otherwise return the value - var _value = attr.getValue(); - }else{ - // if there are subattributes, create getter setters for each on the returned object - // this means every result of attr.getValue must be an object. - // For attributes that have a string return value, attr.getValue() actually returns a fake string object - // which is an object with a value property and a toString() method returning the value. - var _value = (attr.column != null)?new this.$.oList(attr.frames, 1):attr.getValue(); - for (var i in _subAttrs){ - this.setAttrGetterSetter( _subAttrs[i], _value ); - } - } - return _value; - }, - - set : function(newValue){ - // this.$.debug("setting attribute through getter setter "+attr.keyword+" to value: "+newValue, this.$.DEBUG_LEVEL.DEBUG) - // if attribute has animation, passed value must be a frame object - var _subAttrs = attr.subAttributes; - - // setting the attribute directly if no subattributes are present, or if value is a color (exception) - if (_subAttrs.length == 0 || attr.type == "COLOR"){ - if (attr.column != null) { - if (!newValue.hasOwnProperty("frameNumber")) { - // fallback to set frame 1 - newValue = {value:newValue, frameNumber:1}; - } - attr.setValue(newValue.value, newValue.frameNumber) - }else{ - return attr.setValue(newValue) - } - }else{ - var _frame = undefined; - var _value = newValue; - // dealing with value being an object with frameNumber for animated values - if (attr.column != null) { - if (!(newValue instanceof oFrame)) { - // fallback to set frame 1 - newValue = {value:newValue, frameNumber:1}; - } - - _frame = newValue.frameNumber; - _value = newValue.value; - } - - // setting non animated attribute value - for (var i in _subAttrs){ - // set each subAttr individually based on corresponding values in the provided object - var _keyword = _subAttrs[i].shortKeyword; - if (_value.hasOwnProperty(_keyword)) _subAttrs[i].setValue(_value[_keyword], _frame); - } - } - } - }); -}; - - -/** - * The derived path to the node. - * @deprecated use oNode.path instead - * @name $.oNode#fullPath - * @readonly - * @type {string} - */ -Object.defineProperty($.oNode.prototype, 'fullPath', { - get : function( ){ - return this._path; - } -}); - - -/** - * The path of the node (includes all groups from 'Top' separated by forward slashes). - * To change the path of a node, use oNode.moveToGroup() - * @name $.oNode#path - * @type {string} - * @readonly - */ -Object.defineProperty($.oNode.prototype, 'path', { - get : function( ){ - return this._path; - } -}); - - -/** - * The type of the node. - * @name $.oNode#type - * @readonly - * @type {string} - */ -Object.defineProperty( $.oNode.prototype, 'type', { - get : function( ){ - return node.type( this.path ); - } -}); - - -/** - * Is the node a group? - * @name $.oNode#isGroup - * @readonly - * @deprecated check if the node is an instance of oGroupNode instead - * @type {bool} - */ -Object.defineProperty($.oNode.prototype, 'isGroup', { - get : function( ){ - if( this.root ){ - //in a sense, its a group. - return true; - } - - return node.isGroup( this.path ); - } -}); - - -/** - * The $.oNode objects contained in this group. This is deprecated and was moved to oGroupNode - * @DEPRECATED Use oGroupNode.children instead. - * @name $.oNode#children - * @readonly - * @type {$.oNode[]} - */ -Object.defineProperty($.oNode.prototype, 'children', { - get : function( ){ - if( !this.isGroup ){ return []; } - - var _children = []; - var _subnodes = node.subNodes( this.path ); - for( var n=0; n<_subnodes.length; n++ ){ - _children.push( this.scene.getNodeByPath( _subnodes[n] ) ); - } - - return _children; - }, - - set : function( arr_children ){ - //Consider a way to have this group adopt the children, move content here? - //this may be a bit tough to extend. - } -}); - - -/** - * Does the node exist? - * @name $.oNode#exists - * @type {bool} - * @readonly - */ -Object.defineProperty($.oNode.prototype, 'exists', { - get : function(){ - if( this.type ){ - return true; - }else{ - return false; - } - } -}); - - -/** - * Is the node selected? - * @name $.oNode#selected - * @type {bool} - */ -Object.defineProperty($.oNode.prototype, 'selected', { - get : function(){ - for( var n=0;n 0 ){ - for (var j = 0; j < node.numberOfOutputLinks(this.path, i); j++){ - lookup_list.push( [i,j] ); - } - }else{ - lookup_list.push( [i,0] ); - } - } - - var newList = new this.$.oList( [], 0, lookup_list.length, - function( listItem, index ){ return new this.$.oNodeLink( nodeRef, lookup_list[index][0], false, false, lookup_list[index][1] ); }, - function(){ throw new ReferenceError("Unable to set inLinks"); }, - false - ); - return newList; - } -}); - - -/** - * The list of nodes connected to the inport of this node, as a flat list, in order of inport. - * @name $.oNode#linkedOutNodes - * @readonly - * @type {$.oNode[]} - */ -Object.defineProperty($.oNode.prototype, 'linkedOutNodes', { - get: function(){ - var _outNodes = this.getOutLinks().map(function(x){return x.inNode}); - return _outNodes; - } -}) - - -/** - * The list of nodes connected to the inport of this node, as a flat list, in order of inport. - * @name $.oNode#linkedInNodes - * @readonly - * @type {$.oNode[]} - */ -Object.defineProperty($.oNode.prototype, 'linkedInNodes', { - get: function(){ - var _inNodes = this.getInLinks().map(function(x){return x.outNode}); - return _inNodes - } -}) - - -/** - * The list of nodes connected to the inport of this node, in order of inport. Similar to oNode.inNodes - * @name $.oNode#ins - * @readonly - * @type {$.oNode[]} - * @deprecated alias for deprecated oNode.inNodes property -*/ -Object.defineProperty($.oNode.prototype, 'ins', { - get : function(){ - return this.inNodes; - } -}); - - -/** - * The list of nodes connected to the outport of this node, in order of outport and links. Similar to oNode.outNodes - * @name $.oNode#outs - * @readonly - * @type {$.oNode[][]} - * @deprecated alias for deprecated oNode.outNodes property -*/ -Object.defineProperty($.oNode.prototype, 'outs', { - get : function(){ - return this.outNodes; - } -}); - - -/** - * An object containing all attributes of this node. - * @name $.oNode#attributes - * @readonly - * @type {oAttribute} - * @example - * // You can get access to the actual oAttribute object for a node parameter by using the dot notation: - * - * var myNode = $.scn.$node("Top/Drawing") - * var drawingAttribute = myNode.attributes.drawing.element - * - * // from there, it's possible to set/get the value of the attribute, get the column, the attribute keyword etc. - * - * drawingAttribute.setValue ("1", 5); // creating an exposure of drawing 1 at frame 5 - * var drawingColumn = drawingAttribute.column; // grabbing the column linked to the attribute that holds all the animation - * $.log(drawingAttribute.keyword); // "DRAWING.ELEMENT" - * - * // for a more direct way to access an attribute, it's possible to also call: - * - * var drawingAttribute = myNode.getAttributeByName("DRAWING.ELEMENT"); -*/ -Object.defineProperty($.oNode.prototype, 'attributes', { - get : function(){ - return this._attributes_cached; - } -}); - - -/** - * The bounds of the node rectangle in the node view. - * @name $.oNode#bounds - * @readonly - * @type {oBox} -*/ -Object.defineProperty( $.oNode.prototype, 'bounds', { - get : function(){ - return new this.$.oBox(this.x, this.y, this.x+this.width, this.y+this.height); - } -}); - - -/** - * The transformation matrix of the node at the currentFrame. - * @name $.oNode#matrix - * @readonly - * @type {oMatrix} -*/ -Object.defineProperty( $.oNode.prototype, 'matrix', { - get : function(){ - return this.getMatrixAtFrame(this.scene.currentFrame); - } -}); - - -/** - * The list of all columns linked across all the attributes of this node. - * @name $.oNode#linkedColumns - * @readonly - * @type {oColumn[]} -*/ -Object.defineProperty($.oNode.prototype, 'linkedColumns', { - get : function(){ - var _attributes = this.attributes; - var _columns = []; - - for (var i in _attributes){ - _columns = _columns.concat(_attributes[i].getLinkedColumns()); - } - return _columns; - } -}) - - - -/** - * Whether the node can create new in-ports. - * @name $.oNode#canCreateInPorts - * @readonly - * @type {bool} -*/ -Object.defineProperty($.oNode.prototype, 'canCreateInPorts', { - get : function(){ - return ["COMPOSITE", - "GROUP", - "MultiLayerWrite", - "TransformGate", - "TransformationSwitch", - "DeformationCompositeModule", - "MATTE_COMPOSITE", - "COMPOSITE_GENERIC", - "ParticleBkerComposite", - "ParticleSystemComposite", - "ParticleRegionComposite", - "PointConstraintMulti", - "MULTIPORT_OUT"] - .indexOf(this.type) != -1; - } -}) - - -/** - * Whether the node can create new out-ports. - * @name $.oNode#canCreateOutPorts - * @readonly - * @type {bool} -*/ -Object.defineProperty($.oNode.prototype, 'canCreateOutPorts', { - get : function(){ - return ["GROUP", - "MULTIPORT_IN"] - .indexOf(this.type) != -1; - } -}) - - -/** - * Returns the number of links connected to an in-port - * @param {int} inPort the number of the port to get links from. - */ -$.oNode.prototype.getInLinksNumber = function(inPort){ - if (this.inPorts < inPort) return null; - return node.isLinked(this.path, inPort)?1:0; -} - - -/** - * Returns the oLink object representing the connection of a specific inPort - * @param {int} inPort the number of the port to get links from. - * @return {$.oLink} the oLink Object representing the link connected to the inport - */ -$.oNode.prototype.getInLink = function(inPort){ - if (this.inPorts < inPort) return null; - var _info = node.srcNodeInfo(this.path, inPort); - // this.$.log(this.path+" "+inPort+" "+JSON.stringify(_info)) - - if (!_info) return null; - - var _inNode = this.scene.getNodeByPath(_info.node); - var _inLink = new this.$.oLink(_inNode, this, _info.port, inPort, _info.link, true); - - // this.$.log("inLink: "+_inLink) - return _inLink; -} - - -/** - * Returns all the valid oLink objects describing the links that are connected into this node. - * @return {$.oLink[]} An array of $.oLink objects. - */ -$.oNode.prototype.getInLinks = function(){ - var _inPorts = this.inPorts; - var _inLinks = []; - - for (var i = 0; i<_inPorts; i++){ - var _link = this.getInLink(i); - if (_link != null) _inLinks.push(_link); - } - - return _inLinks; -} - - -/** - * Returns a free unconnected in-port - * @param {bool} [createNew=true] Whether to allow creation of new ports - * @return {int} the port number that isn't connected - */ -$.oNode.prototype.getFreeInPort = function(createNew){ - if (typeof createNew === 'undefined') var createNew = true; - - var _inPorts = this.inPorts; - - for (var i=0; i<_inPorts; i++){ - if (this.getInLinksNumber(i) == 0) return i; - } - if (_inPorts == 0 && this.canCreateInPorts) return 0; - if (createNew && this.canCreateInPorts) return _inPorts; - this.$.debug("can't get free inPort for node "+this.path, this.$.DEBUG_LEVEL.ERROR); - return null -} - - -/** - * Links this node's inport to the given module, at the inport and outport indices. - * @param {$.oNode} nodeToLink The node to link this one's inport to. - * @param {int} [ownPort] This node's inport to connect. - * @param {int} [destPort] The target node's outport to connect. - * @param {bool} [createPorts] Whether to create new ports on the nodes. - * - * @return {bool} The result of the link, if successful. - */ -$.oNode.prototype.linkInNode = function( nodeToLink, ownPort, destPort, createPorts){ - if (!(nodeToLink instanceof this.$.oNode)) throw new Error("Incorrect type for argument 'nodeToLink'. Must provide an $.oNode.") - - var _link = (new this.$.oLink(nodeToLink, this, destPort, ownPort)).getValidLink(createPorts, createPorts); - if (_link == null) return; - this.$.debug("linking "+_link, this.$.DEBUG_LEVEL.LOG); - - return _link.connect(); -}; - - -/** - * Searches for and unlinks the $.oNode object from this node's inNodes. - * @param {$.oNode} oNodeObject The node to link this one's inport to. - * @return {bool} The result of the unlink. - */ -$.oNode.prototype.unlinkInNode = function( oNodeObject ){ - - var _node = oNodeObject.path; - - var _links = this.getInLinks(); - - for (var i in _links){ - if (_links[i].outNode.path == _node) return _links[i].disconnect(); - } - - throw new Error (oNodeObject.name + " is not linked to node " + this.name + ", can't unlink."); -}; - - -/** - * Unlinks a specific port from this node's inport. - * @param {int} inPort The inport to disconnect. - * - * @return {bool} The result of the unlink, if successful. - */ -$.oNode.prototype.unlinkInPort = function( inPort ){ - // Default values for optional parameters - if (typeof inPort === 'undefined') inPort = 0; - - return node.unlink( this.path, inPort ); -}; - - -/** - * Returns the node connected to a specific in-port - * @param {int} inPort the number of the port to get the linked Node from. - * @return {$.oNode} The node connected to this in-port - */ -$.oNode.prototype.getLinkedInNode = function(inPort){ - if (this.inPorts < inPort) return null; - return this.scene.getNodeByPath(node.srcNode(this.path, inPort)); -} - - -/** - * Returns the number of links connected to an outPort - * @param {int} outPort the number of the port to get links from. - * @return {int} the number of links - */ -$.oNode.prototype.getOutLinksNumber = function(outPort){ - if (this.outPorts < outPort) return null; - return node.numberOfOutputLinks(this.path, outPort); -} - - -/** - * Returns the $.oLink object representing the connection of a specific outPort / link - * @param {int} outPort the number of the port to get the link from. - * @param {int} [outLink] the index of the link. - * @return {$.oLink} The link object describing the connection - */ -$.oNode.prototype.getOutLink = function(outPort, outLink){ - if (typeof outLink === 'undefined') var outLink = 0; - - if (this.outPorts < outPort) return null; - if (this.getOutLinksNumber(outPort) < outLink) return null; - - var _info = node.dstNodeInfo(this.path, outPort, outLink); - if (!_info) return null; - - var _outNode = this.scene.getNodeByPath(_info.node); - var _outLink = new this.$.oLink(this, _outNode, outPort, _info.port, outLink, true); - - return _outLink; -} - - -/** - * Returns all the valid oLink objects describing the links that are coming out of this node. - * @return {$.oLink[]} An array of $.oLink objects. - */ -$.oNode.prototype.getOutLinks = function(){ - var _outPorts = this.outPorts; - var _links = []; - - for (var i = 0; i<_outPorts; i++){ - var _outLinks = this.getOutLinksNumber(i); - for (var j = 0; j<_outLinks; j++){ - var _link = this.getOutLink(i, j); - if (_link != null) _links.push(_link); - } - } - - return _links; -} - - -/** - * Returns a free unconnected out-port - * @param {bool} [createNew=true] Whether to allow creation of new ports - * @return {int} the port number that isn't connected - */ -$.oNode.prototype.getFreeOutPort = function(createNew){ - if (typeof createNew === 'undefined') var createNew = false; - - var _outPorts = this.outPorts; - for (var i=0; i<_outPorts; i++){ - if (this.getOutLinksNumber(i) == 0) return i; - } - - if (_outPorts == 0 && this.canCreateOutPorts) return 0; - - if (createNew && this.canCreateOutPorts) return _outPorts; - - return _outPorts-1; // if no empty outPort can be found, return the last one -} - - -/** - * Links this node's out-port to the given module, at the inport and outport indices. - * @param {$.oNode} nodeToLink The node to link this one's outport to. - * @param {int} [ownPort] This node's outport to connect. - * @param {int} [destPort] The target node's inport to connect. - * @param {bool} [createPorts] Whether to create new ports on the nodes. - * - * @return {bool} The result of the link, if successful. - */ -$.oNode.prototype.linkOutNode = function(nodeToLink, ownPort, destPort, createPorts){ - if (!(nodeToLink instanceof this.$.oNode)) throw new Error("Incorrect type for argument 'nodeToLink'. Must provide an $.oNode.") - - var _link = (new this.$.oLink(this, nodeToLink, ownPort, destPort)).getValidLink(createPorts, createPorts) - if (_link == null) return; - this.$.debug("linking "+_link, this.$.DEBUG_LEVEL.LOG); - - return _link.connect(); -} - - -/** - * Links this node's out-port to the given module, at the inport and outport indices. - * @param {$.oNode} oNodeObject The node to unlink from this node's outports. - * - * @return {bool} The result of the link, if successful. - */ -$.oNode.prototype.unlinkOutNode = function( oNodeObject ){ - var _node = oNodeObject.path; - - var _links = this.getOutLinks(); - - for (var i in _links){ - if (_links[i].inNode.path == _node) return _links[i].disconnect(); - } - - throw new Error (oNodeObject.name + " is not linked to node " + this.name + ", can't unlink."); -}; - - -/** - * Returns the node connected to a specific outPort - * @param {int} outPort the number of the port to get the node from. - * @param {int} [outLink=0] the index of the link. - * @return {$.oNode} The node connected to this outPort and outLink - */ -$.oNode.prototype.getLinkedOutNode = function(outPort, outLink){ - if (typeof outLink == 'undefined') var outLink = 0; - if (this.outPorts < outPort || this.getOutLinksNumber(outPort) < outLink) return null; - return this.scene.getNodeByPath(node.dstNode(this.path, outPort, outLink)); -} - - -/** - * Unlinks a specific port/link from this node's output. - * @param {int} outPort The outPort to disconnect. - * @param {int} outLink The outLink to disconnect. - * - * @return {bool} The result of the unlink, if successful. - */ -$.oNode.prototype.unlinkOutPort = function( outPort, outLink ){ - // Default values for optional parameters - if (typeof outLink === 'undefined') outLink = 0; - - try{ - var dstNodeInfo = node.dstNodeInfo(this.path, outPort, outLink); - if (dstNodeInfo) node.unlink(dstNodeInfo.node, dstNodeInfo.port); - return true; - }catch(err){ - this.$.debug("couldn't unlink port "+outPort+" of node "+this.path, this.$.DEBUG_LEVEL.ERROR) - return false; - } -}; - - -/** - * Inserts the $.oNodeObject provided as an innode to this node, placing it between any existing nodes if the link already exists. - * @param {int} inPort This node's inport to connect. - * @param {$.oNode} oNodeObject The node to link this one's outport to. - * @param {int} inPortTarget The target node's inPort to connect. - * @param {int} outPortTarget The target node's outPort to connect. - * - * @return {bool} The result of the link, if successful. - */ -$.oNode.prototype.insertInNode = function( inPort, oNodeObject, inPortTarget, outPortTarget ){ - var _node = oNodeObject.path; - - //QScriptValue - if( this.ins[inPort] ){ - //INSERT BETWEEN. - var node_linkinfo = node.srcNodeInfo( this.path, inPort ); - node.link( node_linkinfo.node, node_linkinfo.port, _node, inPortTarget, true, true ); - node.unlink( this.path, inPort ); - return node.link( oNodeObject.path, outPortTarget, this.path, inPort, true, true ); - } - - return this.linkInNode( oNodeObject, inPort, outPortTarget ); -}; - - -/** - * Moves the node into the specified group. This doesn't create any composite or links to the multiport nodes. The node will be unlinked. - * @param {oGroupNode} group the group node to move the node into. - */ -$.oNode.prototype.moveToGroup = function(group){ - var _name = this.name; - if (group instanceof oGroupNode) group = group.path; - - if (this.group != group){ - this.$.beginUndo("oH_moveNodeToGroup_"+_name) - - var _groupNodes = node.subNodes(group); - - node.moveToGroup(this.path, group); - this._path = group+"/"+_name; - - // detect creation of a composite and remove it - var _newNodes = node.subNodes(group) - if (_newNodes.length > _groupNodes.length+1){ - for (var i in _newNodes){ - if (_groupNodes.indexOf(_newNodes[i]) == -1 && _newNodes[i] != this.path) { - var _comp = this.scene.getNodeByPath(_newNodes[i]); - if (_comp && _comp.type == "COMPOSITE") _comp.remove(); - break; - } - } - } - - // remove automated links - var _inPorts = this.inPorts; - for (var i=0; i<_inPorts; i++){ - this.unlinkInPort(i); - } - - var _outPorts = this.outPorts; - for (var i=0; i<_outPorts; i++){ - var _outLinks = this.getOutLinksNumber(i); - for (var j=_outLinks-1; j>=0; j--){ - this.unlinkOutPort(i, j); - } - } - - this.refreshAttributes(); - - this.$.endUndo(); - } -} - - -/** - * Get the transformation matrix for the node at the given frame - * @param {int} frameNumber - * @returns {oMatrix} the matrix object - */ -$.oNode.prototype.getMatrixAtFrame = function (frameNumber){ - return new this.$.oMatrix(node.getMatrix(this.path, frameNumber)); -} - - -/** - * Retrieves the node layer in the timeline provided. - * @param {oTimeline} [timeline] Optional: the timeline object to search the column Layer. (by default, grabs the current timeline) - * - * @return {int} The index within that timeline. - */ - $.oNode.prototype.getTimelineLayer = function(timeline){ - if (typeof timeline === 'undefined') var timeline = this.$.scene.currentTimeline; - - var _nodeLayers = timeline.layers.map(function(x){return x.node.path}); - if (_nodeLayers.indexOf(this.path)0){ - return timeline.layers[_nodeLayers.indexOf(this.path)]; - } - return null -} - - -/** - * Retrieves the node index in the timeline provided. - * @param {oTimeline} [timeline] Optional: the timeline object to search the column Layer. (by default, grabs the current timeline) - * - * @return {int} The index within that timeline. - */ -$.oNode.prototype.timelineIndex = function(timeline){ - if (typeof timeline === 'undefined') var timeline = this.$.scene.currentTimeline; - - var _nodes = timeline.compositionLayersList; - return _nodes.indexOf(this.path); -} - - -/** - * obtains the nodes contained in the group, allows recursive search. This method is deprecated and was moved to oGroupNode - * @DEPRECATED - * @param {bool} recurse Whether to recurse internally for nodes within children groups. - * - * @return {$.oNode[]} The subbnodes contained in the group. - */ -$.oNode.prototype.subNodes = function(recurse){ - if (typeof recurse === 'undefined') recurse = false; - var _nodes = node.subNodes(this.path); - var _subNodes = []; - for (var _node in _nodes){ - var _oNodeObject = new this.$.oNode( _nodes[_node] ); - _subNodes.push(_oNodeObject); - if (recurse && node.isGroup(_nodes[_node])) _subNodes = _subNodes.concat(_$.oNodeObject.subNodes(recurse)); - } - - return _subNodes; -}; - - - /** - * Place a node above one or more nodes with an offset. - * @param {$.oNode[]} oNodeArray The array of nodes to center this above. - * @param {float} xOffset The horizontal offset to apply after centering. - * @param {float} yOffset The vertical offset to apply after centering. - * - * @return {oPoint} The resulting position of the node. - */ -$.oNode.prototype.centerAbove = function( oNodeArray, xOffset, yOffset ){ - if (!oNodeArray) throw new Error ("An array of nodes to center node '"+this.name+"' above must be provided.") - - // Defaults for optional parameters - if (typeof xOffset === 'undefined') var xOffset = 0; - if (typeof yOffset === 'undefined') var yOffset = -30; - - // Works with nodes and nodes array - if (oNodeArray instanceof this.$.oNode) oNodeArray = [oNodeArray]; - if (oNodeArray.filter(function(x){return !x}).length) throw new Error ("Can't center node '"+ this.name+ "' above nodes "+ oNodeArray + ", invalid nodes found.") - - var _box = new this.$.oBox(); - _box.includeNodes( oNodeArray ); - - this.x = _box.center.x - this.width/2 + xOffset; - this.y = _box.top - this.height + yOffset; - - return new this.$.oPoint(this.x, this.y, this.z); -}; - - - /** - * Place a node below one or more nodes with an offset. - * @param {$.oNode[]} oNodeArray The array of nodes to center this below. - * @param {float} xOffset The horizontal offset to apply after centering. - * @param {float} yOffset The vertical offset to apply after centering. - * - * @return {oPoint} The resulting position of the node. - */ -$.oNode.prototype.centerBelow = function( oNodeArray, xOffset, yOffset){ - if (!oNodeArray) throw new Error ("An array of nodes to center node '"+this.name+"' below must be provided.") - - // Defaults for optional parameters - if (typeof xOffset === 'undefined') var xOffset = 0; - if (typeof yOffset === 'undefined') var yOffset = 30; - - // Works with nodes and nodes array - if (oNodeArray instanceof this.$.oNode) oNodeArray = [oNodeArray]; - if (oNodeArray.filter(function(x){return !x}).length) throw new Error ("Can't center node '"+ this.name+ "' below nodes "+ oNodeArray + ", invalid nodes found.") - - var _box = new this.$.oBox(); - _box.includeNodes(oNodeArray); - - this.x = _box.center.x - this.width/2 + xOffset; - this.y = _box.bottom + yOffset; - - return new this.$.oPoint(this.x, this.y, this.z); -} - - - /** - * Place at center of one or more nodes with an offset. - * @param {$.oNode[]} oNodeArray The array of nodes to center this below. - * @param {float} xOffset The horizontal offset to apply after centering. - * @param {float} yOffset The vertical offset to apply after centering. - * - * @return {oPoint} The resulting position of the node. - */ -$.oNode.prototype.placeAtCenter = function( oNodeArray, xOffset, yOffset ){ - // Defaults for optional parameters - if (typeof xOffset === 'undefined') var xOffset = 0; - if (typeof yOffset === 'undefined') var yOffset = 0; - - // Works with nodes and nodes array - if (typeof oNodeArray === 'oNode') oNodeArray = [oNodeArray]; - - var _box = new this.$.oBox(); - _box.includeNodes(oNodeArray); - - this.x = _box.center.x - this.width/2 + xOffset; - this.y = _box.center.y - this.height/2 + yOffset; - - return new this.$.oPoint(this.x, this.y, this.z); -} - - - /** - * Create a clone of the node. - * @param {string} newName The new name for the cloned module. - * @param {oPoint} newPosition The new position for the cloned module. - */ -$.oNode.prototype.clone = function( newName, newPosition ){ - // Defaults for optional parameters - if (typeof newPosition === 'undefined') var newPosition = this.nodePosition; - if (typeof newName === 'undefined') var newName = this.name+"_clone"; - - this.$.beginUndo("oH_cloneNode_"+this.name); - - var _clonedNode = this.group.addNode(this.type, newName, newPosition); - var _attributes = this.attributes; - - for (var i in _attributes){ - var _clonedAttribute = _clonedNode.getAttributeByName(_attributes[i].keyword); - _clonedAttribute.setToAttributeValue(_attributes[i]); - } - - var palettes = this.palettes - for (var i in palettes){ - _clonedNode.linkPalette(palettes[i]) - } - - this.$.endUndo(); - - return _clonedNode; -}; - - - /** - * Duplicates a node by creating an independent copy. - * @param {string} [newName] The new name for the duplicated node. - * @param {oPoint} [newPosition] The new position for the duplicated node. - */ -$.oNode.prototype.duplicate = function(newName, newPosition){ - if (typeof newPosition === 'undefined') var newPosition = this.nodePosition; - if (typeof newName === 'undefined') var newName = this.name+"_duplicate"; - - this.$.beginUndo("oH_cloneNode_"+this.name); - - var _duplicateNode = this.group.addNode(this.type, newName, newPosition); - var _attributes = this.attributes; - - for (var i in _attributes){ - var _duplicateAttribute = _duplicateNode.getAttributeByName(_attributes[i].keyword); - _duplicateAttribute.setToAttributeValue(_attributes[i], true); - } - - var palettes = this.palettes - for (var i in palettes){ - _duplicateNode.linkPalette(palettes[i]) - } - - this.$.endUndo(); - - return _duplicateNode; -}; - - - /** - * Removes the node from the scene. - * @param {bool} deleteColumns Should the columns of drawings be deleted as well? - * @param {bool} deleteElements Should the elements of drawings be deleted as well? - * - * @return {void} - */ -$.oNode.prototype.remove = function( deleteColumns, deleteElements ){ - if (typeof deleteFrames === 'undefined') var deleteColumns = true; - if (typeof deleteElements === 'undefined') var deleteElements = true; - - this.$.beginUndo("oH_deleteNode_"+this.name) - // restore links for special types; - if (this.type == "PEG"){ - var inNodes = this.inNodes; //Pegs can only have one inNode but we'll implement the general case for other types - var outNodes = this.outNodes; - for (var i in inNodes){ - for (var j in outNodes){ - for( var k in outNodes[j] ){ - inNodes[i].linkOutNode(outNodes[j][k]); - } - } - } - } - - node.deleteNode(this.path, deleteColumns, deleteElements); - this.$.endUndo(); -} - - - /** - * Provides a matching attribute based on provided keyword name. Keyword can include "." to get subattributes. - * @param {string} keyword The attribute keyword to search. - * @return {oAttribute} The matched attribute object, given the keyword. - */ -$.oNode.prototype.getAttributeByName = function( keyword ){ - keyword = keyword.toLowerCase(); - keyword = keyword.split("."); - - // we go through the keywords, trying to access an attribute corresponding to the name - var _attribute = this.attributes; - for (var i in keyword){ - var _keyword = keyword[i]; - - // applying conversion to the name 3dpath - if (_keyword == "3dpath") _keyword = "path3d"; - - if (!(_keyword in _attribute)) return null; - - _attribute = _attribute[_keyword]; - } - - if (_attribute instanceof this.$.oAttribute) return _attribute; - return null; -} - - - /** - * Used in converting the node to a string value, provides the string-path. - * @return {string} The node path's as a string. - */ -$.oNode.prototype.toString = function(){ - return this.path; -} - - - /** - * Provides a matching attribute based on the column name provided. Assumes only one match at the moment. - * @param {string} columnName The column name to search. - * @return {oAttribute} The matched attribute object, given the column name. - */ -$.oNode.prototype.getAttributeByColumnName = function( columnName ){ - // var attribs = []; - - //Initially check for cache. - var cdate = (new Date()).getTime(); - if( this.$.cache_columnToNodeAttribute[columnName] ){ - if( ( cdate - this.$.cache_columnToNodeAttribute[columnName].date ) < 5000 ){ - //Cache is in form : { "node":oAttributeObject.node, "attribute": this, "date": (new Date()).getTime() } - // attribs.push( this.$.cache_columnToNodeAttribute[columnName].attribute ); - return this.$.cache_columnToNodeAttribute[columnName].attribute; - } - } - - var _attributes = this.attributes; - - for( var n in _attributes){ - var t_attrib = _attributes[n]; - if( t_attrib.subAttributes.length>0 ){ - //Also check subattributes. - for( var t=0; tattribute lookup table for timeline building. - * @private - * @return {object} The column_name->attribute object LUT. {colName: { "node":oNode, "column":oColumn } } - */ -$.oNode.prototype.getAttributesColumnCache = function( obj_lut ){ - if (typeof obj_lut === 'undefined') obj_lut = {}; - - for( var n in this.attributes ){ - var t_attrib = this.attributes[n]; - if( t_attrib.subAttributes.length>0 ){ - //Also check subattributes. - for( var t=0;t0 ){ - //Its a sub attribute created. - try{ - var sub_attr = this.attributes[ res_split[0] ]; - for( x = 1; x - * It represents peg nodes in the scene. - * @constructor - * @augments $.oNode - * @classdesc Peg Module Class - * @param {string} path Path to the node in the network. - * @param {oScene} oSceneObject Access to the oScene object of the DOM. - */ -$.oPegNode = function( path, oSceneObject ) { - if (node.type(path) != 'PEG') throw "'path' parameter must point to a 'PEG' type node"; - var instance = this.$.oNode.call( this, path, oSceneObject ); - if (instance) return instance; - - this._type = 'pegNode'; -} -$.oPegNode.prototype = Object.create( $.oNode.prototype ); -$.oPegNode.prototype.constructor = $.oPegNode; - - - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oDrawingNode class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - -/** - * Constructor for the $.oDrawingNode class - * @classdesc - * $.oDrawingNode is a subclass of $.oNode and implements the same methods and properties as $.oNode.
- * It represents 'read' nodes or Drawing nodes in the scene. - * @constructor - * @augments $.oNode - * @param {string} path Path to the node in the network. - * @param {$.oScene} oSceneObject Access to the oScene object of the DOM. - * @example - * // Drawing Nodes are more than a node, as they do not work without an associated Drawing column and element. - * // adding a drawing node will automatically create a column and an element, unless they are provided as arguments. - * // Creating an element makes importing a drawing file possible. - * - * var doc = $.scn; - * - * var drawingName = "myDrawing"; - * var myElement = doc.addElement(drawingName, "TVG"); // add an element that holds TVG(Toonboom Vector Drawing) files - * var myDrawingColumn = doc.addColumn("DRAWING", drawingName, myElement); // create a column and link the element created to it - * - * var sceneRoot = doc.root; // grab the scene root group - * - * // Creating the Drawing node and linking the previously created element and column - * var myDrawingNode = sceneRoot.addDrawingNode(drawingName, new $.oPoint(), myDrawingColumn, myElement); - * - * // This also works: - * - * var myOtherNode = sceneRoot.addDrawingNode("Drawing2"); - */ -$.oDrawingNode = function(path, oSceneObject) { - // $.oDrawingNode can only represent a node of type 'READ' - if (node.type(path) != 'READ') throw "'path' parameter must point to a 'READ' type node"; - var instance = this.$.oNode.call(this, path, oSceneObject); - if (instance) return instance; - - this._type = 'drawingNode'; -} -$.oDrawingNode.prototype = Object.create($.oNode.prototype); -$.oDrawingNode.prototype.constructor = $.oDrawingNode; - - -/** - * The element that holds the drawings displayed by the node. - * @name $.oDrawingNode#element - * @type {$.oElement} - */ -Object.defineProperty($.oDrawingNode.prototype, "element", { - get : function(){ - var _column = this.attributes.drawing.element.column; - return ( new this.$.oElement( node.getElementId(this.path), _column ) ); - }, - - set : function( oElementObject ){ - var _column = this.attributes.drawing.element.column; - column.setElementIdOfDrawing( _column.uniqueName, oElementObject.id ); - } -}); - - -/** - * The column that holds the drawings displayed by the node. - * @name $.oDrawingNode.timingColumn - * @type {$.oDrawingColumn} - */ -Object.defineProperty($.oDrawingNode.prototype, "timingColumn", { - get : function(){ - var _column = this.attributes.drawing.element.column; - return _column; - }, - - set : function (oColumnObject){ - var _attribute = this.attributes.drawing.element; - _attribute.column = oColumnObject; - } -}); - - -/** - * An array of the colorIds contained within the drawings displayed by the node. - * @name $.oDrawingNode#usedColorIds - * @type {int[]} - */ -Object.defineProperty($.oDrawingNode.prototype, "usedColorIds", { - get : function(){ - // this.$.log("used colors in node : "+this.name) - var _drawings = this.element.drawings; - var _colors = []; - - for (var i in _drawings){ - var _drawingColors = _drawings[i].usedColorIds; - for (var c in _drawingColors){ - if (_colors.indexOf(_drawingColors[c]) == -1) _colors.push(_drawingColors[c]); - } - } - - return _colors; - } -}); - - -/** - * An array of the colors contained within the drawings displayed by the node, found in the palettes. - * @name $.oDrawingNode#usedColors - * @type {$.oColor[]} - */ -Object.defineProperty($.oDrawingNode.prototype, "usedColors", { - get : function(){ - // get unique Color Ids - var _ids = this.usedColorIds; - - // look in both element and scene palettes - var _palettes = this.palettes.concat(this.$.scn.palettes); - - // build a palette/id list to speedup massive palettes/palette lists - var _colorIds = {} - for (var i in _palettes){ - var _palette = _palettes[i]; - var _colors = _palette.colors; - _colorIds[_palette.name] = {}; - for (var j in _colors){ - _colorIds[_palette.name][_colors[j].id] = _colors[j]; - } - } - - // for each id on the drawing, identify the corresponding color - var _usedColors = _ids.map(function(id){ - for (var paletteName in _colorIds){ - if (_colorIds[paletteName][id]) return _colorIds[paletteName][id]; - } - throw new Error("Missing color found for id: "+id+". Color doesn't belong to any palette in the scene or element."); - }) - - return _usedColors; - } -}) - - -/** - * The drawing.element keyframes. - * @name $.oDrawingNode#timings - * @type {$.oFrames[]} - * @example - * // The timings hold the keyframes that display the drawings across time. - * - * var timings = $.scn.$node("Top/Drawing").timings; - * for (var i in timings){ - * $.log( timings.frameNumber+" : "+timings.value); // outputs the frame and the value of each keyframe - * } - * - * // timings are keyframe objects, so they are dynamic. - * timings[2].value = "5"; // sets the displayed image of the second key to the drawing named "5" - * - * // to set a new value to a frame that wasn't a keyframe before, it's possible to use the attribute keyword like so: - * - * var myNode = $.scn.$node("Top/Drawing"); - * myNode.drawing.element = {frameNumber: 5, value: "10"} // setting the value of the frame 5 - * myNode.drawing.element = {frameNumber: 6, value: timings[1].value} // setting the value to the same as one of the timings - */ -Object.defineProperty($.oDrawingNode.prototype, "timings", { - get : function(){ - return this.attributes.drawing.element.getKeyframes(); - } -}) - - -/** - * The element palettes linked to the node. - * @name $.oDrawingNode#palettes - * @type {$.oPalette[]} - */ -Object.defineProperty($.oDrawingNode.prototype, "palettes", { - get : function(){ - var _element = this.element; - return _element.palettes; - } -}) - - -// Class Methods - -/** - * Gets the drawing name at the given frame. - * @param {int} frameNumber - * @return {$.oDrawing} - */ -$.oDrawingNode.prototype.getDrawingAtFrame = function(frameNumber){ - if (typeof frame === "undefined") var frame = this.$.scene.currentFrame; - - var _attribute = this.attributes.drawing.element - return _attribute.getValue(frameNumber); -} - - - /** - * Gets the list of palettes containing colors used by a drawing node. This only gets palettes with the first occurrence of the colors. - * @return {$.oPalette[]} The palettes that contain the color IDs used by the drawings of the node. - */ -$.oDrawingNode.prototype.getUsedPalettes = function(){ - var _palettes = {}; - var _usedPalettes = []; - - var _usedColors = this.usedColors; - // build an object of palettes under ids as keys to remove duplicates - for (var i in _usedColors){ - var _palette = _usedColors[i].palette; - _palettes[_palette.id] = _palette; - } - for (var i in _palettes){ - _usedPalettes.push(_palettes[i]); - } - - return _usedPalettes; -} - - -/** - * Displays all the drawings from the node's element onto the timeline - * @param {int} [framesPerDrawing=1] The number of frames each drawing will be shown for - */ -$.oDrawingNode.prototype.exposeAllDrawings = function(framesPerDrawing){ - if (typeof framesPerDrawing === 'undefined') var framesPerDrawing = 1; - - var _drawings = this.element.drawings; - var frameNumber = 1; - for (var i=0; i < _drawings.length; i++){ - //log("showing drawing "+_drawings[i].name+" at frame "+i) - this.showDrawingAtFrame(_drawings[i], frameNumber); - frameNumber+=framesPerDrawing; - } - - var _column = this.attributes.drawing.element.column; - var _exposures = _column.getKeyframes(); - _column.extendExposures(_exposures, framesPerDrawing-1); -} - - -/** - * Displays the given drawing at the given frame - * @param {$.oDrawing} drawing - * @param {int} frameNum - */ -$.oDrawingNode.prototype.showDrawingAtFrame = function(drawing, frameNum){ - var _column = this.attributes.drawing.element.column; - _column.setValue(drawing.name, frameNum); -} - - - /** - * Links a palette to a drawing node as Element Palette. - * @param {$.oPalette} oPaletteObject the palette to link to the node - * @param {int} [index] The index of the list at which the palette should appear once linked - * - * @return {$.oPalette} The linked element Palette. - */ -$.oDrawingNode.prototype.linkPalette = function(oPaletteObject, index){ - return this.element.linkPalette(oPaletteObject, index); -} - - - /** - * Unlinks an Element Palette from a drawing node. - * @param {$.oPalette} oPaletteObject the palette to unlink from the node - * - * @return {bool} The success of the unlink operation. - */ -$.oDrawingNode.prototype.unlinkPalette = function(oPaletteObject){ - return this.element.unlinkPalette(oPaletteObject); -} - - - - - /** - * Duplicates a node by creating an independent copy. - * @param {string} [newName] The new name for the duplicated node. - * @param {oPoint} [newPosition] The new position for the duplicated node. - * @param {bool} [duplicateElement] Whether to also duplicate the element. - */ -$.oDrawingNode.prototype.duplicate = function(newName, newPosition, duplicateElement){ - if (typeof newPosition === 'undefined') var newPosition = this.nodePosition; - if (typeof newName === 'undefined') var newName = this.name+"_1"; - if (typeof duplicateElement === 'undefined') var duplicateElement = true; - - var _duplicateElement = duplicateElement?this.element.duplicate(this.name):this.element; - - var _duplicateNode = this.group.addDrawingNode(newName, newPosition, _duplicateElement); - var _attributes = this.attributes; - - for (var i in _attributes){ - var _duplicateAttribute = _duplicateNode.getAttributeByName(_attributes[i].keyword); - _duplicateAttribute.setToAttributeValue(_attributes[i], true); - } - - var _duplicateAttribute = _duplicateNode.getAttributeByName(_attributes[i].keyword); - _duplicateAttribute.setToAttributeValue(_attributes[i], true); - - return _duplicateNode; -}; - - - /** - * Updates the imported drawings in the node. - * @param {$.oFile} sourcePath the oFile object pointing to the source to update from - * @param {string} [drawingName] the drawing to import the updated bitmap into - * @todo implement a memory of the source through metadata - */ -$.oDrawingNode.prototype.update = function(sourcePath, drawingName){ - if (!this.element) return; // no element means nothing to update, import instead. - if (typeof drawingName === 'undefined') var drawingName = this.element.drawings[0].name; - - var _drawing = this.element.getDrawingByName(drawingName); - - _drawing.importBitmap(sourcePath); - _drawing.refreshPreview(); -} - - - /** - * Extracts the position information on a drawing node, and applies it to a new peg instead. - * @return {$.oPegNode} The created peg. - */ -$.oDrawingNode.prototype.extractPeg = function(){ - var _drawingNode = this; - var _peg = this.group.addNode("PEG", this.name+"-P"); - var _columns = _drawingNode.linkedColumns; - - _peg.position.separate = _drawingNode.offset.separate; - _peg.scale.separate = _drawingNode.scale.separate; - - // link each column that can be to the peg instead and reset the drawing node - for (var i in _columns){ - var _attribute = _columns[i].attributeObject; - var _keyword = _attribute._keyword; - - var _nodeAttribute = _drawingNode.getAttributeByName(_keyword); - - if (_keyword.indexOf("OFFSET") != -1) _keyword = _keyword.replace("OFFSET", "POSITION"); - - var _pegAttribute = _peg.getAttributeByName(_keyword); - - if (_pegAttribute !== null){ - _pegAttribute.column = _columns[i]; - _nodeAttribute.column = null; - _drawingNode[_keyword] = _attribute.defaultValue; - } - } - - _drawingNode.offset.separate = false; // doesn't work? - _drawingNode.can_animate = false; - - _peg.centerAbove(_drawingNode, -1, -30) - _drawingNode.linkInNode(_peg) - - return _peg; -} - - - /** - * Gets the contour curves of the drawing, as a concave hull. - * @param {int} [count] The number of points on the contour curve to derive. - * @param {int} [frame] The frame to derive the contours. - * - * @return {oPoint[][]} The contour curves. - */ -$.oDrawingNode.prototype.getContourCurves = function( count, frame ){ - - if (typeof frame === 'undefined') var frame = this.scene.currentFrame; - if (typeof count === 'undefined') var count = 3; - - var res = EnvelopeCreator().getDrawingBezierPath( this.path, - frame, //FRAME - 2.5, //DISCRETIZER - 0, //K - count, //DESIRED POINT COUNT - 0, //BLUR - 0, //EXPAND - false, //SINGLELINE - true, //USE MIN POINTS, - 0, //ADDITIONAL BISSECTING - - false - ); - if( res.success ){ - var _curves = res.results.map(function(x){return [ - new this.$.oPoint( x[0][0], x[0][1], 0.0 ), - new this.$.oPoint( x[1][0], x[1][1], 0.0 ), - new this.$.oPoint( x[2][0], x[2][1], 0.0 ), - new this.$.oPoint( x[3][0], x[3][1], 0.0 ) - ]; } ); - return _curves; - } - - return []; -} - - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oTransformSwitchNode class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - -/** - * Constructor for the $.oTransformSwitchNode class - * @classdesc - * $.oTransformSwitchNode is a subclass of $.oNode and implements the same methods and properties as $.oNode.
- * It represents transform switches in the scene. - * @constructor - * @augments $.oNode - * @param {string} path Path to the node in the network. - * @param {oScene} oSceneObject Access to the oScene object of the DOM. - * @property {$.oTransformNamesObject} names An array-like object with static indices (starting at 0) for each transformation name, which can be retrieved/set directly. - * @example - * // Assuming the existence of a Deformation group applied to a 'Drawing' node at the root of the scene - * var myNode = $.scn.getNodeByPath("Top/Deformation-Drawing/Transformation-Switch"); - * - * myNode.names[0] = "B"; // setting the value for the first transform drawing name to "B" - * - * var drawingNames = ["A", "B", "C"] // example of iterating over the existing names to set/retrieve them - * for (var i in myNode.names){ - * $.log(i+": "+myNode.names[i]); - * $.log(myNode.names[i] = drawingNames[i]); - * } - * - * $.log("length: " + myNode.names.length) // the number of names - * $.log("names: " + myNode.names) // prints the list of names - * $.log("indexOf 'B': " + myNode.names.indexOf("B")) // can use methods from Array - */ -$.oTransformSwitchNode = function( path, oSceneObject ) { - if (node.type(path) != 'TransformationSwitch') throw "'path' parameter ("+path+") must point to a 'TransformationSwitch' type node. Got: "+node.type(path); - var instance = this.$.oNode.call( this, path, oSceneObject ); - if (instance) return instance; - - this._type = 'transformSwitchNode'; - this.names = new this.$.oTransformNamesObject(this); -} -$.oTransformSwitchNode.prototype = Object.create( $.oNode.prototype ); -$.oTransformSwitchNode.prototype.constructor = $.oTransformSwitchNode; - - -/** - * Constructor for the $.oTransformNamesObject class - * @classdesc - * $.oTransformNamesObject is an array like object with static length that exposes getter setters for - * each transformation name used by the oTransformSwitchNode. It can use the same methods as any array. - * @constructor - * @param {$.oTransformSwitchNode} instance the transform Node instance using this object - * @property {int} length the number of valid elements in the object. - */ -$.oTransformNamesObject = function(transformSwitchNode){ - Object.defineProperty(this, "transformSwitchNode", { - enumerable:false, - get: function(){ - return transformSwitchNode; - }, - }) - - this.refresh(); -} -$.oTransformNamesObject.prototype = Object.create(Array.prototype); - - -/** - * creates a $.oTransformSwitch.names property with an index for each name to get/set the name value - * @private - */ -Object.defineProperty($.oTransformNamesObject.prototype, "createGetterSetter", { - enumerable:false, - value: function(index){ - var attrName = "transformation_" + (index+1); - var transformNode = this.transformSwitchNode; - - Object.defineProperty(this, index, { - enumerable:true, - configurable:true, - get: function(){ - return transformNode.transformationnames[attrName]; - }, - set: function(newName){ - newName = newName+""; // convert to string - this.$.debug("setting "+attrName+" to drawing "+newName+" on "+transformNode.path, this.$.DEBUG_LEVEL.DEBUG) - if (newName instanceof this.$.oDrawing) newName = newName.name; - transformNode.transformationnames[attrName] = newName; - } - }) - } -}) - - -/** - * The length of the array of names on the oTransformSwitchNode node. Corresponds to the transformationnames.size subAttribute. - * @name $.oTransformNamesObject#length - * @type {int} - */ - Object.defineProperty($.oTransformNamesObject.prototype, "length", { - enumerable:false, - get: function(){ - return this.transformSwitchNode.transformationnames.size; - }, -}) - - -/** - * A string representation of the names list - * @private - */ -Object.defineProperty($.oTransformNamesObject.prototype, "toString", { - enumerable:false, - value: function(){ - return this.join(","); - } -}) - - -/** - * @private - */ -Object.defineProperty($.oTransformNamesObject.prototype, "refresh", { - enumerable:false, - value:function(){ - for (var i in this){ - delete this[i]; - } - for (var i=0; i - * It represents color overrides in the scene. - * @constructor - * @augments $.oNode - * @param {string} path Path to the node in the network. - * @param {oScene} oSceneObject Access to the oScene object of the DOM. - */ - $.oColorOverrideNode = function(path, oSceneObject) { - // $.oDrawingNode can only represent a node of type 'READ' - if (node.type(path) != 'COLOR_OVERRIDE_TVG') throw "'path' parameter must point to a 'COLOR_OVERRIDE_TVG' type node"; - var instance = this.$.oNode.call(this, path, oSceneObject); - if (instance) return instance; - - this._type = 'colorOverrideNode'; - this._coObject = node.getColorOverride(path) -} -$.oColorOverrideNode.prototype = Object.create($.oNode.prototype); -$.oColorOverrideNode.prototype.constructor = $.oColorOverrideNode; - - -/** - * The list of palette overrides in this color override node - * @name $.oColorOverrideNode#palettes - * @type {$.oPalette[]} - * @readonly - */ -Object.defineProperty($.oColorOverrideNode.prototype, "palettes", { - get: function(){ - this.$.debug("getting palettes", this.$.DEBUG_LEVEL.LOG) - if (!this._palettes){ - this._palettes = []; - - var _numPalettes = this._coObject.getNumPalettes(); - for (var i=0; i<_numPalettes; i++){ - var _palettePath = this._coObject.palettePath(i) + ".plt"; - var _palette = this.$.scn.getPaletteByPath(_palettePath); - if (_palette) this._palettes.push(_palette); - } - } - - return this._palettes; - } -}) - -/** - * Add a new palette to the palette list (for now, only supports scene palettes) - * @param {$.oPalette} palette -*/ -$.oColorOverrideNode.prototype.addPalette = function(palette){ - var _palettes = this.palettes // init palettes cache to add to it - - this._coObject.addPalette(palette.path.path); - this._palettes.push(palette); -} - -/** - * Removes a palette to the palette list (for now, only supports scene palettes) - * @param {$.oPalette} palette - */ -$.oColorOverrideNode.prototype.removePalette = function(palette){ - this._coObject.removePalette(palette.path.path); -} - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oGroupNode class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - -/** - * Constructor for the $.oGroupNode class - * @classdesc - * $.oGroupNode is a subclass of $.oNode and implements the same methods and properties as $.oNode.
- * It represents groups in the scene. From this class, it's possible to add nodes, and backdrops, import files and templates into the group. - * @constructor - * @augments $.oNode - * @param {string} path Path to the node in the network. - * @param {oScene} oSceneObject Access to the oScene object of the DOM. - * @example - * // to add a new node, grab the group it'll be created in first - * var doc = $.scn - * var sceneRoot = doc.root; // grab the scene root group - * - * var myGroup = sceneRoot.addGrop("myGroup", false, false); // create a group in the scene root, with a peg and composite but no nodes - * var MPO = myGroup.multiportOut; // grab the multiport in of the group - * - * var myNode = myGroup.addDrawingNode("myDrawingNode"); // add a drawing node inside the group - * myNode.linkOutNode(MPO); // link the newly created node to the multiport - * myNode.centerAbove(MPO); - * - * var sceneComposite = doc.$node("Top/Composite"); // grab the scene composite node - * myGroup.linkOutNode(sceneComposite); // link the group to it - * - * myGroup.centerAbove(sceneComposite); - */ -$.oGroupNode = function(path, oSceneObject) { - // $.oDrawingNode can only represent a node of type 'READ' - if (node.type(path) != 'GROUP') throw "'path' parameter must point to a 'GROUP' type node"; - var instance = this.$.oNode.call(this, path, oSceneObject); - if (instance) return instance; - - this._type = 'groupNode'; -} -$.oGroupNode.prototype = Object.create($.oNode.prototype); -$.oGroupNode.prototype.constructor = $.oGroupNode; - -/** - * The multiport in node of the group. If one doesn't exist, it will be created. - * @name $.oGroupNode#multiportIn - * @readonly - * @type {$.oNode} - */ -Object.defineProperty($.oGroupNode.prototype, "multiportIn", { - get : function(){ - if (this.isRoot) return null - var _MPI = this.scene.getNodeByPath(node.getGroupInputModule(this.path, "Multiport-In", 0,-100,0),this.scene) - return (_MPI) - } -}) - - -/** - * The multiport out node of the group. If one doesn't exist, it will be created. - * @name $.oGroupNode#multiportOut - * @readonly - * @type {$.oNode} - */ -Object.defineProperty($.oGroupNode.prototype, "multiportOut", { - get : function(){ - if (this.isRoot) return null - var _MPO = this.scene.getNodeByPath(node.getGroupOutputModule(this.path, "Multiport-Out", 0, 100,0),this.scene) - return (_MPO) - } -}); - - /** - * All the nodes contained within the group, one level deep. - * @name $.oGroupNode#nodes - * @readonly - * @type {$.oNode[]} - */ -Object.defineProperty($.oGroupNode.prototype, "nodes", { - get : function() { - var _path = this.path; - var _nodes = node.subNodes(_path); - - var self = this; - return _nodes.map(function(x){return self.scene.getNodeByPath(x)}); - } -}); - - - - /** - * All the backdrops contained within the group. - * @name $.oGroupNode#backdrops - * @readonly - * @type {$.oBackdrop[]} - */ -Object.defineProperty($.oGroupNode.prototype, "backdrops", { - get : function() { - var _path = this.path; - var _backdropObjects = Backdrop.backdrops(this.path); - var _backdrops = _backdropObjects.map(function(x){return new this.$.oBackdrop(_path, x)}); - - return _backdrops; - } -}); - - - /** - * Returns a node from within a group based on its name. - * @param {string} name The name of the node. - * - * @return {$.oNode} The node, or null if can't be found. - */ -$.oGroupNode.prototype.getNodeByName = function(name){ - var _path = this.path+"/"+name; - - return this.scene.getNodeByPath(_path); -} - - - /** - * Returns all the nodes of a certain type in the group. - * Pass a value to recurse to look into the groups as well. - * @param {string} typeName The type of the nodes. - * @param {bool} recurse Whether to look inside the groups. - * - * @return {$.oNode[]} The nodes found. - */ -$.oGroupNode.prototype.getNodesByType = function(typeName, recurse){ - if (typeof recurse === 'undefined') var recurse = false; - return this.subNodes(recurse).filter(function(x){return x.type == typeName}); -} - - - /** - * Returns a child node in a group based on a search. - * @param {string} name The name of the node. - * - * @return {$.oNode} The node, or null if can't be found. - */ -$.oGroupNode.prototype.$node = function(name){ - return this.getNodeByName(name); -} - - - /** - * Gets all the nodes contained within the group. - * @param {bool} [recurse=false] Whether to recurse the groups within the groups. - * - * @return {$.oNode[]} The nodes in the group - */ -$.oGroupNode.prototype.subNodes = function(recurse){ - if (typeof recurse === 'undefined') recurse = false; - - var _nodes = node.subNodes(this.path); - var _subNodes = []; - - for (var i in _nodes){ - var _oNodeObject = this.scene.getNodeByPath(_nodes[i]); - _subNodes.push(_oNodeObject); - if (recurse && node.isGroup(_nodes[i])) _subNodes = _subNodes.concat(_oNodeObject.subNodes(recurse)); - } - - return _subNodes; -} - - - /** - * Gets all children of the group. - * @param {bool} [recurse=false] Whether to recurse the groups within the groups. - * - * @return {$.oNode[]} The nodes in the group - */ -$.oGroupNode.prototype.children = function(recurse){ - return this.subNodes(recurse); -} - - - - /** - * Creates an in-port on top of a group - * @param {int} portNum The port number where a port will be added - * @type {string} - * - * @return {int} The number of the created port in case the port specified was not correct (for example larger than the current number of ports + 1) - */ -$.oGroupNode.prototype.addInPort = function(portNum, type){ - var _inPorts = this.inPorts; - - if (typeof portNum === 'undefined') var portNum = _inPorts; - if (portNum > _inPorts) portNum = _inPorts; - - var _type = (type=="transform")?"READ":"none" - var _dummyNode = this.addNode(_type, "dummy_add_port_node"); - var _MPI = this.multiportIn; - _dummyNode.linkInNode(_MPI, 0, portNum, true); - _dummyNode.unlinkInNode(_MPI); - _dummyNode.remove(); - - return portNum; -} - - - /** - * Creates an out-port at the bottom of a group. For some reason groups can have many unconnected in-ports but only one unconnected out-port. - * @param {int} [portNum] The port number where a port will be added - * @type {string} - * - * @return {int} The number of the created port in case the port specified was not correct (for example larger than the current number of ports + 1) - */ -$.oGroupNode.prototype.addOutPort = function(portNum, type){ - var _outPorts = this.outPorts; - - if (typeof portNum === 'undefined') var portNum = _outPorts; - if (portNum > _outPorts) portNum = _outPorts; - - var _type = (type=="transform")?"PEG":"none" - var _dummyNode = this.addNode(_type, "dummy_add_port_node"); - var _MPO = this.multiportOut; - - _dummyNode.linkOutNode(_MPO, 0, portNum, true); - _dummyNode.unlinkOutNode(_MPO); - _dummyNode.remove(); - - return portNum; -} - - /** - * Gets all children of the group. - * @param {bool} [recurse=false] Whether to recurse the groups within the groups. - * - * @return {$.oNode[]} The nodes in the group - */ -$.oGroupNode.prototype.children = function(recurse){ - return this.subNodes(recurse); -} - - - - /** - * Sorts out the node view inside the group - * @param {bool} [recurse=false] Whether to recurse the groups within the groups. - */ -$.oGroupNode.prototype.orderNodeView = function(recurse){ - if (typeof recurse === 'undefined') var recurse = false; - - TB_orderNetworkUpBatchFromList( node.subNodes(this.path) ); - - if (!this.isRoot){ - var _MPO = this.multiportOut; - var _MPI = this.multiportIn; - - _MPI.x = _MPO.x - } - - if (recurse){ - var _subNodes = this.subNodes().filter(function(x){return x.type == "GROUP"}); - for (var i in _subNodes){ - _subNodes[i].orderNodeView(recurse); - } - } -} - - -/** - * Adds a node to the group. - * @param {string} type The type-name of the node to add. - * @param {string} [name=type] The name of the newly created node. - * @param {$.oPoint} [nodePosition={0,0,0}] The position for the node to be placed in the network. - * - * @return {$.oNode} The created node, or bool as false. - * @example - * // to add a node, simply call addNode on the group you want the node to be added to. - * var sceneRoot = $.scn.root; // grab the scene root group ("Top") - * - * var peg = sceneRoot.addNode("PEG", "MyNewlyCreatedPeg"); // adding a peg - * - * // Now we'll also create a drawing node to connect under the peg - * var sceneComposite = $.scn.getNodeByPath("Top/Composite"); // can also use $.scn.$node("Top/Composite") for shorter synthax - * - * var drawingNode = sceneRoot.addDrawingNode("myNewDrawingNode"); - * drawingNode.linkOutNode(sceneComposite); - * drawingNode.can_animate = false // setting some attributes on the newly created Node - * - * peg.linkOutNode(drawingNode); - * - * //through all this we didn't specify nodePosition parameters so we'll sort everything at once - * - * sceneRoot.orderNodeView(); - * - * // we can also do: - * - * peg.centerAbove(drawingNode); - * - */ -$.oGroupNode.prototype.addNode = function( type, name, nodePosition ){ - // Defaults for optional parameters - if (typeof nodePosition === 'undefined') var nodePosition = new this.$.oPoint(0,0,0); - if (typeof name === 'undefined') var name = type[0]+type.slice(1).toLowerCase(); - if (typeof name !== 'string') name = name+""; - - var _group = this.path; - - // create node and return result (this sanitizes/increments the name, so we only create the oNode with the returned value) - var _path = node.add(_group, name, type, nodePosition.x, nodePosition.y, nodePosition.z); - _node = this.scene.getNodeByPath(_path); - - return _node; -} - - -/** - * Adds a drawing layer to the group, with a drawing column and element linked. Possible to specify the column and element to use. - * @param {string} name The name of the newly created node. - * @param {$.oPoint} [nodePosition={0,0,0}] The position for the node to be placed in the network. - * @param {$.object} [element] The element to attach to the column. - * @param {object} [drawingColumn] The column to attach to the drawing module. - - * @return {$.oNode} The created node, or bool as false. - */ - -$.oGroupNode.prototype.addDrawingNode = function( name, nodePosition, oElementObject, drawingColumn){ - // add drawing column and element if not passed as parameters - this.$.beginUndo("oH_addDrawingNode_"+name); - - // Defaults for optional parameters - if (typeof nodePosition === 'undefined') var nodePosition = new this.$.oPoint(0,0,0); - if (typeof name === 'undefined') var name = type[0]+type.slice(1).toLowerCase(); - - // creating the node first to get the "safe name" returned by harmony - var _node = this.addNode("READ", name, nodePosition); - - if (typeof oElementObject === 'undefined') var oElementObject = this.scene.addElement(_node.name); - if (typeof drawingColumn === 'undefined'){ - // first look for a column in the element - if (!oElementObject.column) { - var drawingColumn = this.scene.addColumn("DRAWING", _node.name, oElementObject); - }else{ - var drawingColumn = oElementObject.column; - } - } - - // setup the node - // setup animate mode/separate based on preferences? - _node.attributes.drawing.element.column = drawingColumn; - - this.$.endUndo(); - - return _node; -} - - -/** - * Adds a new group to the group, and optionally move the specified nodes into it. - * @param {string} name The name of the newly created group. - * @param {$.oPoint} [addComposite=false] Whether to add a composite. - * @param {bool} [addPeg=false] Whether to add a peg. - * @param {$.oNode[]} [includeNodes] The nodes to add to the group. - * @param {$.oPoint} [nodePosition={0,0,0}] The position for the node to be placed in the network. - - * @return {$.oGroupNode} The created node, or bool as false. - */ -$.oGroupNode.prototype.addGroup = function( name, addComposite, addPeg, includeNodes, nodePosition ){ - // Defaults for optional parameters - if (typeof addPeg === 'undefined') var addPeg = false; - if (typeof addComposite === 'undefined') var addComposite = false; - if (typeof includeNodes === 'undefined') var includeNodes = []; - - this.$.beginUndo("oH_addGroup_"+name); - - var nodeBox = new this.$.oBox(); - includeNodes = includeNodes.filter(function(x){return !!x}) // filter out all invalid types - if (includeNodes.length > 0) nodeBox.includeNodes(includeNodes); - - if (typeof nodePosition === 'undefined') var nodePosition = includeNodes.length?nodeBox.center:new this.$.oPoint(0,0,0); - - var _group = this.addNode( "GROUP", name, nodePosition ); - - var _MPI = _group.multiportIn; - var _MPO = _group.multiportOut; - - if (addComposite){ - var _composite = _group.addNode("COMPOSITE", name+"_Composite"); - _composite.composite_mode = "Pass Through"; // get preference? - _composite.linkOutNode(_MPO); - _composite.centerAbove(_MPO); - } - - if (addPeg){ - var _peg = _group.addNode("PEG", name+"-P"); - _peg.linkInNode(_MPI); - _peg.centerBelow(_MPI); - } - - // moves nodes into the created group and recreates their hierarchy and links - if (includeNodes.length > 0){ - includeNodes = includeNodes.sort(function(a, b){return a.timelineIndex()>=b.timelineIndex()?1:-1}) - - var _links = this.scene.getNodesLinks(includeNodes); - - for (var i in includeNodes){ - includeNodes[i].moveToGroup(_group); - } - - for (var i in _links){ - _links[i].connect(); - } - - // link all unconnected nodes to the peg/MPI and comp/MPO - var _topNode = _peg?_peg:_MPI; - var _bottomNode = _composite?_composite:_MPO; - - for (var i in includeNodes){ - for (var j=0; j < includeNodes[i].inPorts; j++){ - if (includeNodes[i].getInLinksNumber(j) == 0) includeNodes[i].linkInNode(_topNode); - } - - for (var j=0; j < includeNodes[i].outPorts; j++){ - if (includeNodes[i].getOutLinksNumber(j) == 0) includeNodes[i].linkOutNode(_bottomNode,0,0); - } - } - - //shifting MPI/MPO/peg/comp out of the way of included nodes - if (_peg){ - _peg.centerAbove(includeNodes); - includeNodes.push(_peg); - } - - if (_composite){ - _composite.centerBelow(includeNodes); - includeNodes.push(_composite); - } - - _MPI.centerAbove(includeNodes); - _MPO.centerBelow(includeNodes); - } - - this.$.endUndo(); - return _group; -} - - -/** - * Imports the specified template into the scene. - * @param {string} tplPath The path of the TPL file to import. - * @param {$.oNode[]} [destinationNodes=false] The nodes affected by the template. - * @param {bool} [extendScene=true] Whether to extend the exposures of the content imported. - * @param {$.oPoint} [nodePosition={0,0,0}] The position to offset imported new nodes. - * @param {object} [pasteOptions] An object containing paste options as per Harmony's standard paste options. - * - * @return {$.oNode[]} The resulting pasted nodes. - */ -$.oGroupNode.prototype.importTemplate = function( tplPath, destinationNodes, extendScene, nodePosition, pasteOptions ){ - if (typeof nodePosition === 'undefined') var nodePosition = new oPoint(0,0,0); - if (typeof destinationNodes === 'undefined' || destinationNodes.length == 0) var destinationNodes = false; - if (typeof extendScene === 'undefined') var extendScene = true; - - if (typeof pasteOptions === 'undefined') var pasteOptions = copyPaste.getCurrentPasteOptions(); - pasteOptions.extendScene = extendScene; - - this.$.beginUndo("oH_importTemplate"); - - var _group = this.path; - - if(tplPath instanceof this.$.oFolder) tplPath = tplPath.path; - - this.$.debug("importing template : "+tplPath, this.$.DEBUG_LEVEL.LOG); - - var _copyOptions = copyPaste.getCurrentCreateOptions(); - var _tpl = copyPaste.copyFromTemplate(tplPath, 0, 999, _copyOptions); // any way to get the length of a template before importing it? - - if (destinationNodes){ - // TODO: deal with import options to specify frames - copyPaste.paste(_tpl, destinationNodes.map(function(x){return x.path}), 0, 999, pasteOptions); - var _nodes = destinationNodes; - }else{ - var oldBackdrops = this.backdrops; - copyPaste.pasteNewNodes(_tpl, _group, pasteOptions); - var _scene = this.scene; - var _nodes = selection.selectedNodes().map(function(x){return _scene.$node(x)}); - for (var i in _nodes){ - // only move the root nodes - if (_nodes[i].parent.path != this.path) continue - - _nodes[i].x += nodePosition.x; - _nodes[i].y += nodePosition.y; - } - - // move backdrops present in the template - var backdrops = this.backdrops.slice(oldBackdrops.length); - for (var i in backdrops){ - backdrops[i].x += nodePosition.x; - backdrops[i].y += nodePosition.y; - } - - // move waypoints in the top level of the template - for (var i in _nodes) { - var nodePorts = _nodes[i].outPorts; - for (var p = 0; p < nodePorts; p++) { - var theseWP = waypoint.childWaypoints(_nodes[i], p); - if (theseWP.length > 0) { - for (var w in theseWP) { - var x = waypoint.coordX(theseWP[w]); - var y = waypoint.coordY(theseWP[w]); - x += nodePosition.x; - y += nodePosition.y; - waypoint.setCoord(theseWP[w],x,y); - } - } - } - } - - } - - this.$.endUndo(); - return _nodes; -} - - -/** - * Adds a backdrop to a group in a specific position. - * @param {string} [title="Backdrop"] The title of the backdrop. - * @param {string} [body=""] The body text of the backdrop. - * @param {$.oColorValue} [color="#323232ff"] The oColorValue of the node. - * @param {float} [x=0] The X position of the backdrop, an offset value if nodes are specified. - * @param {float} [y=0] The Y position of the backdrop, an offset value if nodes are specified. - * @param {float} [width=30] The Width of the backdrop, a padding value if nodes are specified. - * @param {float} [height=30] The Height of the backdrop, a padding value if nodes are specified. - * - * @return {$.oBackdrop} The created backdrop. - */ -$.oGroupNode.prototype.addBackdrop = function(title, body, color, x, y, width, height ){ - if (typeof color === 'undefined') var color = new this.$.oColorValue("#323232ff"); - if (typeof body === 'undefined') var body = ""; - - if (typeof x === 'undefined') var x = 0; - if (typeof y === 'undefined') var y = 0; - if (typeof width === 'undefined') var width = 30; - if (typeof height === 'undefined') var height = 30; - - var position = {"x":x, "y":y, "w":width, "h":height}; - - var groupPath = this.path; - - if(!(color instanceof this.$.oColorValue)) color = new this.$.oColorValue(color); - - - // incrementing title so that two backdrops can't have the same title - if (typeof title === 'undefined') var title = "Backdrop"; - - var _groupBackdrops = Backdrop.backdrops(groupPath); - var names = _groupBackdrops.map(function(x){return x.title.text}) - var count = 0; - var newTitle = title; - - while (names.indexOf(newTitle) != -1){ - count++; - newTitle = title+"_"+count; - } - title = newTitle; - - - var _backdrop = { - "position" : position, - "title" : {"text":title, "color":4278190080, "size":12, "font":"Arial"}, - "description" : {"text":body, "color":4278190080, "size":12, "font":"Arial"}, - "color" : color.toInt() - } - - Backdrop.addBackdrop(groupPath, _backdrop) - return new this.$.oBackdrop(groupPath, _backdrop) -}; - - -/** - * Adds a backdrop to a group around specified nodes - * @param {$.oNode[]} nodes The nodes that the backdrop encompasses. - * @param {string} [title="Backdrop"] The title of the backdrop. - * @param {string} [body=""] The body text of the backdrop. - * @param {$.oColorValue} [color=#323232ff] The oColorValue of the node. - * @param {float} [x=0] The X position of the backdrop, an offset value if nodes are specified. - * @param {float} [y=0] The Y position of the backdrop, an offset value if nodes are specified. - * @param {float} [width=20] The Width of the backdrop, a padding value if nodes are specified. - * @param {float} [height=20] The Height of the backdrop, a padding value if nodes are specified. - * - * @return {$.oBackdrop} The created backdrop. - * @example - * function createColoredBackdrop(){ - * // This script will prompt for a color and create a backdrop around the selection - * $.beginUndo() - * - * var doc = $.scn; // grab the scene - * var nodes = doc.getSelectedNodes(); // grab the selection - * - * if(!nodes) return // exit the function if no nodes are selected - * - * var color = pickColor(); // prompt for color - * - * var group = nodes[0].group // get the group to add the backdrop to - * var backdrop = group.addBackdropToNodes(nodes, "BackDrop", "", color) - * - * $.endUndo(); - * - * // function to get the color chosen by the user - * function pickColor(){ - * var d = new QColorDialog; - * d.exec(); - * var color = d.selectedColor(); - * return new $.oColorValue({r:color.red(), g:color.green(), b:color.blue(), a:color.alpha()}) - * } - * } - */ -$.oGroupNode.prototype.addBackdropToNodes = function( nodes, title, body, color, x, y, width, height ){ - if (typeof color === 'undefined') var color = new this.$.oColorValue("#323232ff"); - if (typeof body === 'undefined') var body = ""; - if (typeof x === 'undefined') var x = 0; - if (typeof y === 'undefined') var y = 0; - if (typeof width === 'undefined') var width = 20; - if (typeof height === 'undefined') var height = 20; - - - // get default size from node bounds - if (typeof nodes === 'undefined') var nodes = []; - - if (nodes.length > 0) { - var _nodeBox = new this.$.oBox(); - _nodeBox.includeNodes(nodes); - - x = _nodeBox.left - x - width; - y = _nodeBox.top - y - height; - width = _nodeBox.width + width*2; - height = _nodeBox.height + height*2; - } - - var _backdrop = this.addBackdrop(title, body, color, x, y, width, height) - - return _backdrop; -}; - - -/** - * Imports a PSD into the group. - * This function is not available when running as harmony in batch mode. - * @param {string} path The PSD file to import. - * @param {bool} [separateLayers=true] Separate the layers of the PSD. - * @param {bool} [addPeg=true] Whether to add a peg. - * @param {bool} [addComposite=true] Whether to add a composite. - * @param {string} [alignment="ASIS"] Alignment type. - * @param {$.oPoint} [nodePosition={0,0,0}] The position for the node to be placed in the node view. - * - * @return {$.oNode[]} The nodes being created as part of the PSD import. - * @example - * // This example browses for a PSD file then import it in the root of the scene, then connects it to the main composite. - * - * function importCustomPSD(){ - * $.beginUndo("importCustomPSD"); - * var psd = $.dialog.browseForFile("get PSD", "*.psd"); // prompt for a PSD file - * - * if (!psd) return; // dialog was cancelled, exit the function - * - * var doc = $.scn; // get the scene object - * var sceneRoot = doc.root // grab the scene root group - * var psdNodes = sceneRoot.importPSD(psd); // import the psd with default settings - * var psdComp = psdNodes.pop() // get the composite node at the end of the psdNodes array - * var sceneComp = doc.$node("Top/Composite") // get the scene main composite - * psdComp.linkOutNode(sceneComp); // ... and link the two. - * sceneRoot.orderNodeView(); // orders the node view inside the group - * $.endUndo(); - * } - */ -$.oGroupNode.prototype.importPSD = function( path, separateLayers, addPeg, addComposite, alignment, nodePosition){ - if (typeof alignment === 'undefined') var alignment = "ASIS" // create an enum for alignments? - if (typeof addComposite === 'undefined') var addComposite = true; - if (typeof addPeg === 'undefined') var addPeg = true; - if (typeof separateLayers === 'undefined') var separateLayers = true; - if (typeof nodePosition === 'undefined') var nodePosition = new this.$.oPoint(0,0,0); - - if (this.$.batchMode){ - this.$.debug("Error: can't import PSD file "+_psdFile.path+" in batch mode.", this.$.DEBUG_LEVEL.ERROR); - return null - } - - var _psdFile = (path instanceof this.$.oFile)?path:new this.$.oFile( path ); - if (!_psdFile.exists){ - this.$.debug("Error: can't import PSD file "+_psdFile.path+" because it doesn't exist", this.$.DEBUG_LEVEL.ERROR); - return null; - } - - this.$.beginUndo("oH_importPSD_"+_psdFile.name); - - var _elementName = _psdFile.name; - - var _xSpacing = 45; - var _ySpacing = 30; - - var _element = this.scene.addElement(_elementName, "PSD"); - - // save scene otherwise PSD is copied correctly into the element - // but the TGA for each layer are not generated - // TODO: how to go around this to avoid saving? - scene.saveAll(); - var _drawing = _element.addDrawing(1); - - if (addPeg) var _peg = this.addNode("PEG", _elementName+"-P", nodePosition); - if (addComposite) var _comp = this.addNode("COMPOSITE", _elementName+"-Composite", nodePosition); - - // Import the PSD in the element - CELIO.pasteImageFile({ src : _psdFile.path, dst : { elementId : _element.id, exposure : _drawing.name}}); - var _layers = CELIO.getLayerInformation(_psdFile.path); - var _info = CELIO.getInformation(_psdFile.path); - - // create the nodes for each layer - var _nodes = []; - if (separateLayers){ - - var _scale = _info.height/scene.defaultResolutionY(); - var _x = nodePosition.x - _layers.length/2*_xSpacing; - var _y = nodePosition.y - _layers.length/2*_ySpacing; - - for (var i in _layers){ - // generate nodes and set them to show the element for each layer - var _layer = _layers[i]; - var _layerName = _layer.layerName.split(" ").join("_"); - var _nodePosition = new this.$.oPoint(_x+=_xSpacing, _y +=_ySpacing, 0); - - // get/build the group - var _group = this; - var _groupPathComponents = _layer.layerPathComponents; - var _destinationPath = this.path; - var _groupPeg = _peg; - var _groupComp = _comp; - - // recursively creating groups if they are missing - for (var i in _groupPathComponents){ - var _destinationPath = _destinationPath + "/" + _groupPathComponents[i]; - var _nextGroup = this.$.scene.getNodeByPath(_destinationPath); - - if (!_nextGroup){ - _nextGroup = _group.addGroup(_groupPathComponents[i], true, true, [], _nodePosition); - if (_groupPeg) _nextGroup.linkInNode(_groupPeg); - if (_groupComp) _nextGroup.linkOutNode(_groupComp, 0, 0); - } - // store the peg/comp for next iteration or layer node - _group = _nextGroup; - _groupPeg = _group.multiportIn.linkedOutNodes[0]; - _groupComp = _group.multiportOut.linkedInNodes[0]; - } - - var _column = this.scene.addColumn("DRAWING", _layerName, _element); - var _node = _group.addDrawingNode(_layerName, _nodePosition, _element, _column); - - _node.enabled = _layers[i].visible; - _node.can_animate = false; // use general pref? - _node.apply_matte_to_color = "Straight"; - _node.alignment_rule = alignment; - _node.scale.x = _scale; - _node.scale.y = _scale; - - _column.setValue(_layer.layer != ""?"1:"+_layer.layer:1, 1); - _column.extendExposures(); - - if (_groupPeg) _node.linkInNode(_groupPeg); - if (_groupComp) _node.linkOutNode(_groupComp, 0, 0); - - _nodes.push(_node); - } - }else{ - this.$.endUndo(); - throw new Error("importing PSD as a flattened layer not yet implemented"); - } - - if (addPeg){ - _peg.centerAbove(_nodes, 0, -_ySpacing ) - _nodes.unshift(_peg) - } - - if (addComposite){ - _comp.centerBelow(_nodes, 0, _ySpacing ) - _nodes.push(_comp) - } - // TODO how to display only one node with the whole file - this.$.endUndo() - - return _nodes -} - - -/** - * Updates a PSD previously imported into the group - * @param {string} path The updated psd file to import. - * @param {bool} [separateLayers=true] Separate the layers of the PSD. - * - * @return {$.oNode[]} The nodes that have been updated/created - */ -$.oGroupNode.prototype.updatePSD = function( path, separateLayers ){ - if (typeof separateLayers === 'undefined') var separateLayers = true; - - var _psdFile = (path instanceof this.$.oFile)?path:new this.$.oFile(path); - if (!_psdFile.exists){ - this.$.debug("Error: can't import PSD file "+_psdFile.path+" for update because it doesn't exist", this.$.DEBUG_LEVEL.ERROR); - return null; - } - - this.$.beginUndo("oH_updatePSD_"+_psdFile.name) - - // get info from the PSD - var _info = CELIO.getInformation(_psdFile.path); - var _layers = CELIO.getLayerInformation(_psdFile.path); - var _scale = _info.height/scene.defaultResolutionY(); - - // use layer information to find nodes from precedent export - if (separateLayers){ - var _nodes = this.subNodes(true).filter(function(x){return x.type == "READ"}); - var _nodeNames = _nodes.map(function(x){return x.name}); - - var _psdNodes = []; - var _missingLayers = []; - var _PSDelement = ""; - var _positions = new Array(_layers.length); - var _scale = _info.height/scene.defaultResolutionY(); - - // for each layer find the node by looking at the column name - for (var i in _layers){ - var _layer = _layers[i]; - var _layerName = _layers[i].layerName.split(" ").join("_"); - var _found = false; - - // find the node - for (var j in _nodes){ - if (_nodes[j].element.format != "PSD") continue; - - var _drawingColumn = _nodes[j].attributes.drawing.element.column; - - // update the node if found - if (_drawingColumn.name == _layer.layerName){ - _psdNodes.push(_nodes[j]); - _found = true; - - // update scale in case PSDfile size changed - _nodes[j].scale.x = _scale; - _nodes[j].scale.y = _scale; - - _positions[_layer.position] = _nodes[j]; - - // store the element - _PSDelement = _nodes[j].element - - break; - } - // if not found, add to the list of layers to import - _found = false; - } - - if (!_found) _missingLayers.push(_layer); - } - - - if (_psdNodes.length == 0){ - // PSD was never imported, use import instead? - this.$.debug("can't find a PSD element to update", this.$.DEBUG_LEVEL.ERROR); - this.$.endUndo(); - return null; - } - - // pasting updated PSD into element - CELIO.pasteImageFile({ src : _psdFile.path, dst : { elementId : _PSDelement.id, exposure : "1"}}) - - for (var i in _missingLayers){ - // find previous import Settings re: group/alignment etc - var _layer = _missingLayers[i]; - var _layerName = _layer.layerName.split(" ").join("_"); - - var _layerIndex = _layer.position; - var _nodePosition = new this.$.oPoint(0,0,0); - var _group = _psdNodes[0].group; - var _alignment = _psdNodes[0].alignment_rule; - var _scale = _psdNodes[0].scale.x; - var _peg = _psdNodes[0].inNodes[0]; - var _comp = _psdNodes[0].outNodes[0]; - var _scale = _info.height/scene.defaultResolutionY() - var _port; - - //TODO: set into right group according to PSD organisation - // looking for the existing node below and get the comp port from it - for (var j = _layerIndex-1; j>=0; j--){ - if (_positions[j] != undefined) break; - } - var _nodeBelow = _positions[j]; - - var _compNodes = _comp.inNodes; - - for (var j=0; j<_compNodes.length; j++){ - if (_nodeBelow.path == _compNodes[j].path){ - _port = j+1; - _nodePosition = _compNodes[j].nodePosition; - _nodePosition.x -= 35; - _nodePosition.y -= 25; - } - } - - // generate nodes and set them to show the element for each layer - var _node = this.addDrawingNode(_layerName, _nodePosition, _PSDelement); - - _node.enabled = _layer.visible; - _node.can_animate = false; // use general pref? - _node.apply_matte_to_color = "Straight"; - _node.alignment_rule = _alignment; - _node.scale.x = _scale; - _node.scale.y = _scale; - - _node.attributes.drawing.element.setValue(_layer.layer != ""?"1:"+_layer.layer:1, 1); - _node.attributes.drawing.element.column.extendExposures(); - - // find composite/peg to connect to based on other layers - - //if (addPeg) _node.linkInNode(_peg) - if (_port) _node.linkOutNode(_comp, 0, _port) - - _nodes.push(_node); - } - this.$.endUndo(); - return nodes; - } else{ - this.$.endUndo(); - throw new Error("updating a PSD imported as a flattened layer not yet implemented"); - } -} - - -/** - * Import a generic image format (PNG, JPG, TGA etc) as a read node. - * @param {string} path The image file to import. - * @param {string} [alignment="ASIS"] Alignment type. - * @param {$.oPoint} [nodePosition={0,0,0}] The position for the node to be placed in the node view. - * - * @return {$.oNode} The node for the imported image - */ -$.oGroupNode.prototype.importImage = function( path, alignment, nodePosition, convertToTvg){ - if (typeof alignment === 'undefined') var alignment = "ASIS"; // create an enum for alignments? - if (typeof nodePosition === 'undefined') var nodePosition = new this.$.oPoint(0,0,0); - - var _imageFile = (path instanceof this.$.oFile)?path:new this.$.oFile( path ); - var _elementName = _imageFile.name; - - var _elementType = convertToTvg?"TVG":_imageFile.extension.toUpperCase(); - var _element = this.scene.addElement(_elementName, _elementType); - var _column = this.scene.addColumn("DRAWING", _elementName, _element); - _element.column = _column; - - if (_imageFile.exists) { - var _drawing = _element.addDrawing(1, 1, _imageFile.path, convertToTvg); - }else{ - this.$.debug("Image file to import "+_imageFile.path+" could not be found.", this.$.DEBUG_LEVEL.ERROR); - } - - var _imageNode = this.addDrawingNode(_elementName, nodePosition, _element); - - _imageNode.can_animate = false; // use general pref? - _imageNode.apply_matte_to_color = "Straight"; - _imageNode.alignment_rule = alignment; - - var _scale = CELIO.getInformation(_imageFile.path).height/this.scene.defaultResolutionY; - _imageNode.scale.x = _scale; - _imageNode.scale.y = _scale; - - _imageNode.attributes.drawing.element.setValue(_drawing.name, 1); - _imageNode.attributes.drawing.element.column.extendExposures(); - - // TODO how to display only one node with the whole file - return _imageNode; -} - - -/** - * imports an image as a tvg drawing. - * @param {$.oFile} path the image file to import - * @param {string} [alignment="ASIS"] the alignment mode for the imported image - * @param {$.oPoint} [nodePosition={0,0,0}] the position for the created node. - */ -$.oGroupNode.prototype.importImageAsTVG = function(path, alignment, nodePosition){ - if (!(path instanceof this.$.oFile)) path = new this.$.oFile(path); - - var _imageNode = this.importImage(_convertedFilePath, alignment, nodePosition, true); - _imageNode.name = path.name; - - return _imageNode; -} - - -/** - * imports an image sequence as a node into the current group. - * @param {$.oFile[]} imagePaths a list of paths to the images to import (can pass a list of strings or $.oFile) - * @param {number} [exposureLength=1] the number of frames each drawing should be exposed at. If set to 0/false, each drawing will use the numbering suffix of the file to set its frame. - * @param {boolean} [convertToTvg=false] whether to convert the files to tvg during import - * @param {string} [alignment="ASIS"] the alignment to apply to the node - * @param {$.oPoint} [nodePosition] the position of the node in the nodeview - * - * @returns {$.oDrawingNode} the created node - */ -$.oGroupNode.prototype.importImageSequence = function(imagePaths, exposureLength, convertToTvg, alignment, nodePosition, extendScene) { - if (typeof exposureLength === 'undefined') var exposureLength = 1; - if (typeof alignment === 'undefined') var alignment = "ASIS"; // create an enum for alignments? - if (typeof nodePosition === 'undefined') var nodePosition = new this.$.oPoint(0,0,0); - - if (typeof extendScene === 'undefined') var extendScene = false; - - // match anything but capture trailing numbers and separates punctuation preceding it - var numberingRe = /(.*?)([\W_]+)?(\d*)$/i; - - // sanitize imagePaths - imagePaths = imagePaths.map(function(x){ - if (x instanceof this.$.oFile){ - return x; - } else { - return new this.$.oFile(x); - } - }) - - var images = []; - - if (!exposureLength) { - // figure out scene length based on exposure and extend the scene if needed - var sceneLength = 0; - var image = {frame:0, path:""}; - - for (var i in imagePaths){ - var imagePath = imagePaths[i]; - if (!(imagePath instanceof this.$.oFile)) imagePath = new this.$.oFile(imagePath); - var nameGroups = imagePath.name.match(numberingRe); - - if (nameGroups[3]){ - // use trailing number as frame number - var frameNumber = parseInt(nameGroups[3], 10); - if (frameNumber > sceneLength) sceneLength = frameNumber; - - images.push({frame: frameNumber, path:imagePath}); - } - } - } else { - // simply create a list of numbers based on exposure - images = imagePaths.map(function(x, index){ - var frameNumber = index * exposureLength + 1; - return ({frame:frameNumber, path:x}); - }) - var sceneLength = images[images.length-1].frame + exposureLength - 1; - } - - if (extendScene){ - if (this.scene.length < sceneLength) this.scene.length = sceneLength; - } - - // create a node to hold the image sequence - var firstImage = imagePaths[0]; - var name = firstImage.name.match(numberingRe)[1]; // match anything before trailing digits - var drawingNode = this.importImage(firstImage, alignment, nodePosition, convertToTvg); - drawingNode.name = name; - - for (var i in images){ - var image = images[i]; - drawingNode.element.addDrawing(image.frame, image.frame, image.path, convertToTvg); - } - - drawingNode.timingColumn.extendExposures(); - - return drawingNode; -} - -/** - * Imports a QT into the group - * @param {string} path The palette file to import. - * @param {bool} [importSound=true] Whether to import the sound - * @param {bool} [extendScene=true] Whether to extend the scene to the duration of the QT. - * @param {string} [alignment="ASIS"] Alignment type. - * @param {$.oPoint} [nodePosition] The position for the node to be placed in the network. - * - * @return {$.oNode} The imported Quicktime Node. - */ -$.oGroupNode.prototype.importQT = function( path, importSound, extendScene, alignment, nodePosition){ - if (typeof alignment === 'undefined') var alignment = "ASIS"; - if (typeof extendScene === 'undefined') var extendScene = true; - if (typeof importSound === 'undefined') var importSound = true; - if (typeof nodePosition === 'undefined') var nodePosition = new this.$.oPoint(0,0,0); - - var _QTFile = (path instanceof this.$.oFile)?path:new this.$.oFile(path); - if (!_QTFile.exists){ - throw new Error ("Import Quicktime failed: file "+_QTFile.path+" doesn't exist"); - } - - var _movieName = _QTFile.name; - this.$.beginUndo("oH_importQT_"+_movieName); - - var _element = this.scene.addElement(_movieName, "PNG"); - var _elementName = _element.name; - - var _movieNode = this.addDrawingNode(_movieName, nodePosition, _element); - var _column = _movieNode.attributes.drawing.element.column; - _element.column = _column; - - // setup the node - _movieNode.can_animate = false; - _movieNode.alignment_rule = alignment; - - // create the temp folder - var _tempFolder = new this.$.oFolder(this.$.scn.tempFolder.path + "/movImport/" + _element.id); - _tempFolder.create(); - - var _tempFolderPath = _tempFolder.path; - var _audioPath = _tempFolder.path + "/" + _movieName + ".wav"; - - // progressDialog will display an infinite loading bar as we don't have precise feedback - var progressDialog = new this.$.oProgressDialog("Importing video...", 0, "Import Movie", true); - - // setup import - MovieImport.setMovieFilename(_QTFile.path); - MovieImport.setImageFolder(_tempFolder); - MovieImport.setImagePrefix(_movieName); - if (importSound) MovieImport.setAudioFile(_audioPath); - this.$.log("converting movie file to pngs..."); - MovieImport.doImport(); - this.$.log("conversion finished"); - - progressDialog.range = 100; - progressDialog.value = 80; - - var _movielength = MovieImport.numberOfImages(); - - if (extendScene && this.scene.length < _movielength) this.scene.length = _movielength; - - // create a drawing for each frame - for (var i=1; i<=_movielength; i++) { - _drawingPath = _tempFolder + "/" + _movieName + "-" + i + ".png"; - _element.addDrawing(i, i, _drawingPath); - } - - progressDialog.value = 95; - - // creating an audio column for the sound - if (importSound && MovieImport.isAudioFileCreated() ){ - var _soundName = _elementName + "_sound"; - var _soundColumn = this.scene.addColumn("SOUND", _soundName); - column.importSound( _soundColumn.name, 1, _audioPath); - } - - progressDialog.value = 100; - - this.$.endUndo(); - return _movieNode; -} - diff --git a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_nodeAttributes.js b/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_nodeAttributes.js deleted file mode 100644 index 38a077ea5a..0000000000 --- a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_nodeAttributes.js +++ /dev/null @@ -1,3636 +0,0 @@ -var docstringStart = "/**" -var docstringEnd = "*/" -/* -// values outputted by following script: -function traceAll(){ - var globalMessage = [docstringStart+"\n * Attributes associated to Node types\n * @class NodeTypes \n "+docstringEnd]; - var nodes = selection.selectedNodes() - - for (var i in nodes){ - var message = [ - "Attributes present in the node : " + node.getName(nodes[i]), - "@name NodeTypes#"+ node.type(nodes[i]) - ] - message = message.concat(node.getAttrList( nodes[i], 1).map(function(x){return traceAttributes(x, nodes[i])); - message = ("\n "+docstringStart+"\n * ")+message.join("\n * ")+("\n "+docstringEnd+"\n"); - globalMessage.push(message); - } - - MessageLog.trace(globalMessage.join("\n")); -} - -function traceAttributes(attribute, theNode){ - var message = [formatAttribute(attribute, theNode)]; - if (attribute.hasSubAttributes()){ - var subattributes = attribute.getSubAttributes(); - for (var i in subattributes){ - message = message.concat(traceAttributes(subattributes[i], theNode)); - } - } - return message -} - -function formatAttribute(attr, theNode){ - var keyword = attr.fullKeyword(); - var type = attr.typeName().toLowerCase(); - var name = attr.name(); - var defaultValue = node.getTextAttr(theNode, 1, keyword).split(" ").join("_").replace(".0000", ""); - if (defaultValue == "N") defaultValue = "false"; - if (defaultValue == "Y") defaultValue = "true"; - var message = "@property {"+type+"} "+keyword.toLowerCase()+((defaultValue)?"="+defaultValue:"")+" - "+name+"." - return message; -} -*/ - -/** - * Attributes associated to Node types.
These are the types to specify when creating a node, and the corresponding usual node name when creating directly through Harmony's interface. The attributes displayed here can be set and manipulated by calling the displayed names. - * @class NodeTypes - * @hideconstructor - * @namespace - * @example - * // This is how to use this page: - * - * var myNode = $.scn.root.addNode("READ"); // This is the node type as specified for each node under the default display name. - * $.log(myNode.type) // This is how to find out the type - * - * myNode.drawing.element = "1" // Sets the drawing.element attribute to display drawing "1" - * - * myNode.drawing.element = {frameNumber: 5, "2"} // If the attribute can be animated, pass a {frameNumber, value} object to set a specific frame; - * - * myNode.attributes.drawing.element.setValue ("2", 5) // also possible to set the attribute directly. - * - * // refer to the node type on this page to find out what properties can be set with what synthax for each Node Type. - */ - -/** - * Attributes present in the node of type: 'MasterController' - * @name NodeTypes#MasterController - * @property {string} [specs_editor=" - - - - - - - -"] - Specifications. - * @property {file_editor} script_editor - . - * @property {file_editor} init_script - . - * @property {file_editor} cleanup_script - . - * @property {file_editor} ui_script - . - * @property {string} ui_data - . - * @property {file_library} files - . - * @property {generic_enum} [show_controls_mode="Normal"] - Show Controls Mode. - */ - - -/** - * Attributes present in the node of type: 'ShapeCurve' - * @name NodeTypes#Shape-Curve - * @property {bool} flattenz=true - Flatten Z. - * @property {position_3d} position1 - Position 1. - * @property {bool} position1.separate=On - Separate. - * @property {double} position1.x=0 - Pos x. - * @property {double} position1.y=0 - Pos y. - * @property {double} position1.z=0 - Pos z. - * @property {path_3d} position1.3dpath - Path. - * @property {position_3d} position2 - Left Handle Offset. - * @property {bool} position2.separate=On - Separate. - * @property {double} position2.x=0 - Pos x. - * @property {double} position2.y=-1 - Pos y. - * @property {double} position2.z=0 - Pos z. - * @property {path_3d} position2.3dpath - Path. - * @property {position_3d} position3 - Right Handle Offset. - * @property {bool} position3.separate=On - Separate. - * @property {double} position3.x=0 - Pos x. - * @property {double} position3.y=1 - Pos y. - * @property {double} position3.z=0 - Pos z. - * @property {path_3d} position3.3dpath - Path. - * @property {bool} closeshape=false - Close Shape Contour. - */ - - -/** - * Attributes present in the node of type: 'SubNodeAnimation' - * @name NodeTypes#Subnode-Animation - */ - - -/** - * Attributes present in the node of type: 'BoneModule' - * @name NodeTypes#Stick - * @property {generic_enum} [influencetype="Infinite"] - Influence Type. - * @property {double} influencefade=0.5000 - Influence Fade Radius. - * @property {bool} symmetric=true - Symmetric Ellipse of Influence. - * @property {double} transversalradius=1 - Transversal Influence Radius Left. - * @property {double} transversalradiusright=1 - Transversal Influence Radius Right. - * @property {double} longitudinalradiusbegin=1 - Longitudinal Influence Radius Begin. - * @property {double} longitudinalradius=1 - Longitudinal Influence Radius End. - * @property {double} restlength=3 - Rest Length. - * @property {double} length=3 - Length. - */ - - -/** - * Attributes present in the node of type: 'CurveModule' - * @name NodeTypes#Curve - * @property {bool} localreferential=true - Apply Parent Transformation. - * @property {generic_enum} [influencetype="Infinite"] - Influence Type. - * @property {double} influencefade=0.5000 - Influence Fade Radius. - * @property {bool} symmetric=true - Symmetric Ellipse of Influence. - * @property {double} transversalradius=1 - Transversal Influence Radius Left. - * @property {double} transversalradiusright=1 - Transversal Influence Radius Right. - * @property {double} longitudinalradiusbegin=1 - Longitudinal Influence Radius Begin. - * @property {double} longitudinalradius=1 - Longitudinal Influence Radius End. - * @property {bool} closepath=false - Close Contour. - * @property {double} restlength0=2 - Rest Length 0. - * @property {double} restingorientation0=0 - Resting Orientation 0. - * @property {position_2d} restingoffset - Resting Offset. - * @property {bool} restingoffset.separate=On - Separate. - * @property {double} restingoffset.x=6 - Pos x. - * @property {double} restingoffset.y=0 - Pos y. - * @property {double} restlength1=2 - Rest Length 1. - * @property {double} restingorientation1=0 - Resting Orientation 1. - * @property {double} length0=2 - Length 0. - * @property {double} orientation0=0 - Orientation 0. - * @property {position_2d} offset - Offset. - * @property {bool} offset.separate=On - Separate. - * @property {double} offset.x=6 - Pos x. - * @property {double} offset.y=0 - Pos y. - * @property {point_2d} offset.2dpoint - Point. - * @property {double} length1=2 - Length 1. - * @property {double} orientation1=0 - Orientation 1. - */ - - -/** - * Attributes present in the node of type: 'BendyBoneModule' - * @name NodeTypes#Bone - * @property {generic_enum} [influencetype="Infinite"] - Influence Type. - * @property {double} influencefade=0.5000 - Influence Fade Radius. - * @property {bool} symmetric=true - Symmetric Ellipse of Influence. - * @property {double} transversalradius=1 - Transversal Influence Radius Left. - * @property {double} transversalradiusright=1 - Transversal Influence Radius Right. - * @property {double} longitudinalradiusbegin=1 - Longitudinal Influence Radius Begin. - * @property {double} longitudinalradius=1 - Longitudinal Influence Radius End. - * @property {position_2d} restoffset - Rest Offset. - * @property {bool} restoffset.separate=On - Separate. - * @property {double} restoffset.x=0 - Pos x. - * @property {double} restoffset.y=0 - Pos y. - * @property {double} restorientation=0 - Rest Orientation. - * @property {double} restradius=0.5000 - Rest Radius. - * @property {double} restbias=0.4500 - Rest Bias. - * @property {double} restlength=3 - Rest Length. - * @property {position_2d} offset - Offset. - * @property {bool} offset.separate=On - Separate. - * @property {double} offset.x=0 - Pos x. - * @property {double} offset.y=0 - Pos y. - * @property {point_2d} offset.2dpoint - Point. - * @property {double} orientation=0 - Orientation. - * @property {double} radius=0.5000 - Radius. - * @property {double} bias=0.4500 - Bias. - * @property {double} length=3 - Length. - */ - - -/** - * Attributes present in the node of type: 'ShapeRender' - * @name NodeTypes#Shape-Render - * @property {generic_enum} [edgetype="Hard Edge"] - Edge Type. - * @property {double} scale=25 - Scale. - * @property {double} discretizationscale=5 - Discretization Scale. - * @property {double} preblur=0 - Pre-Blur. - * @property {double} postblur=0 - Post-Blur. - */ - - -/** - * Attributes present in the node of type: 'NormalFloat' - * @name NodeTypes#Normal-Map-Converter - * @property {generic_enum} [conversiontype="Genarts"] - Conversion Type. - * @property {double} offset=0 - Offset. - * @property {double} length=1 - Length. - * @property {bool} invertred=false - Invert Red. - * @property {bool} invertgreen=false - Invert Green. - * @property {bool} invertblue=false - Invert Blue. - */ - - -/** - * Attributes present in the node of type: 'GameBoneModule' - * @name NodeTypes#Game-Bone - * @property {position_2d} restoffset - Rest Offset. - * @property {bool} restoffset.separate=On - Separate. - * @property {double} restoffset.x=0 - Pos x. - * @property {double} restoffset.y=0 - Pos y. - * @property {double} restorientation=0 - Rest Orientation. - * @property {double} restradius=0.5000 - Rest Radius. - * @property {double} restbias=0.4500 - Rest Bias. - * @property {double} restlength=3 - Rest Length. - * @property {position_2d} offset - Offset. - * @property {bool} offset.separate=On - Separate. - * @property {double} offset.x=0 - Pos x. - * @property {double} offset.y=0 - Pos y. - * @property {point_2d} offset.2dpoint - Point. - * @property {double} orientation=0 - Orientation. - * @property {double} radius=0.5000 - Radius. - * @property {double} bias=0.4500 - Bias. - * @property {double} length=3 - Length. - */ - - -/** - * Attributes present in the node of type: 'OffsetModule' - * @name NodeTypes#Offset - * @property {bool} localreferential=true - Apply Parent Transformation. - * @property {position_2d} restingoffset - Resting Offset. - * @property {bool} restingoffset.separate=On - Separate. - * @property {double} restingoffset.x=1 - Pos x. - * @property {double} restingoffset.y=0 - Pos y. - * @property {double} restingorientation=0 - Resting Orientation. - * @property {position_2d} offset - Offset. - * @property {bool} offset.separate=On - Separate. - * @property {double} offset.x=1 - Pos x. - * @property {double} offset.y=0 - Pos y. - * @property {point_2d} offset.2dpoint - Point. - * @property {double} orientation=0 - Orientation. - */ - - -/** - * Attributes present in the node of type: 'ArticulationModule' - * @name NodeTypes#Articulation - * @property {generic_enum} [influencetype="Infinite"] - Influence Type. - * @property {double} influencefade=0.5000 - Influence Fade Radius. - * @property {bool} symmetric=true - Symmetric Ellipse of Influence. - * @property {double} transversalradius=1 - Transversal Influence Radius Left. - * @property {double} transversalradiusright=1 - Transversal Influence Radius Right. - * @property {double} longitudinalradiusbegin=1 - Longitudinal Influence Radius Begin. - * @property {double} longitudinalradius=1 - Longitudinal Influence Radius End. - * @property {double} restradius=0.5000 - Rest Radius. - * @property {double} restingorientation=0 - Resting Orientation. - * @property {double} restbias=0.4500 - Rest Bias. - * @property {double} radius=0.5000 - Radius. - * @property {double} orientation=0 - Orientation. - * @property {double} bias=0.4500 - Bias. - */ - - -/** - * Attributes present in the node of type: 'TransformGate' - * @name NodeTypes#Transformation-Gate - * @property {double} active=100 - ACTIVE. - * @property {int} target_gate=1 - LOCAL TARGET GATE. - * @property {int} default_gate=0 - DEFAULT GATE. - */ - - -/** - * Attributes present in the node of type: 'ParticleBaker' - * @name NodeTypes#Particle-Baker - * @property {int} maxnumparticles=10000 - Maximum Number of Particles. - * @property {generic_enum} [simulationquality="Normal"] - Simulation Quality. - * @property {int} seed=0 - Seed. - * @property {int} transientframes=0 - Number of Pre-roll Frames. - * @property {bool} moveage=false - Age Particles. - * @property {bool} moveposition=true - Move Position. - * @property {bool} moveangle=false - Move Angle. - * @property {bool} roundage=false - Round Particle Age. - */ - - -/** - * Attributes present in the node of type: 'KinematicOutputModule' - * @name NodeTypes#Kinematic-Output - */ - - -/** - * Attributes present in the node of type: 'ParticleVisualizer' - * @name NodeTypes#Particle-Visualizer - * @property {bool} forcedots=false - Force to Render as Dots. - * @property {generic_enum} [sortingstrategy="Back to Front"] - Rendering Order. - * @property {bool} fixalpha=true - Fix Output Alpha. - * @property {bool} useviewscaling=true - Scale Particle System Using Parent Peg. - * @property {double} globalsize=1 - Global Scaling Factor. - */ - - -/** - * Attributes present in the node of type: 'FreeFormDeformation' - * @name NodeTypes#Free-Form-Deformer - * @property {generic_enum} [deformationquality="Very High"] - Deformation Quality. - */ - - -/** - * Attributes present in the node of type: 'ComputeNormals' - * @name NodeTypes#Normal-Map - * @property {string} objectlist - Volume Creation. - * @property {bool} depthinblue=false - Output Elevation in Blue Channel. - * @property {double} blurscale=1 - Bevel Multiplier. - * @property {bool} clipblurredwithgeometry=true - Clip Blurred Image with Geometry. - * @property {double} elevationscale=1 - Elevation Multiplier. - * @property {double} elevationsmoothness=1 - Elevation Smoothness Multiplier. - * @property {bool} generatenormals=true - Generate Normals. - * @property {generic_enum} [normalquality="Low"] - Normal Map Quality. - * @property {bool} usetruckfactor=false - Consider Truck Factor. - * @property {string} colorinformation - Colour Information. - */ - - -/** - * Attributes present in the node of type: 'PointConstraint3' - * @name NodeTypes#Three-Points-Constraints - * @property {double} active=100 - Active. - * @property {generic_enum} [flattentype="Allow 3D Transform"] - Flatten Type. - * @property {generic_enum} [transformtype="Translate"] - Transform Type. - * @property {generic_enum} [primaryport="Right"] - Primary Port. - */ - - -/** - * Attributes present in the node of type: 'GROUP' - * @name NodeTypes#Group - * @property {string} [editor=" - - - - - - - - - - - - - -"] - . - * @property {string} target_composite - Target Composite. - * @property {string} timeline_module - Substitute Node in Timeline. - * @property {bool} mask=false - Mask Flag. - * @property {bool} publish_to_parents=true - Publish to Parent Groups. - */ - - -/** - * Attributes present in the node of type: 'ComputeWorld' - * @name NodeTypes#Surface-Map - * @property {string} objectlist - Volume Creation. - * @property {double} blurscale=1 - Bevel Multiplier. - * @property {bool} clipblurredwithgeometry=true - Clip Blurred Image with Geometry. - * @property {double} elevationscale=1 - Elevation Multiplier. - * @property {double} elevationsmoothness=1 - Elevation Smoothness Multiplier. - * @property {bool} usetruckfactor=false - Consider Truck Factor. - * @property {string} colorinformation - Colour Information. - */ - - -/** - * Attributes present in the node of type: 'FOCUS_SET' - * @name NodeTypes#Focus - * @property {bool} mirror=true - Mirror. - * @property {double} ratio=2 - Mirror Front/Back Ratio. - * @property {simple_bezier} radius=(Curve) - Radius. - * @property {generic_enum} [quality="High"] - Quality. - */ - - -/** - * Attributes present in the node of type: 'SCRIPT_MODULE' - * @name NodeTypes#ScriptModule - * @property {string} [specs_editor=" - - - - - - - -"] - Specifications. - * @property {file_editor} script_editor - . - * @property {file_editor} init_script - . - * @property {file_editor} cleanup_script - . - * @property {file_editor} ui_script - . - * @property {string} ui_data - . - * @property {file_library} files - . - */ - - -/** - * Attributes present in the node of type: 'StaticConstraint' - * @name NodeTypes#Static-Transformation - * @property {push_button} bakeattr - Bake Immediate Parent's Transformation. - * @property {push_button} bakeattr_all - Bake All Incoming Transformations. - * @property {bool} active=false - Active. - * @property {position_3d} translate - Translate. - * @property {bool} translate.separate=On - Separate. - * @property {double} translate.x=0 - Pos x. - * @property {double} translate.y=0 - Pos y. - * @property {double} translate.z=0 - Pos z. - * @property {scale_3d} scale - Skew. - * @property {bool} scale.separate=On - Separate. - * @property {bool} scale.in_fields=Off - In fields. - * @property {doublevb} scale.xy=1 - Scale. - * @property {doublevb} scale.x=1 - Scale x. - * @property {doublevb} scale.y=1 - Scale y. - * @property {doublevb} scale.z=1 - Scale z. - * @property {rotation_3d} rotate - Rotate. - * @property {bool} rotate.separate=On - Separate. - * @property {doublevb} rotate.anglex=0 - Angle_x. - * @property {doublevb} rotate.angley=0 - Angle_y. - * @property {doublevb} rotate.anglez=0 - Angle_z. - * @property {double} skewx=0 - Skew X. - * @property {double} skewy=0 - Skew Y. - * @property {double} skewz=0 - Skew Z. - * @property {bool} inverted=false - Invert Transformation. - */ - - -/** - * Attributes present in the node of type: 'GLCacheLock' - * @name NodeTypes#OpenGL-Cache-Lock - * @property {bool} composite_3d=false - 3D. - */ - - -/** - * Attributes present in the node of type: 'PLUGIN' - * @name NodeTypes#Brightness-Contrast - * @property {double} b=0 - Brightness. - * @property {double} c=0 - Contrast. - */ - - -/** - * Attributes present in the node of type: 'PLUGIN' - * @name NodeTypes#Sparkle - * @property {double} angle=0 - Start angle. - * @property {double} scale=1 - Scale. - * @property {double} factor=0.7500 - Factor. - * @property {double} density=50 - Density. - * @property {int} n_points=8 - Number of Points. - * @property {double} prob_app=100 - Probability of Appearing. - * @property {double} point_noise=0 - Point Noise. - * @property {double} center_noise=0 - Center Noise. - * @property {double} angle_noise=0 - Angle Noise. - * @property {int} seed=0 - Random Seed. - * @property {bool} use_drawing_color=true - Use Drawing Colours. - * @property {bool} flatten_sparkles_of_same_color=true - Flatten Sparkles of Same Colour. - * @property {color} sparkle_color=80ffffff - Sparkles' Colour. - * @property {int} sparkle_color.red=255 - Red. - * @property {int} sparkle_color.green=255 - Green. - * @property {int} sparkle_color.blue=255 - Blue. - * @property {int} sparkle_color.alpha=128 - Alpha. - * @property {generic_enum} [sparkle_color.preferred_ui="Separate"] - Preferred Editor. - */ - - -/** - * Attributes present in the node of type: 'WeightedDeform' - * @name NodeTypes#Weighted-Deform - * @property {double} blend=0 - Pre-Blend Amount. - * @property {double} postblend=0 - Post-Blend Amount. - * @property {generic_enum} [deformationquality="Very High"] - Deformation Quality. - */ - - -/** - * Attributes present in the node of type: 'BurnIn' - * @name NodeTypes#Burn-In - * @property {bool} drawbackgroundbox=false - Add background box. - * @property {color} textcolor=ffffffff - Text colour. - * @property {int} textcolor.red=255 - Red. - * @property {int} textcolor.green=255 - Green. - * @property {int} textcolor.blue=255 - Blue. - * @property {int} textcolor.alpha=255 - Alpha. - * @property {generic_enum} [textcolor.preferred_ui="Separate"] - Preferred Editor. - * @property {color} backgroundcolor=ff000000 - Background colour. - * @property {int} backgroundcolor.red=0 - Red. - * @property {int} backgroundcolor.green=0 - Green. - * @property {int} backgroundcolor.blue=0 - Blue. - * @property {int} backgroundcolor.alpha=255 - Alpha. - * @property {generic_enum} [backgroundcolor.preferred_ui="Separate"] - Preferred Editor. - * @property {int} size=36 - Size. - * @property {int} frameoffset=0 - Frame Offset. - * @property {bool} drawframenumber=true - Frame Number. - * @property {bool} drawtimecode=true - Time code. - * @property {string} [printinfo="Environment %e Job %j Scene %s"] - Scene Name. - * @property {generic_enum} [alignment="Left"] - Alignment. - * @property {int} font=Arial - Font. - */ - - -/** - * Attributes present in the node of type: 'TransformLimit' - * @name NodeTypes#Transformation-Limit - * @property {double} active=100 - Active. - * @property {generic_enum} [switchtype="Active Value"] - Switch Effects. - * @property {double} tx=100 - Translate X. - * @property {double} ty=100 - Translate Y. - * @property {double} tz=100 - Translate Z. - * @property {double} rot=100 - Rotate. - * @property {double} skew=100 - Skew. - * @property {double} sx=100 - Scale X. - * @property {double} sy=100 - Scale Y. - * @property {bool} allowflip=true - Allow Flipping. - * @property {bool} uniformscale=false - Uniform Scale. - * @property {double} pignore=0 - Ignore Parents. - * @property {string} parentname - Parent's Name. - * @property {generic_enum} [flattentype="Allow 3D Translate"] - Flatten Type. - * @property {generic_enum} [skewtype="Skew Optimized for Rotation"] - Skew Type. - * @property {generic_enum} [flipaxis="Allow Flip on X-Axis"] - Flip Axis. - * @property {position_2d} pos - Control Position. - * @property {bool} pos.separate=On - Separate. - * @property {double} pos.x=0 - Pos x. - * @property {double} pos.y=0 - Pos y. - * @property {point_2d} pos.2dpoint - Point. - */ - - -/** - * Attributes present in the node of type: 'SCRIPT_MODULE' - * @name NodeTypes#Maya-Batch-Render - * @property {string} [specs_editor=" - - - - - - - - - -"] - Specifications. - * @property {file_editor} script_editor - . - * @property {file_editor} init_script - . - * @property {file_editor} cleanup_script - . - * @property {file_editor} ui_script - . - * @property {string} ui_data - . - * @property {file_library} files - . - * @property {string} renderer - renderer. - */ - - -/** - * Attributes present in the node of type: 'FIELD_CHART' - * @name NodeTypes#Field-Chart - * @property {bool} enable_3d=false - Enable 3D. - * @property {bool} face_camera=false - Face Camera. - * @property {generic_enum} [camera_alignment="None"] - Camera Alignment. - * @property {position_3d} offset - Position. - * @property {bool} offset.separate=On - Separate. - * @property {double} offset.x=0 - Pos x. - * @property {double} offset.y=0 - Pos y. - * @property {double} offset.z=0 - Pos z. - * @property {path_3d} offset.3dpath - Path. - * @property {scale_3d} scale - Scale. - * @property {bool} scale.separate=On - Separate. - * @property {bool} scale.in_fields=Off - In fields. - * @property {doublevb} scale.xy=1 - Scale. - * @property {doublevb} scale.x=1 - Scale x. - * @property {doublevb} scale.y=1 - Scale y. - * @property {doublevb} scale.z=1 - Scale z. - * @property {rotation_3d} rotation - Rotation. - * @property {bool} rotation.separate=Off - Separate. - * @property {doublevb} rotation.anglex=0 - Angle_x. - * @property {doublevb} rotation.angley=0 - Angle_y. - * @property {doublevb} rotation.anglez=0 - Angle_z. - * @property {quaternion_path} rotation.quaternionpath - Quaternion. - * @property {alias} angle=0 - Angle. - * @property {double} skew=0 - Skew. - * @property {position_3d} pivot - Pivot. - * @property {bool} pivot.separate=On - Separate. - * @property {double} pivot.x=0 - Pos x. - * @property {double} pivot.y=0 - Pos y. - * @property {double} pivot.z=0 - Pos z. - * @property {position_3d} spline_offset - Spline Offset. - * @property {bool} spline_offset.separate=On - Separate. - * @property {double} spline_offset.x=0 - Pos x. - * @property {double} spline_offset.y=0 - Pos y. - * @property {double} spline_offset.z=0 - Pos z. - * @property {bool} ignore_parent_peg_scaling=false - Ignore Parent Scaling. - * @property {bool} disable_field_rendering=false - Disable Field Rendering. - * @property {int} depth=0 - Depth. - * @property {bool} enable_min_max_angle=false - Enable Min/Max Angle. - * @property {double} min_angle=-360 - Min Angle. - * @property {double} max_angle=360 - Max Angle. - * @property {bool} nail_for_children=false - Nail for Children. - * @property {bool} ik_hold_orientation=false - Hold Orientation in IK. - * @property {bool} ik_hold_x=false - Hold X in IK. - * @property {bool} ik_hold_y=false - Hold Y in IK. - * @property {bool} ik_excluded=false - Is Excluded from IK. - * @property {bool} ik_can_rotate=true - Can Rotate during IK. - * @property {bool} ik_can_translate_x=false - Can Translate in X during IK. - * @property {bool} ik_can_translate_y=false - Can Translate in Y during IK. - * @property {double} ik_bone_x=0.2000 - X Direction of Bone. - * @property {double} ik_bone_y=0 - Y Direction of Bone. - * @property {double} ik_stiffness=1 - Stiffness of Bone. - * @property {drawing} drawing - Drawing. - * @property {bool} drawing.element_mode=On - Element Mode. - * @property {element} drawing.element=unknown - Element. - * @property {string} drawing.element.layer - Layer. - * @property {custom_name} drawing.custom_name - Custom Name. - * @property {string} drawing.custom_name.name - Local Name. - * @property {timing} drawing.custom_name.timing - Timing. - * @property {string} drawing.custom_name.extension=tga - Extension. - * @property {double} drawing.custom_name.field_chart=12 - FieldChart. - * @property {bool} read_overlay=true - Overlay Art Enabled. - * @property {bool} read_line_art=true - Line Art Enabled. - * @property {bool} read_color_art=true - Colour Art Enabled. - * @property {bool} read_underlay=true - Underlay Art Enabled. - * @property {generic_enum} [overlay_art_drawing_mode="Vector"] - Overlay Art Type. - * @property {generic_enum} [line_art_drawing_mode="Vector"] - Line Art Type. - * @property {generic_enum} [color_art_drawing_mode="Vector"] - Colour Art Type. - * @property {generic_enum} [underlay_art_drawing_mode="Vector"] - Underlay Art Type. - * @property {bool} pencil_line_deformation_preserve_thickness=false - Preserve Line Thickness. - * @property {generic_enum} [pencil_line_deformation_quality="Low"] - Pencil Lines Quality. - * @property {int} pencil_line_deformation_smooth=1 - Pencil Lines Smoothing. - * @property {double} pencil_line_deformation_fit_error=3 - Fit Error. - * @property {bool} read_color=true - Colour. - * @property {bool} read_transparency=true - Transparency. - * @property {generic_enum} [color_transformation="Linear"] - Colour Space. - * @property {string} color_space - Colour Space. - * @property {generic_enum} [apply_matte_to_color="Premultiplied with Black"] - Transparency Type. - * @property {bool} enable_line_texture=true - Enable Line Texture. - * @property {generic_enum} [antialiasing_quality="Medium"] - Antialiasing Quality. - * @property {double} antialiasing_exponent=1 - Antialiasing Exponent. - * @property {double} opacity=100 - Opacity. - * @property {generic_enum} [texture_filter="Nearest (Filtered)"] - Texture Filter. - * @property {bool} adjust_pencil_thickness=false - Adjust Pencil Lines Thickness. - * @property {bool} normal_line_art_thickness=true - Normal Thickness. - * @property {generic_enum} [zoom_independent_line_art_thickness="Scale Independent"] - Scale Independent. - * @property {double} mult_line_art_thickness=1 - Proportional. - * @property {double} add_line_art_thickness=0 - Constant. - * @property {double} min_line_art_thickness=0 - Minimum. - * @property {double} max_line_art_thickness=0 - Maximum. - * @property {generic_enum} [use_drawing_pivot="Apply Embedded Pivot on Drawing Layer"] - Use Embedded Pivots. - * @property {bool} flip_hor=false - Flip Horizontal. - * @property {bool} flip_vert=false - Flip Vertical. - * @property {bool} turn_before_alignment=false - Turn Before Alignment. - * @property {bool} no_clipping=false - No Clipping. - * @property {int} x_clip_factor=0 - Clipping Factor (x). - * @property {int} y_clip_factor=0 - Clipping Factor (y). - * @property {generic_enum} [alignment_rule="Center First Page"] - Alignment Rule. - * @property {double} morphing_velo=0 - Morphing Velocity. - * @property {bool} can_animate=true - Animate Using Animation Tools. - * @property {bool} tile_horizontal=false - Tile Horizontally. - * @property {bool} tile_vertical=false - Tile Vertically. - * @property {generic_enum} [size="12"] - Size. - * @property {bool} opaque=false - Opaque. - */ - - -/** - * Attributes present in the node of type: 'READ' - * @name NodeTypes#Drawing - * @property {bool} enable_3d=false - Enable 3D. - * @property {bool} face_camera=false - Face Camera. - * @property {generic_enum} [camera_alignment="None"] - Camera Alignment. - * @property {position_3d} offset - Position. - * @property {bool} offset.separate=On - Separate. - * @property {double} offset.x=0 - Pos x. - * @property {double} offset.y=0 - Pos y. - * @property {double} offset.z=0 - Pos z. - * @property {path_3d} offset.3dpath - Path. - * @property {scale_3d} scale - Scale. - * @property {bool} scale.separate=On - Separate. - * @property {bool} scale.in_fields=Off - In fields. - * @property {doublevb} scale.xy=1 - Scale. - * @property {doublevb} scale.x=1 - Scale x. - * @property {doublevb} scale.y=1 - Scale y. - * @property {doublevb} scale.z=1 - Scale z. - * @property {rotation_3d} rotation - Rotation. - * @property {bool} rotation.separate=Off - Separate. - * @property {doublevb} rotation.anglex=0 - Angle_x. - * @property {doublevb} rotation.angley=0 - Angle_y. - * @property {doublevb} rotation.anglez=0 - Angle_z. - * @property {quaternion_path} rotation.quaternionpath - Quaternion. - * @property {alias} angle=0 - Angle. - * @property {double} skew=0 - Skew. - * @property {position_3d} pivot - Pivot. - * @property {bool} pivot.separate=On - Separate. - * @property {double} pivot.x=0 - Pos x. - * @property {double} pivot.y=0 - Pos y. - * @property {double} pivot.z=0 - Pos z. - * @property {position_3d} spline_offset - Spline Offset. - * @property {bool} spline_offset.separate=On - Separate. - * @property {double} spline_offset.x=0 - Pos x. - * @property {double} spline_offset.y=0 - Pos y. - * @property {double} spline_offset.z=0 - Pos z. - * @property {bool} ignore_parent_peg_scaling=false - Ignore Parent Scaling. - * @property {bool} disable_field_rendering=false - Disable Field Rendering. - * @property {int} depth=0 - Depth. - * @property {bool} enable_min_max_angle=false - Enable Min/Max Angle. - * @property {double} min_angle=-360 - Min Angle. - * @property {double} max_angle=360 - Max Angle. - * @property {bool} nail_for_children=false - Nail for Children. - * @property {bool} ik_hold_orientation=false - Hold Orientation in IK. - * @property {bool} ik_hold_x=false - Hold X in IK. - * @property {bool} ik_hold_y=false - Hold Y in IK. - * @property {bool} ik_excluded=false - Is Excluded from IK. - * @property {bool} ik_can_rotate=true - Can Rotate during IK. - * @property {bool} ik_can_translate_x=false - Can Translate in X during IK. - * @property {bool} ik_can_translate_y=false - Can Translate in Y during IK. - * @property {double} ik_bone_x=0.2000 - X Direction of Bone. - * @property {double} ik_bone_y=0 - Y Direction of Bone. - * @property {double} ik_stiffness=1 - Stiffness of Bone. - * @property {drawing} drawing=C:/Users/mathieuc/Documents/NewScene/elements/Drawing/Drawing-1.tvg - Drawing. - * @property {bool} drawing.element_mode=On - Element Mode. - * @property {element} drawing.element=unknown - Element. - * @property {string} drawing.element.layer - Layer. - * @property {custom_name} drawing.custom_name - Custom Name. - * @property {string} drawing.custom_name.name - Local Name. - * @property {timing} drawing.custom_name.timing - Timing. - * @property {string} drawing.custom_name.extension=tga - Extension. - * @property {double} drawing.custom_name.field_chart=12 - FieldChart. - * @property {bool} read_overlay=true - Overlay Art Enabled. - * @property {bool} read_line_art=true - Line Art Enabled. - * @property {bool} read_color_art=true - Colour Art Enabled. - * @property {bool} read_underlay=true - Underlay Art Enabled. - * @property {generic_enum} [overlay_art_drawing_mode="Vector"] - Overlay Art Type. - * @property {generic_enum} [line_art_drawing_mode="Vector"] - Line Art Type. - * @property {generic_enum} [color_art_drawing_mode="Vector"] - Colour Art Type. - * @property {generic_enum} [underlay_art_drawing_mode="Vector"] - Underlay Art Type. - * @property {bool} pencil_line_deformation_preserve_thickness=false - Preserve Line Thickness. - * @property {generic_enum} [pencil_line_deformation_quality="Low"] - Pencil Lines Quality. - * @property {int} pencil_line_deformation_smooth=1 - Pencil Lines Smoothing. - * @property {double} pencil_line_deformation_fit_error=3 - Fit Error. - * @property {bool} read_color=true - Colour. - * @property {bool} read_transparency=true - Transparency. - * @property {generic_enum} [color_transformation="Linear"] - Colour Space. - * @property {string} color_space - Colour Space. - * @property {generic_enum} [apply_matte_to_color="Premultiplied with Black"] - Transparency Type. - * @property {bool} enable_line_texture=true - Enable Line Texture. - * @property {generic_enum} [antialiasing_quality="High"] - Antialiasing Quality. - * @property {double} antialiasing_exponent=1 - Antialiasing Exponent. - * @property {double} opacity=100 - Opacity. - * @property {generic_enum} [texture_filter="Nearest (Filtered)"] - Texture Filter. - * @property {bool} adjust_pencil_thickness=false - Adjust Pencil Lines Thickness. - * @property {bool} normal_line_art_thickness=true - Normal Thickness. - * @property {generic_enum} [zoom_independent_line_art_thickness="Scale Independent"] - Scale Independent. - * @property {double} mult_line_art_thickness=1 - Proportional. - * @property {double} add_line_art_thickness=0 - Constant. - * @property {double} min_line_art_thickness=0 - Minimum. - * @property {double} max_line_art_thickness=0 - Maximum. - * @property {generic_enum} [use_drawing_pivot="Apply Embedded Pivot on Drawing Layer"] - Use Embedded Pivots. - * @property {bool} flip_hor=false - Flip Horizontal. - * @property {bool} flip_vert=false - Flip Vertical. - * @property {bool} turn_before_alignment=false - Turn Before Alignment. - * @property {bool} no_clipping=false - No Clipping. - * @property {int} x_clip_factor=0 - Clipping Factor (x). - * @property {int} y_clip_factor=0 - Clipping Factor (y). - * @property {generic_enum} [alignment_rule="Center First Page"] - Alignment Rule. - * @property {double} morphing_velo=0 - Morphing Velocity. - * @property {bool} can_animate=false - Animate Using Animation Tools. - * @property {bool} tile_horizontal=false - Tile Horizontally. - * @property {bool} tile_vertical=false - Tile Vertically. - * @property {bool} invert_matte_port=false - Invert Matte. - */ - - -/** - * Attributes present in the node of type: 'Shake' - * @name NodeTypes#Shake - * @property {double} frequency=0.3000 - Frequency. - * @property {int} octaves=2 - Octaves. - * @property {double} multiplier=0.5000 - Multiplier. - * @property {double} positionx=1 - Position X. - * @property {double} positiony=1.3300 - Position Y. - * @property {double} positionz=0.1000 - Position Z. - * @property {double} rotationx=0 - Rotation X. - * @property {double} rotationy=0 - Rotation Y. - * @property {double} rotationz=1 - Rotation Z. - * @property {double} pivotx=0 - Pivot X. - * @property {double} pivoty=0 - Pivot Y. - * @property {double} pivotz=0 - Pivot Z. - * @property {int} steps=1 - Steps. - * @property {int} seed=0 - Random Seed. - */ - - -/** - * Attributes present in the node of type: 'QUADMAP' - * @name NodeTypes#Quadmap - * @property {position_2d} src_point_1 - Source Point 1. - * @property {bool} src_point_1.separate=On - Separate. - * @property {double} src_point_1.x=-12 - Pos x. - * @property {double} src_point_1.y=12 - Pos y. - * @property {point_2d} src_point_1.2dpoint - Point. - * @property {position_2d} src_point_2 - Source Point 2. - * @property {bool} src_point_2.separate=On - Separate. - * @property {double} src_point_2.x=12 - Pos x. - * @property {double} src_point_2.y=12 - Pos y. - * @property {point_2d} src_point_2.2dpoint - Point. - * @property {position_2d} src_point_3 - Source Point 3. - * @property {bool} src_point_3.separate=On - Separate. - * @property {double} src_point_3.x=-12 - Pos x. - * @property {double} src_point_3.y=-12 - Pos y. - * @property {point_2d} src_point_3.2dpoint - Point. - * @property {position_2d} src_point_4 - Source Point 4. - * @property {bool} src_point_4.separate=On - Separate. - * @property {double} src_point_4.x=12 - Pos x. - * @property {double} src_point_4.y=-12 - Pos y. - * @property {point_2d} src_point_4.2dpoint - Point. - * @property {position_2d} point_1 - Destination Point 1. - * @property {bool} point_1.separate=On - Separate. - * @property {double} point_1.x=-12 - Pos x. - * @property {double} point_1.y=12 - Pos y. - * @property {point_2d} point_1.2dpoint - Point. - * @property {position_2d} point_2 - Destination Point 2. - * @property {bool} point_2.separate=On - Separate. - * @property {double} point_2.x=12 - Pos x. - * @property {double} point_2.y=12 - Pos y. - * @property {point_2d} point_2.2dpoint - Point. - * @property {position_2d} point_3 - Destination Point 3. - * @property {bool} point_3.separate=On - Separate. - * @property {double} point_3.x=-12 - Pos x. - * @property {double} point_3.y=-12 - Pos y. - * @property {point_2d} point_3.2dpoint - Point. - * @property {position_2d} point_4 - Destination Point 4. - * @property {bool} point_4.separate=On - Separate. - * @property {double} point_4.x=12 - Pos x. - * @property {double} point_4.y=-12 - Pos y. - * @property {point_2d} point_4.2dpoint - Point. - * @property {position_2d} pivot - Pivot. - * @property {bool} pivot.separate=On - Separate. - * @property {double} pivot.x=0 - Pos x. - * @property {double} pivot.y=0 - Pos y. - */ - - -/** - * Attributes present in the node of type: 'RADIALBLUR-PLUGIN' - * @name NodeTypes#Blur-Radial-Zoom - * @property {bool} invert_matte_port=false - Invert Matte. - * @property {bool} truck_factor=true - Truck Factor. - * @property {bool} bidirectional=true - Bidirectional. - * @property {generic_enum} [precision="Medium 8"] - Precision. - * @property {double} blurriness=0 - Blurriness. - * @property {double} fall_off=0 - Fall Off. - * @property {double} spiral=0 - Custom. - * @property {position_2d} focus - Focus. - * @property {bool} focus.separate=On - Separate. - * @property {double} focus.x=0 - Pos x. - * @property {double} focus.y=0 - Pos y. - * @property {point_2d} focus.2dpoint - Point. - * @property {generic_enum} [smoothness="Quadratic"] - Variation. - * @property {double} quality=1 - Quality. - * @property {bool} legacy=false - Legacy. - */ - - -/** - * Attributes present in the node of type: 'CAMERA' - * @name NodeTypes#Camera - * @property {position_3d} offset - Offset. - * @property {bool} offset.separate=On - Separate. - * @property {double} offset.x=0 - Pos x. - * @property {double} offset.y=0 - Pos y. - * @property {double} offset.z=12 - Pos z. - * @property {position_2d} pivot - Pivot. - * @property {bool} pivot.separate=On - Separate. - * @property {double} pivot.x=0 - Pos x. - * @property {double} pivot.y=0 - Pos y. - * @property {doublevb} angle=0 - Angle. - * @property {bool} override_scene_fov=false - Override Scene Fov. - * @property {doublevb} fov=41.1121 - FOV. - * @property {double} near_plane=0.1000 - Near Plane. - * @property {double} far_plane=1000 - Far Plane. - */ - - -/** - * Attributes present in the node of type: 'COMPOSITE' - * @name NodeTypes#Composite - * @property {generic_enum} [composite_mode="Pass Through"] - Mode. - * @property {bool} flatten_output=false - Flatten Output. - * @property {bool} flatten_vector=false - Vector Flatten Output. - * @property {bool} composite_2d=false - 2D. - * @property {bool} composite_3d=false - 3D. - * @property {generic_enum} [output_z="Leftmost"] - Output Z. - * @property {int} output_z_input_port=1 - Port For Output Z. - * @property {bool} apply_focus=true - Apply Focus. - * @property {double} multiplier=1 - Focus Multiplier. - * @property {string} tvg_palette=compositedPalette - Palette Name. - * @property {bool} merge_vector=false - Flatten. - */ - - -/** - * Attributes present in the node of type: 'CastShadow' - * @name NodeTypes#Cast-Shadow - * @property {generic_enum} [lighttype="Point"] - Light Type. - * @property {generic_enum} [shadetype="Smooth"] - Shading Type. - * @property {double} anglebias=0 - Angle Bias. - * @property {double} shadowdarkness=100 - Shadow Darkness. - * @property {double} shadowlength=0 - Shadow Length. - * @property {double} shadowbias=0 - Shadow Bias. - * @property {int} samplecount=1 - Sample Count. - * @property {double} samplesize=0.5000 - Sample Size. - * @property {int} softcount=1 - Soft Shadow Sample Count. - * @property {double} softsize=1 - Soft Shadow Sample Size. - * @property {double} softweight=1 - Soft Shadow Weight. - * @property {double} postblur=0 - Final Blur. - * @property {double} postblurthreshold=0 - Final Blur Threshold. - * @property {double} shadownoise=0 - Shadow Noise. - * @property {int} expandsource=0 - Expand Render Source. - * @property {double} shadowgamma=1 - Shadow Gamma. - * @property {int} antialiasbias=1 - Anti-Alias Bias. - * @property {int} antialiasblend=1 - Anti-Alias Blend. - * @property {int} antialiasblur=1 - Anti-Alias Blur. - * @property {double} exponent=2 - Abruptness. - * @property {color} color=ff000000 - Light Colour. - * @property {int} color.red=0 - Red. - * @property {int} color.green=0 - Green. - * @property {int} color.blue=0 - Blue. - * @property {int} color.alpha=255 - Alpha. - * @property {generic_enum} [color.preferred_ui="Separate"] - Preferred Editor. - * @property {bool} useimagecolor=false - Use Image Colour. - * @property {double} imagecolorweight=50 - Image Colour Intensity. - * @property {bool} usetruckfactor=true - Consider Truck Factor. - * @property {bool} polarmethod=false - Use Polar Method. - * @property {bool} invert_matte_port=false - Invert Matte. - */ - - -/** - * Attributes present in the node of type: 'PRECOMP' - * @name NodeTypes#Pre-render-Cache - * @property {generic_enum} [composite_mode="As Bitmap"] - Mode. - * @property {bool} flatten_output=true - Flatten Output. - * @property {bool} flatten_vector=false - Vector Flatten Output. - * @property {bool} composite_2d=false - 2D. - * @property {bool} composite_3d=false - 3D. - * @property {generic_enum} [output_z="Leftmost"] - Output Z. - * @property {int} output_z_input_port=1 - Port For Output Z. - * @property {bool} apply_focus=true - Apply Focus. - * @property {double} multiplier=1 - Focus Multiplier. - * @property {string} tvg_palette=compositedPalette - Palette Name. - * @property {bool} merge_vector=false - Flatten. - * @property {bool} prerender_current_frame=false - Current Frame. - * @property {bool} prerender_selected_frames=false - Selected Frames. - * @property {int} prerender_frames_from=1 - From. - * @property {int} prerender_frames_to=1 - To. - * @property {push_button} render_prerender_cache - Render. - * @property {push_button} clear_prerender_cache - Clear. - */ - - -/** - * Attributes present in the node of type: 'MATTE_COMPOSITE' - * @name NodeTypes#Matte-Composite - */ - - -/** - * Attributes present in the node of type: 'TransformationSwitch' - * @name NodeTypes#Transformation-Switch - * @property {drawing} drawing - Drawing. - * @property {bool} drawing.element_mode=On - Element Mode. - * @property {element} drawing.element=unknown - Element. - * @property {string} drawing.element.layer - Layer. - * @property {custom_name} drawing.custom_name - Custom Name. - * @property {string} drawing.custom_name.name - Local Name. - * @property {timing} drawing.custom_name.timing - Timing. - * @property {string} drawing.custom_name.extension=tga - Extension. - * @property {double} drawing.custom_name.field_chart=12 - FieldChart. - * @property {array_string} transformationnames=2;; - Transformation Names. - * @property {int} transformationnames.size=2 - Size. - * @property {string} transformationnames.transformation_1 - Transformation 1. - * @property {string} transformationnames.transformation_2 - Transformation 2. - */ - - -/** - * Attributes present in the node of type: 'MOTION_BLUR' - * @name NodeTypes#Motion-Blur-Legacy - * @property {double} nb_frames_trail=10 - Number of Frames in the Trail. - * @property {double} samples=200 - Number of Samples. - * @property {double} falloff=2 - Fall-off Rate. - * @property {double} intensity=1 - Intensity. - * @property {bool} mirror=false - Use Mirror on Edges. - */ - - -/** - * Attributes present in the node of type: 'BLUR_VARIABLE' - * @name NodeTypes#Blur-Variable - * @property {bool} invert_matte_port=false - Invert Matte. - * @property {double} black_radius=0 - Black radius. - * @property {double} white_radius=0 - White radius. - * @property {generic_enum} [quality="High"] - Quality. - * @property {bool} keep_inside_source_image=false - Keep inside source image. - */ - - -/** - * Attributes present in the node of type: 'LAYER_SELECTOR' - * @name NodeTypes#Layer-Selector - * @property {bool} flatten=false - Flatten. - * @property {bool} apply_to_matte_ports=false - Apply to Matte Ports on Input Effects. - * @property {generic_enum} [antialiasing_quality="Ignore"] - Antialiasing Quality. - * @property {double} antialiasing_exponent=1 - Antialiasing Exponent. - * @property {bool} read_overlay=false - Read Overlay. - * @property {bool} read_lineart=true - Read LineArt. - * @property {bool} read_colourart=true - Read ColourArt. - * @property {bool} read_underlay=false - Read Underlay. - */ - - -/** - * Attributes present in the node of type: 'MOTIONBLUR-PLUGIN' - * @name NodeTypes#Motion-Blur - * @property {double} nb_frames_trail=1 - Duration (Number of Frames). - * @property {int} samples=30 - Samples per Frame. - * @property {double} falloff=0 - Fall-off Rate. - * @property {bool} use_camera_transformation=false - Use Camera Motion. - * @property {bool} preroll_motion=true - Preroll Motion. - */ - - -/** - * Attributes present in the node of type: 'COLOR_CARD' - * @name NodeTypes#Colour-Card - * @property {int} depth=0 - Depth. - * @property {double} offset_z=-12 - Offset Z. - * @property {color} color=ffffffff - Color. - * @property {int} color.red=255 - Red. - * @property {int} color.green=255 - Green. - * @property {int} color.blue=255 - Blue. - * @property {int} color.alpha=255 - Alpha. - * @property {generic_enum} [color.preferred_ui="Separate"] - Preferred Editor. - * @property {bool} invert_matte_port=false - Invert Matte. - */ - - -/** - * Attributes present in the node of type: 'TransformLoop' - * @name NodeTypes#Transform-Loop - * @property {bool} autorange=true - Automatic Range Detection. - * @property {int} rangestart=1 - Start. - * @property {int} rangeend=1 - End. - * @property {generic_enum} [looptype="Repeat"] - Loop Type. - */ - - -/** - * Attributes present in the node of type: 'COLOR_MASK' - * @name NodeTypes#Channel-Selector - * @property {bool} red=true - Red. - * @property {bool} green=true - Green. - * @property {bool} blue=true - Blue. - * @property {bool} alpha=true - Alpha. - * @property {bool} invert_matte_port=false - Invert Matte. - */ - - -/** - * Attributes present in the node of type: 'SCALE' - * @name NodeTypes#Scale-Output - * @property {bool} by_value=true - Custom Resolution. - * @property {string} resolution_name - Resolution Name. - * @property {int} res_x=720 - Width. - * @property {int} res_y=540 - Height. - */ - - -/** - * Attributes present in the node of type: 'COLOR_LEVELS' - * @name NodeTypes#Colour-Levels - * @property {levels-channel-params-attribute} rgb - RGB. - * @property {double} rgb.input_black=0 - Input Black. - * @property {double} rgb.input_white=1 - Input White. - * @property {double} rgb.gamma=1 - Gamma. - * @property {double} rgb.output_black=0 - Output Black. - * @property {double} rgb.output_white=1 - Output White. - * @property {levels-channel-params-attribute} red - Red. - * @property {double} red.input_black=0 - Input Black. - * @property {double} red.input_white=1 - Input White. - * @property {double} red.gamma=1 - Gamma. - * @property {double} red.output_black=0 - Output Black. - * @property {double} red.output_white=1 - Output White. - * @property {levels-channel-params-attribute} green - Green. - * @property {double} green.input_black=0 - Input Black. - * @property {double} green.input_white=1 - Input White. - * @property {double} green.gamma=1 - Gamma. - * @property {double} green.output_black=0 - Output Black. - * @property {double} green.output_white=1 - Output White. - * @property {levels-channel-params-attribute} blue - Blue. - * @property {double} blue.input_black=0 - Input Black. - * @property {double} blue.input_white=1 - Input White. - * @property {double} blue.gamma=1 - Gamma. - * @property {double} blue.output_black=0 - Output Black. - * @property {double} blue.output_white=1 - Output White. - * @property {levels-channel-params-attribute} alpha - Alpha. - * @property {double} alpha.input_black=0 - Input Black. - * @property {double} alpha.input_white=1 - Input White. - * @property {double} alpha.gamma=1 - Gamma. - * @property {double} alpha.output_black=0 - Output Black. - * @property {double} alpha.output_white=1 - Output White. - */ - - -/** - * Attributes present in the node of type: 'COLOR_FADE' - * @name NodeTypes#Colour-Fade - * @property {double} fadefactor=100 - Fade. - * @property {generic_enum} [colorspace="RGB"] - Colour Interpolation. - * @property {generic_enum} [hueinterpolation="Linear"] - Hue Interpolation. - */ - - -/** - * Attributes present in the node of type: 'Gamma' - * @name NodeTypes#Gamma - * @property {double} rgb_gamma=1 - RGB Gamma. - * @property {double} red_gamma=1 - Red Gamma. - * @property {double} green_gamma=1 - Green Gamma. - * @property {double} blue_gamma=1 - Blue Gamma. - * @property {double} alpha_gamma=1 - Alpha Gamma. - */ - - -/** - * Attributes present in the node of type: 'DITHER' - * @name NodeTypes#Dither - * @property {double} magnitude=1 - Magnitude. - * @property {bool} correlate=false - Correlate. - * @property {bool} random=true - Random. - */ - - -/** - * Attributes present in the node of type: 'GRAIN' - * @name NodeTypes#Grain - * @property {bool} invert_matte_port=false - Invert Matte. - * @property {double} noise=0.3000 - Noise. - * @property {double} smooth=0 - Smooth. - * @property {bool} random=true - Random At Each Frame. - * @property {int} seed=0 - Seed Value. - */ - - -/** - * Attributes present in the node of type: 'ShapeLine' - * @name NodeTypes#Shape-Line - * @property {bool} flattenz=true - Flatten Z. - * @property {position_3d} position1 - Position 1. - * @property {bool} position1.separate=On - Separate. - * @property {double} position1.x=0 - Pos x. - * @property {double} position1.y=0 - Pos y. - * @property {double} position1.z=0 - Pos z. - * @property {path_3d} position1.3dpath - Path. - * @property {bool} closeshape=false - Close Shape Contour. - */ - - -/** - * Attributes present in the node of type: 'COMPOSITE_GENERIC' - * @name NodeTypes#Composite-Generic - * @property {generic_enum} [color_operation="Apply With Alpha"] - Colour Operation. - * @property {double} intensity_color_red=1 - Intensity Red. - * @property {double} intensity_color_blue=1 - Intensity Blue. - * @property {double} intensity_color_green=1 - Intensity Green. - * @property {double} opacity=100 - Opacity. - * @property {generic_enum} [alpha_operation="Apply"] - Alpha Operation. - * @property {generic_enum} [output_z="Leftmost"] - Output Z. - * @property {int} output_z_input_port=1 - Port For Output Z. - */ - - -/** - * Attributes present in the node of type: 'COLOR_ART' - * @name NodeTypes#Colour-Art - * @property {bool} flatten=false - Flatten. - * @property {bool} apply_to_matte_ports=false - Apply to Matte Ports on Input Effects. - * @property {generic_enum} [antialiasing_quality="Ignore"] - Antialiasing Quality. - * @property {double} antialiasing_exponent=1 - Antialiasing Exponent. - */ - - -/** - * Attributes present in the node of type: 'UNDERLAY' - * @name NodeTypes#Underlay-Layer - * @property {bool} flatten=false - Flatten. - * @property {bool} apply_to_matte_ports=false - Apply to Matte Ports on Input Effects. - * @property {generic_enum} [antialiasing_quality="Ignore"] - Antialiasing Quality. - * @property {double} antialiasing_exponent=1 - Antialiasing Exponent. - */ - - -/** - * Attributes present in the node of type: 'CUTTER' - * @name NodeTypes#Cutter - * @property {bool} inverted=false - Inverted. - */ - - -/** - * Attributes present in the node of type: 'FOCUS_APPLY' - * @name NodeTypes#Focus-Multiplier - * @property {double} multiplier=1 - Multiplier. - */ - - -/** - * Attributes present in the node of type: 'PEG_APPLY3' - * @name NodeTypes#Apply-Image-Transformation - */ - - -/** - * Attributes present in the node of type: 'PEG_APPLY3_V2' - * @name NodeTypes#Apply-Peg-Transformation - */ - - -/** - * Attributes present in the node of type: 'LINE_ART' - * @name NodeTypes#Line-Art - * @property {bool} flatten=false - Flatten. - * @property {bool} apply_to_matte_ports=false - Apply to Matte Ports on Input Effects. - * @property {generic_enum} [antialiasing_quality="Ignore"] - Antialiasing Quality. - * @property {double} antialiasing_exponent=1 - Antialiasing Exponent. - */ - - -/** - * Attributes present in the node of type: 'OVERLAY' - * @name NodeTypes#Overlay-Layer - * @property {bool} flatten=false - Flatten. - * @property {bool} apply_to_matte_ports=false - Apply to Matte Ports on Input Effects. - * @property {generic_enum} [antialiasing_quality="Ignore"] - Antialiasing Quality. - * @property {double} antialiasing_exponent=1 - Antialiasing Exponent. - */ - - -/** - * Attributes present in the node of type: 'AutoPatchModule' - * @name NodeTypes#Auto-Patch - */ - - -/** - * Attributes present in the node of type: 'SubNodeAnimationFilter' - * @name NodeTypes#3D-Kinematic-Output - * @property {string} sub_node_name - Subnode Name. - */ - - -/** - * Attributes present in the node of type: 'BOXBLUR-PLUGIN' - * @name NodeTypes#Blur-Box - * @property {bool} invert_matte_port=false - Invert Matte. - * @property {bool} truck_factor=true - Truck Factor. - * @property {bool} bidirectional=true - Bidirectional. - * @property {generic_enum} [precision="Medium 8"] - Precision. - * @property {bool} repeat_edge_pixels=false - Repeat Edge Pixels. - * @property {bool} directional=false - Directional. - * @property {double} angle=0 - Angle. - * @property {int} iterations=1 - Number of Iterations. - * @property {double} radius=0 - Radius. - * @property {double} width=0 - Width. - * @property {double} length=0 - Length. - * @property {double} fall_off=0 - Fall Off. - */ - - -/** - * Attributes present in the node of type: 'RGB_DIFFERENCE_KEYER' - * @name NodeTypes#RGB-Difference-Keyer - * @property {color} color=ff000000 - Colour. - * @property {int} color.red=0 - Red. - * @property {int} color.green=0 - Green. - * @property {int} color.blue=0 - Blue. - * @property {int} color.alpha=255 - Alpha. - * @property {generic_enum} [color.preferred_ui="Separate"] - Preferred Editor. - * @property {bool} pre_multiplied_alpha=true - Pre-multiplied Alpha. - * @property {double} key_difference_weighting=50 - Key Weight. - * @property {double} edge_key_threshold=0 - Background Bias. - * @property {double} key_primary_spill_reduction=0 - Spill Reduction. - * @property {double} key_low_intensity_scaled_thresh=100 - Low Intensity Threshold. - * @property {bool} blend_input_alpha=true - Blend Input Alpha. - * @property {bool} despill_matte=true - Despill Matte. - * @property {color} spill_color=ff000000 - Spill Replace Colour. - * @property {int} spill_color.red=0 - Red. - * @property {int} spill_color.green=0 - Green. - * @property {int} spill_color.blue=0 - Blue. - * @property {int} spill_color.alpha=255 - Alpha. - * @property {generic_enum} [spill_color.preferred_ui="Separate"] - Preferred Editor. - * @property {double} matte_clip_black=0 - Clip Black. - * @property {double} matte_clip_white=100 - Clip White. - * @property {bool} invert_matte=false - Invert Output Matte. - */ - - -/** - * Attributes present in the node of type: 'CHANNEL_SWAP' - * @name NodeTypes#Channel-Swap - * @property {generic_enum} [redchannelselection="Red"] - Red Channel From. - * @property {generic_enum} [greenchannelselection="Green"] - Green Channel From. - * @property {generic_enum} [bluechannelselection="Blue"] - Blue Channel From. - * @property {generic_enum} [alphachannelselection="Alpha"] - Alpha Channel From. - * @property {bool} invert_matte_port=false - Invert Matte. - */ - - -/** - * Attributes present in the node of type: 'FADE' - * @name NodeTypes#Transparency - * @property {double} transparency=50 - Transparency. - */ - - -/** - * Attributes present in the node of type: 'OGLBYPASS' - * @name NodeTypes#OpenGL-Bypass - */ - - -/** - * Attributes present in the node of type: 'NOTE' - * @name NodeTypes#Note - * @property {string} text - Text. - */ - - -/** - * Attributes present in the node of type: 'OpenGLPreview' - * @name NodeTypes#RenderPreview - * @property {generic_enum} [refreshstrategy="Current Frame Only"] - Render. - * @property {generic_enum} [scaling="Use Render Preview Setting"] - Preview Resolution. - * @property {generic_enum} [renderstrategy="Use Previously Rendered"] - Outdated Images Mode. - * @property {push_button} computeallimages - Render Frames. - */ - - -/** - * Attributes present in the node of type: 'TbdColorSelector' - * @name NodeTypes#Colour-Selector - * @property {string} selectedcolors - Selected Colours. - * @property {bool} applytomatte=false - Apply to Matte Ports on Input Effects. - */ - - -/** - * Attributes present in the node of type: 'COLOR_OVERRIDE_TVG' - * @name NodeTypes#Colour-Override - */ - - -/** - * Attributes present in the node of type: 'FLATTEN' - * @name NodeTypes#Flatten - */ - - -/** - * Attributes present in the node of type: 'DISPLAY' - * @name NodeTypes#Display - */ - - -/** - * Attributes present in the node of type: 'DynamicSpring' - * @name NodeTypes#Dynamic-Spring - * @property {double} active=100 - Active. - * @property {bool} matchexposures=false - Match Animation on Active Attribute. - * @property {double} tensionx=7 - Tension X. - * @property {double} inertiax=80 - Inertia X. - * @property {double} tensiony=7 - Tension Y. - * @property {double} inertiay=80 - Inertia Y. - * @property {double} tensionz=7 - Tension Z. - * @property {double} inertiaz=80 - Inertia Z. - * @property {double} tensionscale=7 - Tension Scale. - * @property {double} inertiascale=80 - Inertia Scale. - * @property {double} tensionskew=7 - Tension Skew. - * @property {double} inertiaskew=80 - Inertia Skew. - * @property {double} tensionrotate=7 - Tension Rotate. - * @property {double} inertiarotate=80 - Inertia Rotate. - * @property {double} pignore=0 - Ignore Parents. - * @property {string} parentname - Parent's Name. - */ - - -/** - * Attributes present in the node of type: 'WRITE' - * @name NodeTypes#Write - * @property {generic_enum} [export_to_movie="Output Drawings"] - Export to movie. - * @property {string} drawing_name=frames/final- - Drawing name. - * @property {string} movie_path=frames/output - Movie path. - * @property {string} movie_format=com.toonboom.quicktime.legacy - Movie format setting. - * @property {string} movie_audio - Movie audio settings. - * @property {string} movie_video - Movie video settings. - * @property {string} movie_videoaudio - Movie video and audio settings. - * @property {int} leading_zeros=3 - Leading zeros. - * @property {int} start=1 - Start. - * @property {string} drawing_type=TGA - Drawing type. - * @property {enable} [enabling="Always Enabled"] - Enabling. - * @property {generic_enum} [enabling.filter="Always Enabled"] - Filter. - * @property {string} enabling.filter_name - Filter name. - * @property {int} enabling.filter_res_x=720 - X resolution. - * @property {int} enabling.filter_res_y=540 - Y resolution. - * @property {bool} script_movie=false - Script Movie. - * @property {string} [script_editor="// Following code will be called at the end of Write Node rendering -// operations to create a movie file from rendered images. - -// ..."] - Movie Generation Script. - * @property {string} color_space - Colour Space. - * @property {generic_enum} [composite_partitioning="Off"] - Composite Partitioning. - * @property {double} z_partition_range=1 - Z Partition Range. - * @property {bool} clean_up_partition_folders=true - Clean up partition folders. - */ - - -/** - * Attributes present in the node of type: 'MultiLayerWrite' - * @name NodeTypes#Multi-Layer-Write - * @property {generic_enum} [export_to_movie="Output Drawings"] - Export to movie. - * @property {string} drawing_name=frames/final- - Drawing name. - * @property {string} movie_path=frames/output - Movie path. - * @property {string} movie_format=com.toonboom.quicktime.legacy - Movie format setting. - * @property {string} movie_audio - Movie audio settings. - * @property {string} movie_video - Movie video settings. - * @property {string} movie_videoaudio - Movie video and audio settings. - * @property {int} leading_zeros=3 - Leading zeros. - * @property {int} start=1 - Start. - * @property {string} drawing_type=PSD - Drawing type. - * @property {enable} [enabling="Always Enabled"] - Enabling. - * @property {generic_enum} [enabling.filter="Always Enabled"] - Filter. - * @property {string} enabling.filter_name - Filter name. - * @property {int} enabling.filter_res_x=720 - X resolution. - * @property {int} enabling.filter_res_y=540 - Y resolution. - * @property {bool} script_movie=false - Script Movie. - * @property {string} [script_editor="// Following code will be called at the end of Write Node rendering -// operations to create a movie file from rendered images. - -// ..."] - Movie Generation Script. - * @property {string} color_space - Colour Space. - * @property {generic_enum} [composite_partitioning="Off"] - Composite Partitioning. - * @property {double} z_partition_range=1 - Z Partition Range. - * @property {bool} clean_up_partition_folders=true - Clean up partition folders. - * @property {string} input_names - Input Names. - */ - - -/** - * Attributes present in the node of type: 'BLUR_DIRECTIONAL' - * @name NodeTypes#Blur-Directional - * @property {bool} invert_matte_port=false - Invert Matte. - * @property {bool} truck_factor=true - Truck Factor. - * @property {double} fallof_rate=0 - Falloff Rate. - * @property {double} angle=0 - Angle. - * @property {double} radius=0 - Radius. - * @property {generic_enum} [direction_of_trail="Angle"] - Direction of trail. - * @property {bool} ignore_alpha=false - Ignore Alpha. - * @property {bool} extra_final_blur=true - Extra Final Blur. - */ - - -/** - * Attributes present in the node of type: 'TONE' - * @name NodeTypes#Tone - * @property {bool} truck_factor=true - Truck Factor. - * @property {generic_enum} [blur_type="Radial"] - Blur Type. - * @property {double} radius=2 - Radius. - * @property {double} directional_angle=0 - Directional Angle. - * @property {double} directional_falloff_rate=1 - Directional Falloff Rate. - * @property {bool} use_matte_color=false - Use Matte Colour. - * @property {bool} invert_matte=false - Invert Matte. - * @property {color} color=649c9c9c - Color. - * @property {int} color.red=-100 - Red. - * @property {int} color.green=-100 - Green. - * @property {int} color.blue=-100 - Blue. - * @property {int} color.alpha=100 - Alpha. - * @property {generic_enum} [color.preferred_ui="Separate"] - Preferred Editor. - * @property {bool} multiplicative=false - Multiplicative. - * @property {double} colour_gain=1 - Intensity. - * @property {bool} invert_matte_port=false - Invert Matte. - */ - - -/** - * Attributes present in the node of type: 'GAUSSIANBLUR-PLUGIN' - * @name NodeTypes#Blur-Gaussian - * @property {bool} invert_matte_port=false - Invert Matte. - * @property {bool} truck_factor=true - Truck Factor. - * @property {bool} bidirectional=true - Bidirectional. - * @property {generic_enum} [precision="Medium 8"] - Precision. - * @property {bool} repeat_edge_pixels=false - Repeat Edge Pixels. - * @property {bool} directional=false - Directional. - * @property {double} angle=0 - Angle. - * @property {int} iterations=1 - Number of Iterations. - * @property {double} blurriness=0 - Blurriness. - * @property {double} vertical=0 - Vertical Blurriness. - * @property {double} horizontal=0 - Horizontal Blurriness. - */ - - -/** - * Attributes present in the node of type: 'HIGHLIGHT' - * @name NodeTypes#Highlight - * @property {bool} truck_factor=true - Truck Factor. - * @property {generic_enum} [blur_type="Radial"] - Blur Type. - * @property {double} radius=2 - Radius. - * @property {double} directional_angle=0 - Directional Angle. - * @property {double} directional_falloff_rate=1 - Directional Falloff Rate. - * @property {bool} use_matte_color=false - Use Matte Colour. - * @property {bool} invert_matte=false - Invert Matte. - * @property {color} color=64646464 - Color. - * @property {int} color.red=100 - Red. - * @property {int} color.green=100 - Green. - * @property {int} color.blue=100 - Blue. - * @property {int} color.alpha=100 - Alpha. - * @property {generic_enum} [color.preferred_ui="Separate"] - Preferred Editor. - * @property {bool} multiplicative=false - Multiplicative. - * @property {double} colour_gain=1 - Intensity. - * @property {bool} invert_matte_port=false - Invert Matte. - */ - - -/** - * Attributes present in the node of type: 'MATTE_BLUR' - * @name NodeTypes#Matte-Blur - * @property {bool} truck_factor=true - Truck Factor. - * @property {generic_enum} [blur_type="Radial"] - Blur Type. - * @property {double} radius=0 - Radius. - * @property {double} directional_angle=0 - Directional Angle. - * @property {double} directional_falloff_rate=1 - Directional Falloff Rate. - * @property {bool} use_matte_color=false - Use Matte Colour. - * @property {bool} invert_matte=false - Invert Matte. - * @property {color} color=ffffffff - Color. - * @property {int} color.red=255 - Red. - * @property {int} color.green=255 - Green. - * @property {int} color.blue=255 - Blue. - * @property {int} color.alpha=255 - Alpha. - * @property {generic_enum} [color.preferred_ui="Separate"] - Preferred Editor. - * @property {bool} multiplicative=false - Multiplicative. - * @property {double} colour_gain=1 - Intensity. - */ - - -/** - * Attributes present in the node of type: 'PEG' - * @name NodeTypes#Peg - * @property {bool} enable_3d=false - Enable 3D. - * @property {bool} face_camera=false - Face Camera. - * @property {generic_enum} [camera_alignment="None"] - Camera Alignment. - * @property {position_3d} position - Position. - * @property {bool} position.separate=On - Separate. - * @property {double} position.x=0 - Pos x. - * @property {double} position.y=0 - Pos y. - * @property {double} position.z=0 - Pos z. - * @property {path_3d} position.3dpath - Path. - * @property {scale_3d} scale - Scale. - * @property {bool} scale.separate=On - Separate. - * @property {bool} scale.in_fields=Off - In fields. - * @property {doublevb} scale.xy=1 - Scale. - * @property {doublevb} scale.x=1 - Scale x. - * @property {doublevb} scale.y=1 - Scale y. - * @property {doublevb} scale.z=1 - Scale z. - * @property {rotation_3d} rotation - Rotation. - * @property {bool} rotation.separate=Off - Separate. - * @property {doublevb} rotation.anglex=0 - Angle_x. - * @property {doublevb} rotation.angley=0 - Angle_y. - * @property {doublevb} rotation.anglez=0 - Angle_z. - * @property {quaternion_path} rotation.quaternionpath - Quaternion. - * @property {alias} angle=0 - Angle. - * @property {double} skew=0 - Skew. - * @property {position_3d} pivot - Pivot. - * @property {bool} pivot.separate=On - Separate. - * @property {double} pivot.x=0 - Pos x. - * @property {double} pivot.y=0 - Pos y. - * @property {double} pivot.z=0 - Pos z. - * @property {position_3d} spline_offset - Spline Offset. - * @property {bool} spline_offset.separate=On - Separate. - * @property {double} spline_offset.x=0 - Pos x. - * @property {double} spline_offset.y=0 - Pos y. - * @property {double} spline_offset.z=0 - Pos z. - * @property {bool} ignore_parent_peg_scaling=false - Ignore Parent Scaling. - * @property {bool} disable_field_rendering=false - Disable Field Rendering. - * @property {int} depth=0 - Depth. - * @property {bool} enable_min_max_angle=false - Enable Min/Max Angle. - * @property {double} min_angle=-360 - Min Angle. - * @property {double} max_angle=360 - Max Angle. - * @property {bool} nail_for_children=false - Nail for Children. - * @property {bool} ik_hold_orientation=false - Hold Orientation in IK. - * @property {bool} ik_hold_x=false - Hold X in IK. - * @property {bool} ik_hold_y=false - Hold Y in IK. - * @property {bool} ik_excluded=false - Is Excluded from IK. - * @property {bool} ik_can_rotate=true - Can Rotate during IK. - * @property {bool} ik_can_translate_x=false - Can Translate in X during IK. - * @property {bool} ik_can_translate_y=false - Can Translate in Y during IK. - * @property {double} ik_bone_x=0.2000 - X Direction of Bone. - * @property {double} ik_bone_y=0 - Y Direction of Bone. - * @property {double} ik_stiffness=1 - Stiffness of Bone. - * @property {bool} group_at_network_building=false - Group at Network Building. - * @property {bool} add_composite_to_group=true - Add Composite to Group. - */ - - -/** - * Attributes present in the node of type: 'GLOW' - * @name NodeTypes#Glow - * @property {bool} truck_factor=true - Truck Factor. - * @property {generic_enum} [blur_type="Radial"] - Blur Type. - * @property {double} radius=0 - Radius. - * @property {double} directional_angle=0 - Directional Angle. - * @property {double} directional_falloff_rate=1 - Directional Falloff Rate. - * @property {bool} use_matte_color=false - Use Source Colour. - * @property {bool} invert_matte=false - Invert Matte. - * @property {color} color=ff646464 - Color. - * @property {int} color.red=100 - Red. - * @property {int} color.green=100 - Green. - * @property {int} color.blue=100 - Blue. - * @property {int} color.alpha=255 - Alpha. - * @property {generic_enum} [color.preferred_ui="Separate"] - Preferred Editor. - * @property {bool} multiplicative=false - Multiplicative. - * @property {double} colour_gain=1 - Intensity. - */ - - -/** - * Attributes present in the node of type: 'BLEND_MODE_MODULE' - * @name NodeTypes#Blending - * @property {generic_enum} [blend_mode="Normal"] - Blend Mode. - * @property {generic_enum} [flash_blend_mode="Normal"] - SWF Blend Mode. - */ - - -/** - * Attributes present in the node of type: 'BLUR_RADIAL' - * @name NodeTypes#Blur - * @property {bool} invert_matte_port=false - Invert Matte. - * @property {bool} truck_factor=true - Truck Factor. - * @property {double} radius=0 - Radius. - * @property {generic_enum} [quality="High"] - Quality. - */ - - -/** - * Attributes present in the node of type: 'ImageSwitch' - * @name NodeTypes#Image-Switch - * @property {int} port_index=0 - Port Index. - */ - - -/** - * Attributes present in the node of type: 'ORTHOLOCK' - * @name NodeTypes#OrthoLock - * @property {generic_enum} [rotation_axis="X and Y Axes"] - Rotation Axis. - * @property {double} max_angle=0 - Max Angle. - */ - - -/** - * Attributes present in the node of type: 'CHROMA_KEYING' - * @name NodeTypes#Chroma-Keying - * @property {bool} invert_matte_port=false - Invert Matte. - * @property {color} color=ffffffff - Color. - * @property {int} color.red=255 - Red. - * @property {int} color.green=255 - Green. - * @property {int} color.blue=255 - Blue. - * @property {int} color.alpha=255 - Alpha. - * @property {generic_enum} [color.preferred_ui="Separate"] - Preferred Editor. - * @property {double} chroma_key_minimum=0 - Black Point. - * @property {double} chroma_key_maximum=255 - White Point. - * @property {double} chroma_key_filter_intensity=1 - Blur Passes. - * @property {double} chroma_key_sampling=2 - Adjacent Pixels per Pass. - * @property {bool} applyfinalthreshold=true - Threshold Matte. - * @property {double} finalthreshold=10 - Threshold. - * @property {bool} cutimage=true - Cut Colour. - */ - - -/** - * Attributes present in the node of type: 'Quake' - * @name NodeTypes#Quake - * @property {int} hold=1 - Hold Time. - * @property {bool} interpolate=false - Interpolate. - * @property {double} moveamplitude=1 - Move Amplitude. - * @property {bool} applyx=true - Apply on X. - * @property {bool} applyy=true - Apply on Y. - * @property {bool} applyz=true - Apply on Z. - * @property {double} rotationamplitude=0 - Rotation Amplitude. - * @property {int} seed=0 - Random Seed. - */ - - -/** - * Attributes present in the node of type: 'GRADIENT-PLUGIN' - * @name NodeTypes#Gradient - * @property {int} depth=0 - Depth. - * @property {bool} invert_matte_port=false - Invert Matte. - * @property {generic_enum} [type="Linear"] - Gradient Type. - * @property {position_2d} 0 - Position 0. - * @property {bool} 0.separate=On - Separate. - * @property {double} 0.x=0 - Pos x. - * @property {double} 0.y=12 - Pos y. - * @property {point_2d} 0.2dpoint - Point. - * @property {position_2d} 1 - Position 1. - * @property {bool} 1.separate=On - Separate. - * @property {double} 1.x=0 - Pos x. - * @property {double} 1.y=-12 - Pos y. - * @property {point_2d} 1.2dpoint - Point. - * @property {color} color0=ff000000 - Colour 0. - * @property {int} color0.red=0 - Red. - * @property {int} color0.green=0 - Green. - * @property {int} color0.blue=0 - Blue. - * @property {int} color0.alpha=255 - Alpha. - * @property {generic_enum} [color0.preferred_ui="Separate"] - Preferred Editor. - * @property {color} color1=ffffffff - Colour 1. - * @property {int} color1.red=255 - Red. - * @property {int} color1.green=255 - Green. - * @property {int} color1.blue=255 - Blue. - * @property {int} color1.alpha=255 - Alpha. - * @property {generic_enum} [color1.preferred_ui="Separate"] - Preferred Editor. - * @property {double} offset_z=0 - Offset Z. - */ - - -/** - * Attributes present in the node of type: 'BRIGHTNESS_CONTRAST' - * @name NodeTypes#BrightnessContrast - * @property {bool} invert_matte_port=false - Invert Matte. - * @property {bool} brightcontrast_legacy_brightness=false - Legacy Brightness. - * @property {double} brightcontrast_brightness_adjustment=0 - Brightness. - * @property {double} brightcontrast_contrast_adjustment=0 - Contrast. - * @property {bool} brightcontrast_legacy_contrast=false - Legacy Contrast. - */ - - -/** - * Attributes present in the node of type: 'Switch' - * @name NodeTypes#Constraint-Switch - * @property {double} active=100 - ACTIVE. - * @property {int} gatenum=0 - TARGET GATE. - * @property {position_2d} uioffsetpos - GUI OFFSET. - * @property {bool} uioffsetpos.separate=On - Separate. - * @property {double} uioffsetpos.x=0 - Pos x. - * @property {double} uioffsetpos.y=0 - Pos y. - * @property {double} uiscale=1 - GUI SCALE. - */ - - -/** - * Attributes present in the node of type: 'Grid' - * @name NodeTypes#Grid - * @property {int} size=12 - Size. - * @property {double} aspect=1.3333 - Aspect. - * @property {bool} showtext=true - Display Text. - * @property {color} gridcolor=ff000000 - Color. - * @property {int} gridcolor.red=0 - Red. - * @property {int} gridcolor.green=0 - Green. - * @property {int} gridcolor.blue=0 - Blue. - * @property {int} gridcolor.alpha=255 - Alpha. - * @property {generic_enum} [gridcolor.preferred_ui="Separate"] - Preferred Editor. - * @property {color} bgcolor=ffffffff - Color. - * @property {int} bgcolor.red=255 - Red. - * @property {int} bgcolor.green=255 - Green. - * @property {int} bgcolor.blue=255 - Blue. - * @property {int} bgcolor.alpha=255 - Alpha. - * @property {generic_enum} [bgcolor.preferred_ui="Separate"] - Preferred Editor. - * @property {bool} opaque=false - Fill. - * @property {bool} fitvertical=true - Fit Vertical. - */ - - -/** - * Attributes present in the node of type: 'Turbulence' - * @name NodeTypes#Turbulence - * @property {generic_enum} [fractal_type="Fractional Brownian"] - Fractal Type. - * @property {generic_enum} [noise_type="Perlin"] - Noise Type. - * @property {locked} frequency - Frequency. - * @property {bool} frequency.separate=Off - Separate. - * @property {doublevb} frequency.xyfrequency=1 - Frequency xy. - * @property {doublevb} frequency.xfrequency=0 - Frequency x. - * @property {doublevb} frequency.yfrequency=0 - Frequency y. - * @property {locked} amount - Amount. - * @property {bool} amount.separate=Off - Separate. - * @property {doublevb} amount.xyamount=0 - Amount xy. - * @property {doublevb} amount.xamount=0 - Amount x. - * @property {doublevb} amount.yamount=0 - Amount y. - * @property {locked} offset - Offset. - * @property {bool} offset.separate=Off - Separate. - * @property {doublevb} offset.xyoffset=0 - Offset xy. - * @property {doublevb} offset.xoffset=0 - Offset x. - * @property {doublevb} offset.yoffset=0 - Offset y. - * @property {locked} seed - Seed. - * @property {bool} seed.separate=On - Separate. - * @property {doublevb} seed.xyseed=0 - Seed xy. - * @property {doublevb} seed.xseed=10 - Seed x. - * @property {doublevb} seed.yseed=0 - Seed y. - * @property {double} evolution=0 - Evolution. - * @property {double} evolution_frequency=0 - Evolution Frequency. - * @property {double} gain=0.6500 - Gain. - * @property {double} lacunarity=2 - Sub Scaling. - * @property {double} octaves=1 - Complexity. - * @property {bool} pinning=false - Pinning. - * @property {generic_enum} [deformationquality="Medium"] - Deformation Quality. - */ - - -/** - * Attributes present in the node of type: 'PointConstraintMulti' - * @name NodeTypes#Multi-Points-Constraint - * @property {double} active=100 - Active. - * @property {generic_enum} [flattentype="Allow 3D Transform"] - Flatten Type. - * @property {bool} convexhull=false - Ignore Internal Points. - * @property {bool} allowpersp=false - Allow Perspective Transform. - */ - - -/** - * Attributes present in the node of type: 'VISIBILITY' - * @name NodeTypes#Visibility - * @property {bool} oglrender=true - Display in OpenGL View. - * @property {bool} softrender=true - Soft Render. - */ - - -/** - * Attributes present in the node of type: 'REFRACT' - * @name NodeTypes#Refract - * @property {bool} invert_matte_port=false - Invert Matte. - * @property {double} intensity=10 - Intensity. - * @property {double} height=0 - Height. - */ - - -/** - * Attributes present in the node of type: 'MULTIPORT_OUT' - * @name NodeTypes#Multi-Port-Out - */ - - -/** - * Attributes present in the node of type: 'REMOVE_TRANSPARENCY' - * @name NodeTypes#Remove-Transparency - * @property {double} threshold=50 - Threshold. - * @property {bool} remove_color_transparency=true - Remove Colour Transparency. - * @property {bool} remove_alpha_transparency=true - Remove Alpha Transparency. - */ - - -/** - * Attributes present in the node of type: 'Bloom' - * @name NodeTypes#Bloom - * @property {double} luminancethresholdthresh=75 - Threshold. - * @property {bool} luminancethresholdsoften=true - Soften Colours. - * @property {double} luminancethresholdgamma=1.5000 - Gamma Correction. - * @property {bool} luminancethresholdgrey=false - Output Greyscale Matte. - * @property {bool} invert_matte_port=false - Invert Matte. - * @property {bool} truck_factor=true - Truck Factor. - * @property {double} radius=4 - Radius. - * @property {generic_enum} [quality="High"] - Quality. - * @property {bool} composite_src_image=true - Composite with Source Image. - * @property {generic_enum} [blend_mode="Screen"] - Blend Mode. - */ - - -/** - * Attributes present in the node of type: 'MULTIPORT_IN' - * @name NodeTypes#Multi-Port-In - */ - - -/** - * Attributes present in the node of type: 'MedianFilter' - * @name NodeTypes#Median - * @property {bool} invert_matte_port=false - Invert Matte. - * @property {double} radius=0 - Radius. - * @property {int} bitdepth=256 - Colour Depth. - */ - - -/** - * Attributes present in the node of type: 'ToneShader' - * @name NodeTypes#Tone-Shader - * @property {generic_enum} [lighttype="Directional"] - Light Type. - * @property {double} floodangle=90 - Cone Angle. - * @property {double} floodsharpness=0 - Diffusion. - * @property {double} floodradius=2000 - Falloff. - * @property {double} pointelevation=200 - Light Source Elevation. - * @property {double} anglethreshold=90 - Surface Reflectivity. - * @property {generic_enum} [shadetype="Smooth"] - Shading Type. - * @property {double} bias=0.1000 - Bias. - * @property {double} exponent=2 - Abruptness. - * @property {color} lightcolor=ff646464 - Light Colour. - * @property {int} lightcolor.red=100 - Red. - * @property {int} lightcolor.green=100 - Green. - * @property {int} lightcolor.blue=100 - Blue. - * @property {int} lightcolor.alpha=255 - Alpha. - * @property {generic_enum} [lightcolor.preferred_ui="Separate"] - Preferred Editor. - * @property {bool} flatten=true - Flatten Fx. - * @property {bool} useimagecolor=false - Use image Colour. - * @property {double} imagecolorweight=50 - Image Colour Intensity. - * @property {bool} adjustlevel=false - Adjust Light Intensity. - * @property {double} adjustedlevel=75 - Intensity. - * @property {double} scale=1 - Multiplier. - * @property {bool} usesurface=false - Use Surface Lighting. - * @property {double} speculartransparency=0 - Specular Transparency. - * @property {double} specularity=100 - Specular Strength. - * @property {double} distancefalloff=0 - Distance Falloff. - */ - - -/** - * Attributes present in the node of type: 'DeformationCompositeModule' - * @name NodeTypes#Deformation-Composite - * @property {bool} outputmatrixonly=false - Output Kinematic Only. - * @property {bool} outputselectedonly=false - Output Selected Port Only. - * @property {generic_enum} [outputkinematicchainselector="Rightmost"] - Output Kinematic Chain. - * @property {int} outputkinematicchain=1 - Output Kinematic Chain Selection. - */ - - -/** - * Attributes present in the node of type: 'AnimatedMatteGenerator' - * @name NodeTypes#Animated-Matte-Generator - * @property {double} snapradius=15 - Drag-to-Snap Distance. - * @property {bool} snapoutlinesonly=false - Snap to Outlines Only. - * @property {generic_enum} [outputtype="Feathered"] - Type. - * @property {double} outputinterpolation=0 - Interpolation Factor. - * @property {color} insidecolor=ffffffff - Inside Colour. - * @property {int} insidecolor.red=255 - Red. - * @property {int} insidecolor.green=255 - Green. - * @property {int} insidecolor.blue=255 - Blue. - * @property {int} insidecolor.alpha=255 - Alpha. - * @property {generic_enum} [insidecolor.preferred_ui="Separate"] - Preferred Editor. - * @property {color} outsidecolor=ffffffff - Outside Colour. - * @property {int} outsidecolor.red=255 - Red. - * @property {int} outsidecolor.green=255 - Green. - * @property {int} outsidecolor.blue=255 - Blue. - * @property {int} outsidecolor.alpha=255 - Alpha. - * @property {generic_enum} [outsidecolor.preferred_ui="Separate"] - Preferred Editor. - * @property {generic_enum} [interpolationmode="Distance"] - Interpolation Mode. - * @property {generic_enum} [colorinterpolation="Constant"] - Colour Interpolation. - * @property {generic_enum} [alphamapping="Linear"] - Alpha Mapping. - * @property {int} colorlutdomain=100 - Colour LUT Domain. - * @property {int} alphalutdomain=100 - Alpha LUT Domain. - * @property {double} colorgamma=1 - Colour Gamma. - * @property {double} alphagamma=1 - Alpha Gamma. - * @property {double} colorlut=0 - Colour LUT. - * @property {double} alphalut=0 - Alpha LUT. - * @property {bool} snapunderlay=false - Underlay Art. - * @property {bool} snapcolor=true - Colour Art. - * @property {bool} snapline=true - Line Art. - * @property {bool} snapoverlay=false - Overlay Art. - * @property {bool} usehints=true - Enable Hints. - * @property {double} snapradiusdraghint=20 - Drag-to-Snap Distance. - * @property {double} snapradiusgeneratehint=95 - Generated Matte Snap Distance. - * @property {double} mindistancepregeneratehints=75 - Minimum Distance Between Generated Hints. - * @property {bool} snaphintunderlay=false - Underlay Art. - * @property {bool} snaphintcolor=true - Colour Art. - * @property {bool} snaphintline=false - Line Art. - * @property {bool} snaphintoverlay=false - Overlay Art. - * @property {bool} overlayisnote=true - Use Overlay Layer as Note. - * @property {string} contourcentres - Contour Centres. - */ - - -/** - * Attributes present in the node of type: 'COLOR2BW' - * @name NodeTypes#Greyscale - * @property {double} percent=100 - Percent. - * @property {bool} matte_output=false - Matte Output. - * @property {bool} invert_matte_port=false - Invert Matte. - */ - - -/** - * Attributes present in the node of type: 'CONTRAST' - * @name NodeTypes#Contrast - * @property {double} mid_point=0.5000 - Mid Point. - * @property {double} dark_pixel_adjustement=1 - Dark Pixel Adjustment. - * @property {double} bright_pixel_adjustement=1 - Bright Pixel Adjustment. - * @property {bool} invert_matte_port=false - Invert Matte. - */ - - -/** - * Attributes present in the node of type: 'COLOR_CURVES' - * @name NodeTypes#Colour-Curves - * @property {color-correction-control-point-attribute} control_point_red_0 - Control point. - * @property {position_2d} control_point_red_0.control - Control Point. - * @property {bool} control_point_red_0.control.separate=Off - Separate. - * @property {double} control_point_red_0.control.x=0 - Pos x. - * @property {double} control_point_red_0.control.y=0 - Pos y. - * @property {point_2d} control_point_red_0.control.2dpoint - Point. - * @property {position_2d} control_point_red_0.left_handle - Left Handle. - * @property {bool} control_point_red_0.left_handle.separate=Off - Separate. - * @property {double} control_point_red_0.left_handle.x=-0.1000 - Pos x. - * @property {double} control_point_red_0.left_handle.y=-0.1000 - Pos y. - * @property {point_2d} control_point_red_0.left_handle.2dpoint - Point. - * @property {position_2d} control_point_red_0.right_handle - Right Handle. - * @property {bool} control_point_red_0.right_handle.separate=Off - Separate. - * @property {double} control_point_red_0.right_handle.x=0.1000 - Pos x. - * @property {double} control_point_red_0.right_handle.y=0.1000 - Pos y. - * @property {point_2d} control_point_red_0.right_handle.2dpoint - Point. - * @property {color-correction-control-point-attribute} control_point_red_1 - Control point. - * @property {position_2d} control_point_red_1.control - Control Point. - * @property {bool} control_point_red_1.control.separate=Off - Separate. - * @property {double} control_point_red_1.control.x=1 - Pos x. - * @property {double} control_point_red_1.control.y=1 - Pos y. - * @property {point_2d} control_point_red_1.control.2dpoint - Point. - * @property {position_2d} control_point_red_1.left_handle - Left Handle. - * @property {bool} control_point_red_1.left_handle.separate=Off - Separate. - * @property {double} control_point_red_1.left_handle.x=-0.1000 - Pos x. - * @property {double} control_point_red_1.left_handle.y=-0.1000 - Pos y. - * @property {point_2d} control_point_red_1.left_handle.2dpoint - Point. - * @property {position_2d} control_point_red_1.right_handle - Right Handle. - * @property {bool} control_point_red_1.right_handle.separate=Off - Separate. - * @property {double} control_point_red_1.right_handle.x=0.1000 - Pos x. - * @property {double} control_point_red_1.right_handle.y=0.1000 - Pos y. - * @property {point_2d} control_point_red_1.right_handle.2dpoint - Point. - * @property {color-correction-control-point-attribute} control_point_green_0 - Control point. - * @property {position_2d} control_point_green_0.control - Control Point. - * @property {bool} control_point_green_0.control.separate=Off - Separate. - * @property {double} control_point_green_0.control.x=0 - Pos x. - * @property {double} control_point_green_0.control.y=0 - Pos y. - * @property {point_2d} control_point_green_0.control.2dpoint - Point. - * @property {position_2d} control_point_green_0.left_handle - Left Handle. - * @property {bool} control_point_green_0.left_handle.separate=Off - Separate. - * @property {double} control_point_green_0.left_handle.x=-0.1000 - Pos x. - * @property {double} control_point_green_0.left_handle.y=-0.1000 - Pos y. - * @property {point_2d} control_point_green_0.left_handle.2dpoint - Point. - * @property {position_2d} control_point_green_0.right_handle - Right Handle. - * @property {bool} control_point_green_0.right_handle.separate=Off - Separate. - * @property {double} control_point_green_0.right_handle.x=0.1000 - Pos x. - * @property {double} control_point_green_0.right_handle.y=0.1000 - Pos y. - * @property {point_2d} control_point_green_0.right_handle.2dpoint - Point. - * @property {color-correction-control-point-attribute} control_point_green_1 - Control point. - * @property {position_2d} control_point_green_1.control - Control Point. - * @property {bool} control_point_green_1.control.separate=Off - Separate. - * @property {double} control_point_green_1.control.x=1 - Pos x. - * @property {double} control_point_green_1.control.y=1 - Pos y. - * @property {point_2d} control_point_green_1.control.2dpoint - Point. - * @property {position_2d} control_point_green_1.left_handle - Left Handle. - * @property {bool} control_point_green_1.left_handle.separate=Off - Separate. - * @property {double} control_point_green_1.left_handle.x=-0.1000 - Pos x. - * @property {double} control_point_green_1.left_handle.y=-0.1000 - Pos y. - * @property {point_2d} control_point_green_1.left_handle.2dpoint - Point. - * @property {position_2d} control_point_green_1.right_handle - Right Handle. - * @property {bool} control_point_green_1.right_handle.separate=Off - Separate. - * @property {double} control_point_green_1.right_handle.x=0.1000 - Pos x. - * @property {double} control_point_green_1.right_handle.y=0.1000 - Pos y. - * @property {point_2d} control_point_green_1.right_handle.2dpoint - Point. - * @property {color-correction-control-point-attribute} control_point_blue_0 - Control point. - * @property {position_2d} control_point_blue_0.control - Control Point. - * @property {bool} control_point_blue_0.control.separate=Off - Separate. - * @property {double} control_point_blue_0.control.x=0 - Pos x. - * @property {double} control_point_blue_0.control.y=0 - Pos y. - * @property {point_2d} control_point_blue_0.control.2dpoint - Point. - * @property {position_2d} control_point_blue_0.left_handle - Left Handle. - * @property {bool} control_point_blue_0.left_handle.separate=Off - Separate. - * @property {double} control_point_blue_0.left_handle.x=-0.1000 - Pos x. - * @property {double} control_point_blue_0.left_handle.y=-0.1000 - Pos y. - * @property {point_2d} control_point_blue_0.left_handle.2dpoint - Point. - * @property {position_2d} control_point_blue_0.right_handle - Right Handle. - * @property {bool} control_point_blue_0.right_handle.separate=Off - Separate. - * @property {double} control_point_blue_0.right_handle.x=0.1000 - Pos x. - * @property {double} control_point_blue_0.right_handle.y=0.1000 - Pos y. - * @property {point_2d} control_point_blue_0.right_handle.2dpoint - Point. - * @property {color-correction-control-point-attribute} control_point_blue_1 - Control point. - * @property {position_2d} control_point_blue_1.control - Control Point. - * @property {bool} control_point_blue_1.control.separate=Off - Separate. - * @property {double} control_point_blue_1.control.x=1 - Pos x. - * @property {double} control_point_blue_1.control.y=1 - Pos y. - * @property {point_2d} control_point_blue_1.control.2dpoint - Point. - * @property {position_2d} control_point_blue_1.left_handle - Left Handle. - * @property {bool} control_point_blue_1.left_handle.separate=Off - Separate. - * @property {double} control_point_blue_1.left_handle.x=-0.1000 - Pos x. - * @property {double} control_point_blue_1.left_handle.y=-0.1000 - Pos y. - * @property {point_2d} control_point_blue_1.left_handle.2dpoint - Point. - * @property {position_2d} control_point_blue_1.right_handle - Right Handle. - * @property {bool} control_point_blue_1.right_handle.separate=Off - Separate. - * @property {double} control_point_blue_1.right_handle.x=0.1000 - Pos x. - * @property {double} control_point_blue_1.right_handle.y=0.1000 - Pos y. - * @property {point_2d} control_point_blue_1.right_handle.2dpoint - Point. - * @property {color-correction-control-point-attribute} control_point_rgb_0 - Control point. - * @property {position_2d} control_point_rgb_0.control - Control Point. - * @property {bool} control_point_rgb_0.control.separate=Off - Separate. - * @property {double} control_point_rgb_0.control.x=0 - Pos x. - * @property {double} control_point_rgb_0.control.y=0 - Pos y. - * @property {point_2d} control_point_rgb_0.control.2dpoint - Point. - * @property {position_2d} control_point_rgb_0.left_handle - Left Handle. - * @property {bool} control_point_rgb_0.left_handle.separate=Off - Separate. - * @property {double} control_point_rgb_0.left_handle.x=-0.1000 - Pos x. - * @property {double} control_point_rgb_0.left_handle.y=-0.1000 - Pos y. - * @property {point_2d} control_point_rgb_0.left_handle.2dpoint - Point. - * @property {position_2d} control_point_rgb_0.right_handle - Right Handle. - * @property {bool} control_point_rgb_0.right_handle.separate=Off - Separate. - * @property {double} control_point_rgb_0.right_handle.x=0.1000 - Pos x. - * @property {double} control_point_rgb_0.right_handle.y=0.1000 - Pos y. - * @property {point_2d} control_point_rgb_0.right_handle.2dpoint - Point. - * @property {color-correction-control-point-attribute} control_point_rgb_1 - Control point. - * @property {position_2d} control_point_rgb_1.control - Control Point. - * @property {bool} control_point_rgb_1.control.separate=Off - Separate. - * @property {double} control_point_rgb_1.control.x=1 - Pos x. - * @property {double} control_point_rgb_1.control.y=1 - Pos y. - * @property {point_2d} control_point_rgb_1.control.2dpoint - Point. - * @property {position_2d} control_point_rgb_1.left_handle - Left Handle. - * @property {bool} control_point_rgb_1.left_handle.separate=Off - Separate. - * @property {double} control_point_rgb_1.left_handle.x=-0.1000 - Pos x. - * @property {double} control_point_rgb_1.left_handle.y=-0.1000 - Pos y. - * @property {point_2d} control_point_rgb_1.left_handle.2dpoint - Point. - * @property {position_2d} control_point_rgb_1.right_handle - Right Handle. - * @property {bool} control_point_rgb_1.right_handle.separate=Off - Separate. - * @property {double} control_point_rgb_1.right_handle.x=0.1000 - Pos x. - * @property {double} control_point_rgb_1.right_handle.y=0.1000 - Pos y. - * @property {point_2d} control_point_rgb_1.right_handle.2dpoint - Point. - * @property {color-correction-control-point-attribute} control_point_alpha_0 - Control point. - * @property {position_2d} control_point_alpha_0.control - Control Point. - * @property {bool} control_point_alpha_0.control.separate=Off - Separate. - * @property {double} control_point_alpha_0.control.x=0 - Pos x. - * @property {double} control_point_alpha_0.control.y=0 - Pos y. - * @property {point_2d} control_point_alpha_0.control.2dpoint - Point. - * @property {position_2d} control_point_alpha_0.left_handle - Left Handle. - * @property {bool} control_point_alpha_0.left_handle.separate=Off - Separate. - * @property {double} control_point_alpha_0.left_handle.x=-0.1000 - Pos x. - * @property {double} control_point_alpha_0.left_handle.y=-0.1000 - Pos y. - * @property {point_2d} control_point_alpha_0.left_handle.2dpoint - Point. - * @property {position_2d} control_point_alpha_0.right_handle - Right Handle. - * @property {bool} control_point_alpha_0.right_handle.separate=Off - Separate. - * @property {double} control_point_alpha_0.right_handle.x=0.1000 - Pos x. - * @property {double} control_point_alpha_0.right_handle.y=0.1000 - Pos y. - * @property {point_2d} control_point_alpha_0.right_handle.2dpoint - Point. - * @property {color-correction-control-point-attribute} control_point_alpha_1 - Control point. - * @property {position_2d} control_point_alpha_1.control - Control Point. - * @property {bool} control_point_alpha_1.control.separate=Off - Separate. - * @property {double} control_point_alpha_1.control.x=1 - Pos x. - * @property {double} control_point_alpha_1.control.y=1 - Pos y. - * @property {point_2d} control_point_alpha_1.control.2dpoint - Point. - * @property {position_2d} control_point_alpha_1.left_handle - Left Handle. - * @property {bool} control_point_alpha_1.left_handle.separate=Off - Separate. - * @property {double} control_point_alpha_1.left_handle.x=-0.1000 - Pos x. - * @property {double} control_point_alpha_1.left_handle.y=-0.1000 - Pos y. - * @property {point_2d} control_point_alpha_1.left_handle.2dpoint - Point. - * @property {position_2d} control_point_alpha_1.right_handle - Right Handle. - * @property {bool} control_point_alpha_1.right_handle.separate=Off - Separate. - * @property {double} control_point_alpha_1.right_handle.x=0.1000 - Pos x. - * @property {double} control_point_alpha_1.right_handle.y=0.1000 - Pos y. - * @property {point_2d} control_point_alpha_1.right_handle.2dpoint - Point. - */ - - -/** - * Attributes present in the node of type: 'HUE_SATURATION' - * @name NodeTypes#Hue-Saturation - * @property {hue_range} masterrangecolor - Master. - * @property {double} masterrangecolor.hue_shift=0 - Hue. - * @property {double} masterrangecolor.saturation=0 - Saturation. - * @property {double} masterrangecolor.lightness=0 - Lightness. - * @property {hue_range} redrangecolor - Reds. - * @property {double} redrangecolor.hue_shift=0 - Hue. - * @property {double} redrangecolor.saturation=0 - Saturation. - * @property {double} redrangecolor.lightness=0 - Lightness. - * @property {double} redrangecolor.low_range=345 - LowRange. - * @property {double} redrangecolor.high_range=15 - HighRange. - * @property {double} redrangecolor.low_falloff=30 - LowFalloff. - * @property {double} redrangecolor.high_falloff=30 - HighFalloff. - * @property {hue_range} greenrangecolor - Greens. - * @property {double} greenrangecolor.hue_shift=0 - Hue. - * @property {double} greenrangecolor.saturation=0 - Saturation. - * @property {double} greenrangecolor.lightness=0 - Lightness. - * @property {double} greenrangecolor.low_range=105 - LowRange. - * @property {double} greenrangecolor.high_range=135 - HighRange. - * @property {double} greenrangecolor.low_falloff=30 - LowFalloff. - * @property {double} greenrangecolor.high_falloff=30 - HighFalloff. - * @property {hue_range} bluerangecolor - Blues. - * @property {double} bluerangecolor.hue_shift=0 - Hue. - * @property {double} bluerangecolor.saturation=0 - Saturation. - * @property {double} bluerangecolor.lightness=0 - Lightness. - * @property {double} bluerangecolor.low_range=225 - LowRange. - * @property {double} bluerangecolor.high_range=255 - HighRange. - * @property {double} bluerangecolor.low_falloff=30 - LowFalloff. - * @property {double} bluerangecolor.high_falloff=30 - HighFalloff. - * @property {hue_range} cyanrangecolor - Cyans. - * @property {double} cyanrangecolor.hue_shift=0 - Hue. - * @property {double} cyanrangecolor.saturation=0 - Saturation. - * @property {double} cyanrangecolor.lightness=0 - Lightness. - * @property {double} cyanrangecolor.low_range=165 - LowRange. - * @property {double} cyanrangecolor.high_range=195 - HighRange. - * @property {double} cyanrangecolor.low_falloff=30 - LowFalloff. - * @property {double} cyanrangecolor.high_falloff=30 - HighFalloff. - * @property {hue_range} magentarangecolor - Magentas. - * @property {double} magentarangecolor.hue_shift=0 - Hue. - * @property {double} magentarangecolor.saturation=0 - Saturation. - * @property {double} magentarangecolor.lightness=0 - Lightness. - * @property {double} magentarangecolor.low_range=285 - LowRange. - * @property {double} magentarangecolor.high_range=315 - HighRange. - * @property {double} magentarangecolor.low_falloff=30 - LowFalloff. - * @property {double} magentarangecolor.high_falloff=30 - HighFalloff. - * @property {hue_range} yellowrangecolor - Yellows. - * @property {double} yellowrangecolor.hue_shift=0 - Hue. - * @property {double} yellowrangecolor.saturation=0 - Saturation. - * @property {double} yellowrangecolor.lightness=0 - Lightness. - * @property {double} yellowrangecolor.low_range=45 - LowRange. - * @property {double} yellowrangecolor.high_range=75 - HighRange. - * @property {double} yellowrangecolor.low_falloff=30 - LowFalloff. - * @property {double} yellowrangecolor.high_falloff=30 - HighFalloff. - * @property {bool} colorizeenable=false - Colorize. - * @property {hsl} colorizehsl - Colorize HSL. - * @property {double} colorizehsl.hue=0 - Hue. - * @property {double} colorizehsl.saturation=25 - Saturation. - * @property {double} colorizehsl.lightness=0 - Lightness. - * @property {push_button} resetred - Reset Range. - * @property {push_button} resetgreen - Reset Range. - * @property {push_button} resetblue - Reset Range. - * @property {push_button} resetcyan - Reset Range. - * @property {push_button} resetmagenta - Reset Range. - * @property {push_button} resetyellow - Reset Range. - * @property {bool} invert_matte_port=false - Invert Matte. - */ - - -/** - * Attributes present in the node of type: 'NEGATE' - * @name NodeTypes#Negate - * @property {bool} color=true - Negate Colour. - * @property {bool} color_alpha=false - Negate Alpha. - * @property {bool} color_clamp_to_alpha=true - Negate Colour Clamp to Alpha. - * @property {bool} invert_matte_port=false - Invert Matte. - */ - - -/** - * Attributes present in the node of type: 'TurbulentNoise' - * @name NodeTypes#TurbulentNoise - * @property {int} depth=0 - Depth. - * @property {bool} invert_matte_port=false - Invert Matte. - * @property {generic_enum} [fractal_type="Fractional Brownian"] - Fractal Type. - * @property {generic_enum} [noise_type="Perlin"] - Noise Type. - * @property {locked} frequency - Frequency. - * @property {bool} frequency.separate=Off - Separate. - * @property {doublevb} frequency.xyfrequency=0 - Frequency xy. - * @property {doublevb} frequency.xfrequency=0 - Frequency x. - * @property {doublevb} frequency.yfrequency=0 - Frequency y. - * @property {locked} offset - Offset. - * @property {bool} offset.separate=Off - Separate. - * @property {doublevb} offset.xyoffset=0 - Offset xy. - * @property {doublevb} offset.xoffset=0 - Offset x. - * @property {doublevb} offset.yoffset=0 - Offset y. - * @property {double} evolution=0 - Evolution. - * @property {double} evolution_frequency=0 - Evolution Frequency. - * @property {double} gain=0.6500 - Gain. - * @property {double} lacunarity=2 - Sub Scaling. - * @property {double} octaves=1 - Complexity. - */ - - -/** - * Attributes present in the node of type: 'BezierMesh' - * @name NodeTypes#Mesh-Warp - * @property {array_position_2d} mesh - Mesh. - * @property {int} mesh.size=105 - Size. - * @property {position_2d} mesh.meshpoint0x0 - MeshPoint0x0. - * @property {bool} mesh.meshpoint0x0.separate=On - Separate. - * @property {double} mesh.meshpoint0x0.x=-12 - Pos x. - * @property {double} mesh.meshpoint0x0.y=-12 - Pos y. - * @property {point_2d} mesh.meshpoint0x0.2dpoint - Point. - * @property {position_2d} mesh.meshpoint0x1 - MeshPoint0x1. - * @property {bool} mesh.meshpoint0x1.separate=On - Separate. - * @property {double} mesh.meshpoint0x1.x=-10 - Pos x. - * @property {double} mesh.meshpoint0x1.y=-12 - Pos y. - * @property {point_2d} mesh.meshpoint0x1.2dpoint - Point. - * @property {position_2d} mesh.meshpoint0x2 - MeshPoint0x2. - * @property {bool} mesh.meshpoint0x2.separate=On - Separate. - * @property {double} mesh.meshpoint0x2.x=-8 - Pos x. - * @property {double} mesh.meshpoint0x2.y=-12 - Pos y. - * @property {point_2d} mesh.meshpoint0x2.2dpoint - Point. - * @property {position_2d} mesh.meshpoint0x3 - MeshPoint0x3. - * @property {bool} mesh.meshpoint0x3.separate=On - Separate. - * @property {double} mesh.meshpoint0x3.x=-6 - Pos x. - * @property {double} mesh.meshpoint0x3.y=-12 - Pos y. - * @property {point_2d} mesh.meshpoint0x3.2dpoint - Point. - * @property {position_2d} mesh.meshpoint0x4 - MeshPoint0x4. - * @property {bool} mesh.meshpoint0x4.separate=On - Separate. - * @property {double} mesh.meshpoint0x4.x=-4 - Pos x. - * @property {double} mesh.meshpoint0x4.y=-12 - Pos y. - * @property {point_2d} mesh.meshpoint0x4.2dpoint - Point. - * @property {position_2d} mesh.meshpoint0x5 - MeshPoint0x5. - * @property {bool} mesh.meshpoint0x5.separate=On - Separate. - * @property {double} mesh.meshpoint0x5.x=-2 - Pos x. - * @property {double} mesh.meshpoint0x5.y=-12 - Pos y. - * @property {point_2d} mesh.meshpoint0x5.2dpoint - Point. - * @property {position_2d} mesh.meshpoint0x6 - MeshPoint0x6. - * @property {bool} mesh.meshpoint0x6.separate=On - Separate. - * @property {double} mesh.meshpoint0x6.x=0 - Pos x. - * @property {double} mesh.meshpoint0x6.y=-12 - Pos y. - * @property {point_2d} mesh.meshpoint0x6.2dpoint - Point. - * @property {position_2d} mesh.meshpoint0x7 - MeshPoint0x7. - * @property {bool} mesh.meshpoint0x7.separate=On - Separate. - * @property {double} mesh.meshpoint0x7.x=2 - Pos x. - * @property {double} mesh.meshpoint0x7.y=-12 - Pos y. - * @property {point_2d} mesh.meshpoint0x7.2dpoint - Point. - * @property {position_2d} mesh.meshpoint0x8 - MeshPoint0x8. - * @property {bool} mesh.meshpoint0x8.separate=On - Separate. - * @property {double} mesh.meshpoint0x8.x=4 - Pos x. - * @property {double} mesh.meshpoint0x8.y=-12 - Pos y. - * @property {point_2d} mesh.meshpoint0x8.2dpoint - Point. - * @property {position_2d} mesh.meshpoint0x9 - MeshPoint0x9. - * @property {bool} mesh.meshpoint0x9.separate=On - Separate. - * @property {double} mesh.meshpoint0x9.x=6 - Pos x. - * @property {double} mesh.meshpoint0x9.y=-12 - Pos y. - * @property {point_2d} mesh.meshpoint0x9.2dpoint - Point. - * @property {position_2d} mesh.meshpoint0x10 - MeshPoint0x10. - * @property {bool} mesh.meshpoint0x10.separate=On - Separate. - * @property {double} mesh.meshpoint0x10.x=8 - Pos x. - * @property {double} mesh.meshpoint0x10.y=-12 - Pos y. - * @property {point_2d} mesh.meshpoint0x10.2dpoint - Point. - * @property {position_2d} mesh.meshpoint0x11 - MeshPoint0x11. - * @property {bool} mesh.meshpoint0x11.separate=On - Separate. - * @property {double} mesh.meshpoint0x11.x=10 - Pos x. - * @property {double} mesh.meshpoint0x11.y=-12 - Pos y. - * @property {point_2d} mesh.meshpoint0x11.2dpoint - Point. - * @property {position_2d} mesh.meshpoint0x12 - MeshPoint0x12. - * @property {bool} mesh.meshpoint0x12.separate=On - Separate. - * @property {double} mesh.meshpoint0x12.x=12 - Pos x. - * @property {double} mesh.meshpoint0x12.y=-12 - Pos y. - * @property {point_2d} mesh.meshpoint0x12.2dpoint - Point. - * @property {position_2d} mesh.meshpoint0x13 - MeshPoint0x13. - * @property {bool} mesh.meshpoint0x13.separate=On - Separate. - * @property {double} mesh.meshpoint0x13.x=-12 - Pos x. - * @property {double} mesh.meshpoint0x13.y=-10 - Pos y. - * @property {point_2d} mesh.meshpoint0x13.2dpoint - Point. - * @property {position_2d} mesh.meshpoint0x14 - MeshPoint0x14. - * @property {bool} mesh.meshpoint0x14.separate=On - Separate. - * @property {double} mesh.meshpoint0x14.x=-6 - Pos x. - * @property {double} mesh.meshpoint0x14.y=-10 - Pos y. - * @property {point_2d} mesh.meshpoint0x14.2dpoint - Point. - * @property {position_2d} mesh.meshpoint0x15 - MeshPoint0x15. - * @property {bool} mesh.meshpoint0x15.separate=On - Separate. - * @property {double} mesh.meshpoint0x15.x=0 - Pos x. - * @property {double} mesh.meshpoint0x15.y=-10 - Pos y. - * @property {point_2d} mesh.meshpoint0x15.2dpoint - Point. - * @property {position_2d} mesh.meshpoint0x16 - MeshPoint0x16. - * @property {bool} mesh.meshpoint0x16.separate=On - Separate. - * @property {double} mesh.meshpoint0x16.x=6 - Pos x. - * @property {double} mesh.meshpoint0x16.y=-10 - Pos y. - * @property {point_2d} mesh.meshpoint0x16.2dpoint - Point. - * @property {position_2d} mesh.meshpoint0x17 - MeshPoint0x17. - * @property {bool} mesh.meshpoint0x17.separate=On - Separate. - * @property {double} mesh.meshpoint0x17.x=12 - Pos x. - * @property {double} mesh.meshpoint0x17.y=-10 - Pos y. - * @property {point_2d} mesh.meshpoint0x17.2dpoint - Point. - * @property {position_2d} mesh.meshpoint0x18 - MeshPoint0x18. - * @property {bool} mesh.meshpoint0x18.separate=On - Separate. - * @property {double} mesh.meshpoint0x18.x=-12 - Pos x. - * @property {double} mesh.meshpoint0x18.y=-8 - Pos y. - * @property {point_2d} mesh.meshpoint0x18.2dpoint - Point. - * @property {position_2d} mesh.meshpoint0x19 - MeshPoint0x19. - * @property {bool} mesh.meshpoint0x19.separate=On - Separate. - * @property {double} mesh.meshpoint0x19.x=-6 - Pos x. - * @property {double} mesh.meshpoint0x19.y=-8 - Pos y. - * @property {point_2d} mesh.meshpoint0x19.2dpoint - Point. - * @property {position_2d} mesh.meshpoint0x20 - MeshPoint0x20. - * @property {bool} mesh.meshpoint0x20.separate=On - Separate. - * @property {double} mesh.meshpoint0x20.x=0 - Pos x. - * @property {double} mesh.meshpoint0x20.y=-8 - Pos y. - * @property {point_2d} mesh.meshpoint0x20.2dpoint - Point. - * @property {position_2d} mesh.meshpoint0x21 - MeshPoint0x21. - * @property {bool} mesh.meshpoint0x21.separate=On - Separate. - * @property {double} mesh.meshpoint0x21.x=6 - Pos x. - * @property {double} mesh.meshpoint0x21.y=-8 - Pos y. - * @property {point_2d} mesh.meshpoint0x21.2dpoint - Point. - * @property {position_2d} mesh.meshpoint0x22 - MeshPoint0x22. - * @property {bool} mesh.meshpoint0x22.separate=On - Separate. - * @property {double} mesh.meshpoint0x22.x=12 - Pos x. - * @property {double} mesh.meshpoint0x22.y=-8 - Pos y. - * @property {point_2d} mesh.meshpoint0x22.2dpoint - Point. - * @property {position_2d} mesh.meshpoint0x23 - MeshPoint0x23. - * @property {bool} mesh.meshpoint0x23.separate=On - Separate. - * @property {double} mesh.meshpoint0x23.x=-12 - Pos x. - * @property {double} mesh.meshpoint0x23.y=-6 - Pos y. - * @property {point_2d} mesh.meshpoint0x23.2dpoint - Point. - * @property {position_2d} mesh.meshpoint0x24 - MeshPoint0x24. - * @property {bool} mesh.meshpoint0x24.separate=On - Separate. - * @property {double} mesh.meshpoint0x24.x=-10 - Pos x. - * @property {double} mesh.meshpoint0x24.y=-6 - Pos y. - * @property {point_2d} mesh.meshpoint0x24.2dpoint - Point. - * @property {position_2d} mesh.meshpoint0x25 - MeshPoint0x25. - * @property {bool} mesh.meshpoint0x25.separate=On - Separate. - * @property {double} mesh.meshpoint0x25.x=-8 - Pos x. - * @property {double} mesh.meshpoint0x25.y=-6 - Pos y. - * @property {point_2d} mesh.meshpoint0x25.2dpoint - Point. - * @property {position_2d} mesh.meshpoint0x26 - MeshPoint0x26. - * @property {bool} mesh.meshpoint0x26.separate=On - Separate. - * @property {double} mesh.meshpoint0x26.x=-6 - Pos x. - * @property {double} mesh.meshpoint0x26.y=-6 - Pos y. - * @property {point_2d} mesh.meshpoint0x26.2dpoint - Point. - * @property {position_2d} mesh.meshpoint0x27 - MeshPoint0x27. - * @property {bool} mesh.meshpoint0x27.separate=On - Separate. - * @property {double} mesh.meshpoint0x27.x=-4 - Pos x. - * @property {double} mesh.meshpoint0x27.y=-6 - Pos y. - * @property {point_2d} mesh.meshpoint0x27.2dpoint - Point. - * @property {position_2d} mesh.meshpoint0x28 - MeshPoint0x28. - * @property {bool} mesh.meshpoint0x28.separate=On - Separate. - * @property {double} mesh.meshpoint0x28.x=-2 - Pos x. - * @property {double} mesh.meshpoint0x28.y=-6 - Pos y. - * @property {point_2d} mesh.meshpoint0x28.2dpoint - Point. - * @property {position_2d} mesh.meshpoint0x29 - MeshPoint0x29. - * @property {bool} mesh.meshpoint0x29.separate=On - Separate. - * @property {double} mesh.meshpoint0x29.x=0 - Pos x. - * @property {double} mesh.meshpoint0x29.y=-6 - Pos y. - * @property {point_2d} mesh.meshpoint0x29.2dpoint - Point. - * @property {position_2d} mesh.meshpoint0x30 - MeshPoint0x30. - * @property {bool} mesh.meshpoint0x30.separate=On - Separate. - * @property {double} mesh.meshpoint0x30.x=2 - Pos x. - * @property {double} mesh.meshpoint0x30.y=-6 - Pos y. - * @property {point_2d} mesh.meshpoint0x30.2dpoint - Point. - * @property {position_2d} mesh.meshpoint1x0 - MeshPoint1x0. - * @property {bool} mesh.meshpoint1x0.separate=On - Separate. - * @property {double} mesh.meshpoint1x0.x=4 - Pos x. - * @property {double} mesh.meshpoint1x0.y=-6 - Pos y. - * @property {point_2d} mesh.meshpoint1x0.2dpoint - Point. - * @property {position_2d} mesh.meshpoint1x1 - MeshPoint1x1. - * @property {bool} mesh.meshpoint1x1.separate=On - Separate. - * @property {double} mesh.meshpoint1x1.x=6 - Pos x. - * @property {double} mesh.meshpoint1x1.y=-6 - Pos y. - * @property {point_2d} mesh.meshpoint1x1.2dpoint - Point. - * @property {position_2d} mesh.meshpoint1x2 - MeshPoint1x2. - * @property {bool} mesh.meshpoint1x2.separate=On - Separate. - * @property {double} mesh.meshpoint1x2.x=8 - Pos x. - * @property {double} mesh.meshpoint1x2.y=-6 - Pos y. - * @property {point_2d} mesh.meshpoint1x2.2dpoint - Point. - * @property {position_2d} mesh.meshpoint1x3 - MeshPoint1x3. - * @property {bool} mesh.meshpoint1x3.separate=On - Separate. - * @property {double} mesh.meshpoint1x3.x=10 - Pos x. - * @property {double} mesh.meshpoint1x3.y=-6 - Pos y. - * @property {point_2d} mesh.meshpoint1x3.2dpoint - Point. - * @property {position_2d} mesh.meshpoint1x4 - MeshPoint1x4. - * @property {bool} mesh.meshpoint1x4.separate=On - Separate. - * @property {double} mesh.meshpoint1x4.x=12 - Pos x. - * @property {double} mesh.meshpoint1x4.y=-6 - Pos y. - * @property {point_2d} mesh.meshpoint1x4.2dpoint - Point. - * @property {position_2d} mesh.meshpoint1x5 - MeshPoint1x5. - * @property {bool} mesh.meshpoint1x5.separate=On - Separate. - * @property {double} mesh.meshpoint1x5.x=-12 - Pos x. - * @property {double} mesh.meshpoint1x5.y=-4 - Pos y. - * @property {point_2d} mesh.meshpoint1x5.2dpoint - Point. - * @property {position_2d} mesh.meshpoint1x6 - MeshPoint1x6. - * @property {bool} mesh.meshpoint1x6.separate=On - Separate. - * @property {double} mesh.meshpoint1x6.x=-6 - Pos x. - * @property {double} mesh.meshpoint1x6.y=-4 - Pos y. - * @property {point_2d} mesh.meshpoint1x6.2dpoint - Point. - * @property {position_2d} mesh.meshpoint1x7 - MeshPoint1x7. - * @property {bool} mesh.meshpoint1x7.separate=On - Separate. - * @property {double} mesh.meshpoint1x7.x=0 - Pos x. - * @property {double} mesh.meshpoint1x7.y=-4 - Pos y. - * @property {point_2d} mesh.meshpoint1x7.2dpoint - Point. - * @property {position_2d} mesh.meshpoint1x8 - MeshPoint1x8. - * @property {bool} mesh.meshpoint1x8.separate=On - Separate. - * @property {double} mesh.meshpoint1x8.x=6 - Pos x. - * @property {double} mesh.meshpoint1x8.y=-4 - Pos y. - * @property {point_2d} mesh.meshpoint1x8.2dpoint - Point. - * @property {position_2d} mesh.meshpoint1x9 - MeshPoint1x9. - * @property {bool} mesh.meshpoint1x9.separate=On - Separate. - * @property {double} mesh.meshpoint1x9.x=12 - Pos x. - * @property {double} mesh.meshpoint1x9.y=-4 - Pos y. - * @property {point_2d} mesh.meshpoint1x9.2dpoint - Point. - * @property {position_2d} mesh.meshpoint1x10 - MeshPoint1x10. - * @property {bool} mesh.meshpoint1x10.separate=On - Separate. - * @property {double} mesh.meshpoint1x10.x=-12 - Pos x. - * @property {double} mesh.meshpoint1x10.y=-2 - Pos y. - * @property {point_2d} mesh.meshpoint1x10.2dpoint - Point. - * @property {position_2d} mesh.meshpoint2x0 - MeshPoint2x0. - * @property {bool} mesh.meshpoint2x0.separate=On - Separate. - * @property {double} mesh.meshpoint2x0.x=-6 - Pos x. - * @property {double} mesh.meshpoint2x0.y=-2 - Pos y. - * @property {point_2d} mesh.meshpoint2x0.2dpoint - Point. - * @property {position_2d} mesh.meshpoint2x1 - MeshPoint2x1. - * @property {bool} mesh.meshpoint2x1.separate=On - Separate. - * @property {double} mesh.meshpoint2x1.x=0 - Pos x. - * @property {double} mesh.meshpoint2x1.y=-2 - Pos y. - * @property {point_2d} mesh.meshpoint2x1.2dpoint - Point. - * @property {position_2d} mesh.meshpoint2x2 - MeshPoint2x2. - * @property {bool} mesh.meshpoint2x2.separate=On - Separate. - * @property {double} mesh.meshpoint2x2.x=6 - Pos x. - * @property {double} mesh.meshpoint2x2.y=-2 - Pos y. - * @property {point_2d} mesh.meshpoint2x2.2dpoint - Point. - * @property {position_2d} mesh.meshpoint2x3 - MeshPoint2x3. - * @property {bool} mesh.meshpoint2x3.separate=On - Separate. - * @property {double} mesh.meshpoint2x3.x=12 - Pos x. - * @property {double} mesh.meshpoint2x3.y=-2 - Pos y. - * @property {point_2d} mesh.meshpoint2x3.2dpoint - Point. - * @property {position_2d} mesh.meshpoint2x4 - MeshPoint2x4. - * @property {bool} mesh.meshpoint2x4.separate=On - Separate. - * @property {double} mesh.meshpoint2x4.x=-12 - Pos x. - * @property {double} mesh.meshpoint2x4.y=0 - Pos y. - * @property {point_2d} mesh.meshpoint2x4.2dpoint - Point. - * @property {position_2d} mesh.meshpoint2x5 - MeshPoint2x5. - * @property {bool} mesh.meshpoint2x5.separate=On - Separate. - * @property {double} mesh.meshpoint2x5.x=-10 - Pos x. - * @property {double} mesh.meshpoint2x5.y=0 - Pos y. - * @property {point_2d} mesh.meshpoint2x5.2dpoint - Point. - * @property {position_2d} mesh.meshpoint2x6 - MeshPoint2x6. - * @property {bool} mesh.meshpoint2x6.separate=On - Separate. - * @property {double} mesh.meshpoint2x6.x=-8 - Pos x. - * @property {double} mesh.meshpoint2x6.y=0 - Pos y. - * @property {point_2d} mesh.meshpoint2x6.2dpoint - Point. - * @property {position_2d} mesh.meshpoint2x7 - MeshPoint2x7. - * @property {bool} mesh.meshpoint2x7.separate=On - Separate. - * @property {double} mesh.meshpoint2x7.x=-6 - Pos x. - * @property {double} mesh.meshpoint2x7.y=0 - Pos y. - * @property {point_2d} mesh.meshpoint2x7.2dpoint - Point. - * @property {position_2d} mesh.meshpoint2x8 - MeshPoint2x8. - * @property {bool} mesh.meshpoint2x8.separate=On - Separate. - * @property {double} mesh.meshpoint2x8.x=-4 - Pos x. - * @property {double} mesh.meshpoint2x8.y=0 - Pos y. - * @property {point_2d} mesh.meshpoint2x8.2dpoint - Point. - * @property {position_2d} mesh.meshpoint2x9 - MeshPoint2x9. - * @property {bool} mesh.meshpoint2x9.separate=On - Separate. - * @property {double} mesh.meshpoint2x9.x=-2 - Pos x. - * @property {double} mesh.meshpoint2x9.y=0 - Pos y. - * @property {point_2d} mesh.meshpoint2x9.2dpoint - Point. - * @property {position_2d} mesh.meshpoint2x10 - MeshPoint2x10. - * @property {bool} mesh.meshpoint2x10.separate=On - Separate. - * @property {double} mesh.meshpoint2x10.x=0 - Pos x. - * @property {double} mesh.meshpoint2x10.y=0 - Pos y. - * @property {point_2d} mesh.meshpoint2x10.2dpoint - Point. - * @property {position_2d} mesh.meshpoint3x0 - MeshPoint3x0. - * @property {bool} mesh.meshpoint3x0.separate=On - Separate. - * @property {double} mesh.meshpoint3x0.x=2 - Pos x. - * @property {double} mesh.meshpoint3x0.y=0 - Pos y. - * @property {point_2d} mesh.meshpoint3x0.2dpoint - Point. - * @property {position_2d} mesh.meshpoint3x1 - MeshPoint3x1. - * @property {bool} mesh.meshpoint3x1.separate=On - Separate. - * @property {double} mesh.meshpoint3x1.x=4 - Pos x. - * @property {double} mesh.meshpoint3x1.y=0 - Pos y. - * @property {point_2d} mesh.meshpoint3x1.2dpoint - Point. - * @property {position_2d} mesh.meshpoint3x2 - MeshPoint3x2. - * @property {bool} mesh.meshpoint3x2.separate=On - Separate. - * @property {double} mesh.meshpoint3x2.x=6 - Pos x. - * @property {double} mesh.meshpoint3x2.y=0 - Pos y. - * @property {point_2d} mesh.meshpoint3x2.2dpoint - Point. - * @property {position_2d} mesh.meshpoint3x3 - MeshPoint3x3. - * @property {bool} mesh.meshpoint3x3.separate=On - Separate. - * @property {double} mesh.meshpoint3x3.x=8 - Pos x. - * @property {double} mesh.meshpoint3x3.y=0 - Pos y. - * @property {point_2d} mesh.meshpoint3x3.2dpoint - Point. - * @property {position_2d} mesh.meshpoint3x4 - MeshPoint3x4. - * @property {bool} mesh.meshpoint3x4.separate=On - Separate. - * @property {double} mesh.meshpoint3x4.x=10 - Pos x. - * @property {double} mesh.meshpoint3x4.y=0 - Pos y. - * @property {point_2d} mesh.meshpoint3x4.2dpoint - Point. - * @property {position_2d} mesh.meshpoint3x5 - MeshPoint3x5. - * @property {bool} mesh.meshpoint3x5.separate=On - Separate. - * @property {double} mesh.meshpoint3x5.x=12 - Pos x. - * @property {double} mesh.meshpoint3x5.y=0 - Pos y. - * @property {point_2d} mesh.meshpoint3x5.2dpoint - Point. - * @property {position_2d} mesh.meshpoint3x6 - MeshPoint3x6. - * @property {bool} mesh.meshpoint3x6.separate=On - Separate. - * @property {double} mesh.meshpoint3x6.x=-12 - Pos x. - * @property {double} mesh.meshpoint3x6.y=2 - Pos y. - * @property {point_2d} mesh.meshpoint3x6.2dpoint - Point. - * @property {position_2d} mesh.meshpoint3x7 - MeshPoint3x7. - * @property {bool} mesh.meshpoint3x7.separate=On - Separate. - * @property {double} mesh.meshpoint3x7.x=-6 - Pos x. - * @property {double} mesh.meshpoint3x7.y=2 - Pos y. - * @property {point_2d} mesh.meshpoint3x7.2dpoint - Point. - * @property {position_2d} mesh.meshpoint3x8 - MeshPoint3x8. - * @property {bool} mesh.meshpoint3x8.separate=On - Separate. - * @property {double} mesh.meshpoint3x8.x=0 - Pos x. - * @property {double} mesh.meshpoint3x8.y=2 - Pos y. - * @property {point_2d} mesh.meshpoint3x8.2dpoint - Point. - * @property {position_2d} mesh.meshpoint3x9 - MeshPoint3x9. - * @property {bool} mesh.meshpoint3x9.separate=On - Separate. - * @property {double} mesh.meshpoint3x9.x=6 - Pos x. - * @property {double} mesh.meshpoint3x9.y=2 - Pos y. - * @property {point_2d} mesh.meshpoint3x9.2dpoint - Point. - * @property {position_2d} mesh.meshpoint3x10 - MeshPoint3x10. - * @property {bool} mesh.meshpoint3x10.separate=On - Separate. - * @property {double} mesh.meshpoint3x10.x=12 - Pos x. - * @property {double} mesh.meshpoint3x10.y=2 - Pos y. - * @property {point_2d} mesh.meshpoint3x10.2dpoint - Point. - * @property {position_2d} mesh.meshpoint3x11 - MeshPoint3x11. - * @property {bool} mesh.meshpoint3x11.separate=On - Separate. - * @property {double} mesh.meshpoint3x11.x=-12 - Pos x. - * @property {double} mesh.meshpoint3x11.y=4 - Pos y. - * @property {point_2d} mesh.meshpoint3x11.2dpoint - Point. - * @property {position_2d} mesh.meshpoint3x12 - MeshPoint3x12. - * @property {bool} mesh.meshpoint3x12.separate=On - Separate. - * @property {double} mesh.meshpoint3x12.x=-6 - Pos x. - * @property {double} mesh.meshpoint3x12.y=4 - Pos y. - * @property {point_2d} mesh.meshpoint3x12.2dpoint - Point. - * @property {position_2d} mesh.meshpoint3x13 - MeshPoint3x13. - * @property {bool} mesh.meshpoint3x13.separate=On - Separate. - * @property {double} mesh.meshpoint3x13.x=0 - Pos x. - * @property {double} mesh.meshpoint3x13.y=4 - Pos y. - * @property {point_2d} mesh.meshpoint3x13.2dpoint - Point. - * @property {position_2d} mesh.meshpoint3x14 - MeshPoint3x14. - * @property {bool} mesh.meshpoint3x14.separate=On - Separate. - * @property {double} mesh.meshpoint3x14.x=6 - Pos x. - * @property {double} mesh.meshpoint3x14.y=4 - Pos y. - * @property {point_2d} mesh.meshpoint3x14.2dpoint - Point. - * @property {position_2d} mesh.meshpoint3x15 - MeshPoint3x15. - * @property {bool} mesh.meshpoint3x15.separate=On - Separate. - * @property {double} mesh.meshpoint3x15.x=12 - Pos x. - * @property {double} mesh.meshpoint3x15.y=4 - Pos y. - * @property {point_2d} mesh.meshpoint3x15.2dpoint - Point. - * @property {position_2d} mesh.meshpoint3x16 - MeshPoint3x16. - * @property {bool} mesh.meshpoint3x16.separate=On - Separate. - * @property {double} mesh.meshpoint3x16.x=-12 - Pos x. - * @property {double} mesh.meshpoint3x16.y=6 - Pos y. - * @property {point_2d} mesh.meshpoint3x16.2dpoint - Point. - * @property {position_2d} mesh.meshpoint3x17 - MeshPoint3x17. - * @property {bool} mesh.meshpoint3x17.separate=On - Separate. - * @property {double} mesh.meshpoint3x17.x=-10 - Pos x. - * @property {double} mesh.meshpoint3x17.y=6 - Pos y. - * @property {point_2d} mesh.meshpoint3x17.2dpoint - Point. - * @property {position_2d} mesh.meshpoint3x18 - MeshPoint3x18. - * @property {bool} mesh.meshpoint3x18.separate=On - Separate. - * @property {double} mesh.meshpoint3x18.x=-8 - Pos x. - * @property {double} mesh.meshpoint3x18.y=6 - Pos y. - * @property {point_2d} mesh.meshpoint3x18.2dpoint - Point. - * @property {position_2d} mesh.meshpoint3x19 - MeshPoint3x19. - * @property {bool} mesh.meshpoint3x19.separate=On - Separate. - * @property {double} mesh.meshpoint3x19.x=-6 - Pos x. - * @property {double} mesh.meshpoint3x19.y=6 - Pos y. - * @property {point_2d} mesh.meshpoint3x19.2dpoint - Point. - * @property {position_2d} mesh.meshpoint3x20 - MeshPoint3x20. - * @property {bool} mesh.meshpoint3x20.separate=On - Separate. - * @property {double} mesh.meshpoint3x20.x=-4 - Pos x. - * @property {double} mesh.meshpoint3x20.y=6 - Pos y. - * @property {point_2d} mesh.meshpoint3x20.2dpoint - Point. - * @property {position_2d} mesh.meshpoint3x21 - MeshPoint3x21. - * @property {bool} mesh.meshpoint3x21.separate=On - Separate. - * @property {double} mesh.meshpoint3x21.x=-2 - Pos x. - * @property {double} mesh.meshpoint3x21.y=6 - Pos y. - * @property {point_2d} mesh.meshpoint3x21.2dpoint - Point. - * @property {position_2d} mesh.meshpoint3x22 - MeshPoint3x22. - * @property {bool} mesh.meshpoint3x22.separate=On - Separate. - * @property {double} mesh.meshpoint3x22.x=0 - Pos x. - * @property {double} mesh.meshpoint3x22.y=6 - Pos y. - * @property {point_2d} mesh.meshpoint3x22.2dpoint - Point. - * @property {position_2d} mesh.meshpoint3x23 - MeshPoint3x23. - * @property {bool} mesh.meshpoint3x23.separate=On - Separate. - * @property {double} mesh.meshpoint3x23.x=2 - Pos x. - * @property {double} mesh.meshpoint3x23.y=6 - Pos y. - * @property {point_2d} mesh.meshpoint3x23.2dpoint - Point. - * @property {position_2d} mesh.meshpoint3x24 - MeshPoint3x24. - * @property {bool} mesh.meshpoint3x24.separate=On - Separate. - * @property {double} mesh.meshpoint3x24.x=4 - Pos x. - * @property {double} mesh.meshpoint3x24.y=6 - Pos y. - * @property {point_2d} mesh.meshpoint3x24.2dpoint - Point. - * @property {position_2d} mesh.meshpoint3x25 - MeshPoint3x25. - * @property {bool} mesh.meshpoint3x25.separate=On - Separate. - * @property {double} mesh.meshpoint3x25.x=6 - Pos x. - * @property {double} mesh.meshpoint3x25.y=6 - Pos y. - * @property {point_2d} mesh.meshpoint3x25.2dpoint - Point. - * @property {position_2d} mesh.meshpoint3x26 - MeshPoint3x26. - * @property {bool} mesh.meshpoint3x26.separate=On - Separate. - * @property {double} mesh.meshpoint3x26.x=8 - Pos x. - * @property {double} mesh.meshpoint3x26.y=6 - Pos y. - * @property {point_2d} mesh.meshpoint3x26.2dpoint - Point. - * @property {position_2d} mesh.meshpoint3x27 - MeshPoint3x27. - * @property {bool} mesh.meshpoint3x27.separate=On - Separate. - * @property {double} mesh.meshpoint3x27.x=10 - Pos x. - * @property {double} mesh.meshpoint3x27.y=6 - Pos y. - * @property {point_2d} mesh.meshpoint3x27.2dpoint - Point. - * @property {position_2d} mesh.meshpoint3x28 - MeshPoint3x28. - * @property {bool} mesh.meshpoint3x28.separate=On - Separate. - * @property {double} mesh.meshpoint3x28.x=12 - Pos x. - * @property {double} mesh.meshpoint3x28.y=6 - Pos y. - * @property {point_2d} mesh.meshpoint3x28.2dpoint - Point. - * @property {position_2d} mesh.meshpoint3x29 - MeshPoint3x29. - * @property {bool} mesh.meshpoint3x29.separate=On - Separate. - * @property {double} mesh.meshpoint3x29.x=-12 - Pos x. - * @property {double} mesh.meshpoint3x29.y=8 - Pos y. - * @property {point_2d} mesh.meshpoint3x29.2dpoint - Point. - * @property {position_2d} mesh.meshpoint3x30 - MeshPoint3x30. - * @property {bool} mesh.meshpoint3x30.separate=On - Separate. - * @property {double} mesh.meshpoint3x30.x=-6 - Pos x. - * @property {double} mesh.meshpoint3x30.y=8 - Pos y. - * @property {point_2d} mesh.meshpoint3x30.2dpoint - Point. - * @property {position_2d} mesh.meshpoint4x0 - MeshPoint4x0. - * @property {bool} mesh.meshpoint4x0.separate=On - Separate. - * @property {double} mesh.meshpoint4x0.x=0 - Pos x. - * @property {double} mesh.meshpoint4x0.y=8 - Pos y. - * @property {point_2d} mesh.meshpoint4x0.2dpoint - Point. - * @property {position_2d} mesh.meshpoint4x1 - MeshPoint4x1. - * @property {bool} mesh.meshpoint4x1.separate=On - Separate. - * @property {double} mesh.meshpoint4x1.x=6 - Pos x. - * @property {double} mesh.meshpoint4x1.y=8 - Pos y. - * @property {point_2d} mesh.meshpoint4x1.2dpoint - Point. - * @property {position_2d} mesh.meshpoint4x2 - MeshPoint4x2. - * @property {bool} mesh.meshpoint4x2.separate=On - Separate. - * @property {double} mesh.meshpoint4x2.x=12 - Pos x. - * @property {double} mesh.meshpoint4x2.y=8 - Pos y. - * @property {point_2d} mesh.meshpoint4x2.2dpoint - Point. - * @property {position_2d} mesh.meshpoint4x3 - MeshPoint4x3. - * @property {bool} mesh.meshpoint4x3.separate=On - Separate. - * @property {double} mesh.meshpoint4x3.x=-12 - Pos x. - * @property {double} mesh.meshpoint4x3.y=10 - Pos y. - * @property {point_2d} mesh.meshpoint4x3.2dpoint - Point. - * @property {position_2d} mesh.meshpoint4x4 - MeshPoint4x4. - * @property {bool} mesh.meshpoint4x4.separate=On - Separate. - * @property {double} mesh.meshpoint4x4.x=-6 - Pos x. - * @property {double} mesh.meshpoint4x4.y=10 - Pos y. - * @property {point_2d} mesh.meshpoint4x4.2dpoint - Point. - * @property {position_2d} mesh.meshpoint4x5 - MeshPoint4x5. - * @property {bool} mesh.meshpoint4x5.separate=On - Separate. - * @property {double} mesh.meshpoint4x5.x=0 - Pos x. - * @property {double} mesh.meshpoint4x5.y=10 - Pos y. - * @property {point_2d} mesh.meshpoint4x5.2dpoint - Point. - * @property {position_2d} mesh.meshpoint4x6 - MeshPoint4x6. - * @property {bool} mesh.meshpoint4x6.separate=On - Separate. - * @property {double} mesh.meshpoint4x6.x=6 - Pos x. - * @property {double} mesh.meshpoint4x6.y=10 - Pos y. - * @property {point_2d} mesh.meshpoint4x6.2dpoint - Point. - * @property {position_2d} mesh.meshpoint4x7 - MeshPoint4x7. - * @property {bool} mesh.meshpoint4x7.separate=On - Separate. - * @property {double} mesh.meshpoint4x7.x=12 - Pos x. - * @property {double} mesh.meshpoint4x7.y=10 - Pos y. - * @property {point_2d} mesh.meshpoint4x7.2dpoint - Point. - * @property {position_2d} mesh.meshpoint4x8 - MeshPoint4x8. - * @property {bool} mesh.meshpoint4x8.separate=On - Separate. - * @property {double} mesh.meshpoint4x8.x=-12 - Pos x. - * @property {double} mesh.meshpoint4x8.y=12 - Pos y. - * @property {point_2d} mesh.meshpoint4x8.2dpoint - Point. - * @property {position_2d} mesh.meshpoint4x9 - MeshPoint4x9. - * @property {bool} mesh.meshpoint4x9.separate=On - Separate. - * @property {double} mesh.meshpoint4x9.x=-10 - Pos x. - * @property {double} mesh.meshpoint4x9.y=12 - Pos y. - * @property {point_2d} mesh.meshpoint4x9.2dpoint - Point. - * @property {position_2d} mesh.meshpoint4x10 - MeshPoint4x10. - * @property {bool} mesh.meshpoint4x10.separate=On - Separate. - * @property {double} mesh.meshpoint4x10.x=-8 - Pos x. - * @property {double} mesh.meshpoint4x10.y=12 - Pos y. - * @property {point_2d} mesh.meshpoint4x10.2dpoint - Point. - * @property {position_2d} mesh.meshpoint5x0 - MeshPoint5x0. - * @property {bool} mesh.meshpoint5x0.separate=On - Separate. - * @property {double} mesh.meshpoint5x0.x=-6 - Pos x. - * @property {double} mesh.meshpoint5x0.y=12 - Pos y. - * @property {point_2d} mesh.meshpoint5x0.2dpoint - Point. - * @property {position_2d} mesh.meshpoint5x1 - MeshPoint5x1. - * @property {bool} mesh.meshpoint5x1.separate=On - Separate. - * @property {double} mesh.meshpoint5x1.x=-4 - Pos x. - * @property {double} mesh.meshpoint5x1.y=12 - Pos y. - * @property {point_2d} mesh.meshpoint5x1.2dpoint - Point. - * @property {position_2d} mesh.meshpoint5x2 - MeshPoint5x2. - * @property {bool} mesh.meshpoint5x2.separate=On - Separate. - * @property {double} mesh.meshpoint5x2.x=-2 - Pos x. - * @property {double} mesh.meshpoint5x2.y=12 - Pos y. - * @property {point_2d} mesh.meshpoint5x2.2dpoint - Point. - * @property {position_2d} mesh.meshpoint5x3 - MeshPoint5x3. - * @property {bool} mesh.meshpoint5x3.separate=On - Separate. - * @property {double} mesh.meshpoint5x3.x=0 - Pos x. - * @property {double} mesh.meshpoint5x3.y=12 - Pos y. - * @property {point_2d} mesh.meshpoint5x3.2dpoint - Point. - * @property {position_2d} mesh.meshpoint5x4 - MeshPoint5x4. - * @property {bool} mesh.meshpoint5x4.separate=On - Separate. - * @property {double} mesh.meshpoint5x4.x=2 - Pos x. - * @property {double} mesh.meshpoint5x4.y=12 - Pos y. - * @property {point_2d} mesh.meshpoint5x4.2dpoint - Point. - * @property {position_2d} mesh.meshpoint5x5 - MeshPoint5x5. - * @property {bool} mesh.meshpoint5x5.separate=On - Separate. - * @property {double} mesh.meshpoint5x5.x=4 - Pos x. - * @property {double} mesh.meshpoint5x5.y=12 - Pos y. - * @property {point_2d} mesh.meshpoint5x5.2dpoint - Point. - * @property {position_2d} mesh.meshpoint5x6 - MeshPoint5x6. - * @property {bool} mesh.meshpoint5x6.separate=On - Separate. - * @property {double} mesh.meshpoint5x6.x=6 - Pos x. - * @property {double} mesh.meshpoint5x6.y=12 - Pos y. - * @property {point_2d} mesh.meshpoint5x6.2dpoint - Point. - * @property {position_2d} mesh.meshpoint5x7 - MeshPoint5x7. - * @property {bool} mesh.meshpoint5x7.separate=On - Separate. - * @property {double} mesh.meshpoint5x7.x=8 - Pos x. - * @property {double} mesh.meshpoint5x7.y=12 - Pos y. - * @property {point_2d} mesh.meshpoint5x7.2dpoint - Point. - * @property {position_2d} mesh.meshpoint5x8 - MeshPoint5x8. - * @property {bool} mesh.meshpoint5x8.separate=On - Separate. - * @property {double} mesh.meshpoint5x8.x=10 - Pos x. - * @property {double} mesh.meshpoint5x8.y=12 - Pos y. - * @property {point_2d} mesh.meshpoint5x8.2dpoint - Point. - * @property {position_2d} mesh.meshpoint5x9 - MeshPoint5x9. - * @property {bool} mesh.meshpoint5x9.separate=On - Separate. - * @property {double} mesh.meshpoint5x9.x=12 - Pos x. - * @property {double} mesh.meshpoint5x9.y=12 - Pos y. - * @property {point_2d} mesh.meshpoint5x9.2dpoint - Point. - * @property {int} mesh.rows=4 - Rows. - * @property {int} mesh.columns=4 - Columns. - * @property {position_2d} origin - Origin. - * @property {bool} origin.separate=On - Separate. - * @property {double} origin.x=0 - Pos x. - * @property {double} origin.y=0 - Pos y. - * @property {point_2d} origin.2dpoint - Point. - * @property {double} width=12 - Width. - * @property {double} height=12 - Height. - * @property {generic_enum} [deformationquality="Very High"] - Deformation Quality. - */ - - -/** - * Attributes present in the node of type: 'EXTERNAL' - * @name NodeTypes#External - * @property {string} program_name - External Program. - * @property {string} program_input - Program First Input File ($IN1). - * @property {string} program_input2 - Program Second Input File ($IN2). - * @property {string} program_output - Program Output File ($OUT). - * @property {string} extension=TGA - Extension ($EXT). - * @property {double} program_num_param=0 - Numerical Parameter 1 ($NUM). - * @property {bool} program_uniqueid=true - Generate Unique FileNames. - * @property {double} program_num_param_2=0 - Numerical Parameter 2 ($NUM2). - * @property {double} program_num_param_3=0 - Numerical Parameter 3 ($NUM3). - * @property {double} program_num_param_4=0 - Numerical Parameter 4 ($NUM4). - * @property {double} program_num_param_5=0 - Numerical Parameter 5 ($NUM5). - */ - - -/** - * Attributes present in the node of type: 'PointConstraint2' - * @name NodeTypes#Two-Points-Constraint - * @property {double} active=100 - Active. - * @property {double} volumemod=75 - Volume Modifier. - * @property {double} volumemax=200 - Volume Max. - * @property {double} volumemin=25 - Volume Min. - * @property {double} stretchmax=0 - Distance Max. - * @property {double} stretchmin=0 - Distance Min. - * @property {double} skewcontrol=0 - Skew Modifier. - * @property {double} smooth=0 - Smoothing. - * @property {double} balance=0 - Point Balance. - * @property {generic_enum} [flattentype="Allow 3D Transform"] - Flatten Type. - * @property {generic_enum} [transformtype="Translate"] - Transform Type. - * @property {generic_enum} [primaryport="Right"] - Primary Port. - */ - - -/** - * Attributes present in the node of type: 'COLOR_SCALE' - * @name NodeTypes#Colour-Scale - * @property {double} red=1 - Red. - * @property {double} green=1 - Green. - * @property {double} blue=1 - Blue. - * @property {double} alpha=1 - Alpha. - * @property {double} hue=1 - Hue. - * @property {double} hue_offset=0 - Hue Offset. - * @property {double} saturation=1 - Saturation. - * @property {double} value=1 - Value. - * @property {bool} clampneg=false - Clamp Negative. - * @property {bool} pre_multiplied_alpha=false - Pre-multiplied Alpha. - * @property {bool} invert_matte_port=false - Invert Matte. - */ - - -/** - * Attributes present in the node of type: 'LightPosition' - * @name NodeTypes#Light-Position - * @property {position_3d} position0 - Position. - * @property {bool} position0.separate=On - Separate. - * @property {double} position0.x=0 - Pos x. - * @property {double} position0.y=0 - Pos y. - * @property {double} position0.z=0 - Pos z. - * @property {path_3d} position0.3dpath - Path. - * @property {position_3d} position1 - Look at. - * @property {bool} position1.separate=On - Separate. - * @property {double} position1.x=1 - Pos x. - * @property {double} position1.y=0 - Pos y. - * @property {double} position1.z=0 - Pos z. - * @property {path_3d} position1.3dpath - Path. - */ - - -/** - * Attributes present in the node of type: 'SurfaceNormal' - * @name NodeTypes#Surface-Normal - * @property {generic_enum} [normalquality="Low"] - Surface Normal Quality. - */ - - -/** - * Attributes present in the node of type: 'FilterBanding' - * @name NodeTypes#Colour-Banding - * @property {double} threshold1=20 - Threshold 1. - * @property {color} colour1=ffffffff - Colour 1. - * @property {int} colour1.red=255 - Red. - * @property {int} colour1.green=255 - Green. - * @property {int} colour1.blue=255 - Blue. - * @property {int} colour1.alpha=255 - Alpha. - * @property {generic_enum} [colour1.preferred_ui="Separate"] - Preferred Editor. - * @property {double} blur1=0 - Blur 1. - * @property {double} threshold2=40 - Threshold 2. - * @property {color} colour2=ffffffff - Colour 2. - * @property {int} colour2.red=255 - Red. - * @property {int} colour2.green=255 - Green. - * @property {int} colour2.blue=255 - Blue. - * @property {int} colour2.alpha=255 - Alpha. - * @property {generic_enum} [colour2.preferred_ui="Separate"] - Preferred Editor. - * @property {double} blur2=0 - Blur 2. - * @property {double} threshold3=20 - Threshold 3. - * @property {color} colour3=ffffffff - Colour 3. - * @property {int} colour3.red=255 - Red. - * @property {int} colour3.green=255 - Green. - * @property {int} colour3.blue=255 - Blue. - * @property {int} colour3.alpha=255 - Alpha. - * @property {generic_enum} [colour3.preferred_ui="Separate"] - Preferred Editor. - * @property {double} blur3=0 - Blur 3. - * @property {double} threshold4=20 - Threshold 4. - * @property {color} colour4=ffffffff - Colour 4. - * @property {int} colour4.red=255 - Red. - * @property {int} colour4.green=255 - Green. - * @property {int} colour4.blue=255 - Blue. - * @property {int} colour4.alpha=255 - Alpha. - * @property {generic_enum} [colour4.preferred_ui="Separate"] - Preferred Editor. - * @property {double} blur4=0 - Blur 4. - * @property {bool} invert_matte_port=false - Invert Matte. - */ - - -/** - * Attributes present in the node of type: 'MATTE_RESIZE' - * @name NodeTypes#Matte-Resize - * @property {double} radius=0 - Radius. - */ - - -/** - * Attributes present in the node of type: 'IncreaseOpacity' - * @name NodeTypes#Increase-Opacity - * @property {double} factor=1.8000 - Factor. - * @property {bool} invert_matte_port=false - Invert Matte. - */ - - -/** - * Attributes present in the node of type: 'FLICKER_BLUR' - * @name NodeTypes#Anti-Flicker - * @property {double} radius=0 - Radius. - */ - - -/** - * Attributes present in the node of type: 'ObjectDefinition' - * @name NodeTypes#Volume-Object - * @property {int} objectid=1 - ID. - * @property {bool} cutvolumecues=false - Cut Volume Cues with Geometry. - * @property {bool} usegeometry=true - Use Drawing to Create Volume. - * @property {double} geometryintensity=50 - Elevation Baseline. - * @property {double} elevationmin=0 - Elevation Min. - * @property {double} elevationmax=1 - Elevation Max. - * @property {double} smoothness=1 - Elevation Smoothness. - * @property {bool} invertmask=false - Invert Height Matte. - */ - - -/** - * Attributes present in the node of type: 'LuminanceThreshold' - * @name NodeTypes#Luminance-Threshold - * @property {double} luminancethresholdthresh=75 - Threshold. - * @property {bool} luminancethresholdsoften=true - Soften Colours. - * @property {double} luminancethresholdgamma=1.5000 - Gamma Correction. - * @property {bool} luminancethresholdgrey=false - Output Greyscale Matte. - * @property {bool} invert_matte_port=false - Invert Matte. - */ - - -/** - * Attributes present in the node of type: 'PIXELATE' - * @name NodeTypes#Pixelate - * @property {bool} invert_matte_port=false - Invert Matte. - * @property {double} factor=0.0125 - Factor. - */ - - -/** - * Attributes present in the node of type: 'LightShader' - * @name NodeTypes#Light-Shader - * @property {generic_enum} [lighttype="Directional"] - Light Type. - * @property {double} floodangle=90 - Cone Angle. - * @property {double} floodsharpness=0 - Diffusion. - * @property {double} floodradius=2000 - Falloff. - * @property {double} pointelevation=200 - Light Source Elevation. - * @property {double} anglethreshold=90 - Surface Reflectivity. - * @property {generic_enum} [shadetype="Smooth"] - Shading Type. - * @property {double} bias=0.1000 - Bias. - * @property {double} exponent=2 - Abruptness. - * @property {color} lightcolor=ffc8c8c8 - Light Colour. - * @property {int} lightcolor.red=200 - Red. - * @property {int} lightcolor.green=200 - Green. - * @property {int} lightcolor.blue=200 - Blue. - * @property {int} lightcolor.alpha=255 - Alpha. - * @property {generic_enum} [lightcolor.preferred_ui="Separate"] - Preferred Editor. - * @property {bool} flatten=true - Flatten Fx. - * @property {bool} useimagecolor=false - Use image Colour. - * @property {double} imagecolorweight=50 - Image Colour Intensity. - * @property {bool} adjustlevel=false - Adjust Light Intensity. - * @property {double} adjustedlevel=75 - Intensity. - * @property {double} scale=1 - Multiplier. - * @property {bool} usesurface=false - Use Surface Lighting. - * @property {double} speculartransparency=100 - Specular Transparency. - * @property {double} specularity=100 - Specular Strength. - * @property {double} distancefalloff=0 - Distance Falloff. - */ - - -/** - * Attributes present in the node of type: 'DeformationRootModule' - * @name NodeTypes#Deformation-Root - * @property {generic_enum} [deformationquality="Very High"] - Quality. - */ - - -/** - * Attributes present in the node of type: 'DeformationSwitchModule' - * @name NodeTypes#Deformation-Switch - * @property {generic_enum} [vectorquality="Very High"] - Vector Quality. - * @property {double} fadeexponent=3 - Influence Fade Exponent. - * @property {bool} fadeinside=false - Fade Inside Zones. - * @property {int} enabledeformation=1 - Enable Deformation. - * @property {int} chainselectionreference=1 - Kinematic Chain Selection Reference. - */ - - -/** - * Attributes present in the node of type: 'AutoMuscleModule' - * @name NodeTypes#Auto-Muscle - * @property {bool} enableleft=true - Muscle Left. - * @property {double} leftstart=-3 - Left Start. - * @property {double} leftspan=1 - Left Span. - * @property {double} leftamplitude=0.2500 - Left Amplitude. - * @property {bool} enableright=true - Muscle Right. - * @property {bool} symmetric=false - Same as Left. - * @property {double} rightstart=-3 - Right Start. - * @property {double} rightspan=1 - Right Span. - * @property {double} rightamplitude=0.2500 - Right Amplitude. - */ - - -/** - * Attributes present in the node of type: 'AutoFoldModule' - * @name NodeTypes#Deformation-AutoFold - * @property {int} enable=1 - Enable AutoFold. - * @property {double} length=12 - Length. - */ - - -/** - * Attributes present in the node of type: 'DeformationScaleModule' - * @name NodeTypes#Deformation-Scale - * @property {bool} enableleft=true - Scale Left. - * @property {double} leftfadein=0 - Left Fade In. - * @property {double} leftfadeout=0 - Left Fade Out. - * @property {double} leftstart=0 - Left Start. - * @property {double} leftspan=1 - Left Span. - * @property {double} leftscale0=1 - Left Start Scale. - * @property {double} leftscale1=1 - Left End Scale. - * @property {double} lefthandleposition0=25 - Left Start Handle Position. - * @property {double} lefthandleposition1=25 - Left End Handle Position. - * @property {double} lefthandlescale0=1 - Left Start Handle Scale. - * @property {double} lefthandlescale1=1 - Left End Handle Scale. - * @property {bool} enableright=true - Scale Right. - * @property {bool} symmetric=false - Same as Left. - * @property {double} rightfadein=0 - Right Fade In. - * @property {double} rightfadeout=0 - Right Fade Out. - * @property {double} rightstart=0 - Right Start. - * @property {double} rightspan=1 - Right Span. - * @property {double} rightscale0=1 - Right Start Scale. - * @property {double} rightscale1=1 - Right End Scale. - * @property {double} righthandleposition0=25 - Right Start Handle Position. - * @property {double} righthandleposition1=25 - Right End Handle Position. - * @property {double} righthandlescale0=1 - Right Start Handle Scale. - * @property {double} righthandlescale1=1 - Right End Handle Scale. - */ - - -/** - * Attributes present in the node of type: 'DeformationWaveModule' - * @name NodeTypes#Deformation-Wave - * @property {bool} enableleft=true - Wave Left. - * @property {double} leftstart=0 - Left Start. - * @property {double} leftspan=10 - Left Span. - * @property {double} leftoffsett=0 - Left Offset Deformer. - * @property {double} leftamplitude=1 - Left Amplitude. - * @property {double} leftoffset=1 - Left Offset Scaling. - * @property {double} leftperiod=1 - Left Period. - * @property {bool} enableright=true - Wave Right. - * @property {bool} symmetric=false - Same as Left. - * @property {double} rightstart=0 - Right Start. - * @property {double} rightspan=10 - Right Span. - * @property {double} rightoffsett=0 - Right Offset Deformer. - * @property {double} rightamplitude=1 - Right Amplitude. - * @property {double} rightoffset=1 - Right Offset Scaling. - * @property {double} rightperiod=1 - Right Period. - */ - - -/** - * Attributes present in the node of type: 'FoldModule' - * @name NodeTypes#Deformation-Fold - * @property {int} enable=1 - Enable Fold. - * @property {double} t=1 - Where. - * @property {double} tbefore=1 - Span Before. - * @property {double} tafter=1 - Span After. - * @property {double} angle=0 - Orientation. - * @property {double} length=12 - Length. - */ - - -/** - * Attributes present in the node of type: 'DeformationUniformScaleModule' - * @name NodeTypes#Deformation-Uniform-Scale - * @property {double} scale=1 - Scale. - */ - - -/** - * Attributes present in the node of type: 'DEPTHBLUR' - * @name NodeTypes#Z-Buffer-Smoothing - * @property {double} histogram_range=80 - Histogram Range. - * @property {int} kernel_size=5 - Kernel Size. - */ - - -/** - * Attributes present in the node of type: 'ParticleExplosion' - * @name NodeTypes#Explosion - * @property {int} trigger=1 - Trigger. - * @property {double} explosionx=0 - X. - * @property {double} explosiony=0 - Y. - * @property {double} explosionz=0 - Z. - * @property {double} explosionradius=3 - Radius. - * @property {double} explosionsigma=1 - Sigma. - * @property {double} explosionmagnitude=5 - Magnitude. - * @property {double} explosionepsilon=0.0010 - Epsilon. - */ - - -/** - * Attributes present in the node of type: 'ParticleImageEmitter' - * @name NodeTypes#Image-Fracture - * @property {int} trigger=0 - Trigger. - * @property {double} ageatbirth=0 - Age at Birth. - * @property {double} ageatbirthstd=0 - Age at Birth Standard Deviation. - * @property {double} mass=1 - Particles Mass. - * @property {generic_enum} [typechoosingstrategy="Sequentially Assign Type Number"] - Type Generation Strategy. - * @property {int} particletype0=1 - Particle Type 0. - * @property {int} particletype1=1 - Particle Type 1. - * @property {double} particlesize=1 - Size over Age. - * @property {bool} overridevelocity=false - Align Initial Velocity. - * @property {generic_enum} [blend_mode="Normal"] - Blend Mode. - * @property {double} blendintensity=100 - Blend Intensity. - * @property {generic_enum} [colouringstrategy="Use Drawing Colour"] - Colouring Strategy. - * @property {color} particlecolour=ffffffff - Colour. - * @property {int} particlecolour.red=255 - Red. - * @property {int} particlecolour.green=255 - Green. - * @property {int} particlecolour.blue=255 - Blue. - * @property {int} particlecolour.alpha=255 - Alpha. - * @property {generic_enum} [particlecolour.preferred_ui="Separate"] - Preferred Editor. - * @property {bool} alignwithdirection=true - Align with Direction. - * @property {bool} userotation=false - Use Rotation of Particle. - * @property {bool} directionalscale=false - Directional Scale. - * @property {double} directionalscalefactor=1 - Directional Scale Exponent Factor. - * @property {bool} keepvolume=true - Keep Volume. - * @property {generic_enum} [blur="No Blur"] - Blur. - * @property {double} blurintensity=1 - Blur Intensity. - * @property {double} blurfallof=0.5000 - Falloff Rate. - * @property {bool} flipwithdirectionx=false - Flip X Axis to Match Direction. - * @property {bool} flipwithdirectiony=false - Flip Y Axis to Match Direction. - * @property {generic_enum} [alignwithdirectionaxis="Positive X"] - Axis to Align. - */ - - -/** - * Attributes present in the node of type: 'ParticleBounce' - * @name NodeTypes#Bounce - * @property {int} trigger=1 - Trigger. - * @property {double} friction=0.5000 - Friction. - * @property {double} resilience=0.5000 - Resilience. - * @property {double} cutoff=0.5000 - Cutoff Speed. - */ - - -/** - * Attributes present in the node of type: 'ParticleMove' - * @name NodeTypes#Move-Particles - * @property {int} trigger=1 - Trigger. - * @property {bool} moveage=false - Age Particles. - * @property {bool} moveposition=true - Move Position. - * @property {bool} moveangle=true - Move Angle. - * @property {bool} followeachother=false - Make Particles Follow each Other. - * @property {double} followintensity=1 - Follow Intensity. - */ - - -/** - * Attributes present in the node of type: 'ParticleKill' - * @name NodeTypes#Kill - * @property {int} trigger=1 - Trigger. - * @property {bool} handlenaturaldeth=true - Use Maximum Lifespan. - * @property {bool} killyounger=false - Kill Younger. - * @property {int} killyoungerthan=-1 - Kill Younger than. - * @property {bool} killolder=true - Kill Older. - * @property {int} killolderthan=100 - Kill Older than. - */ - - -/** - * Attributes present in the node of type: 'ParticleOrbit' - * @name NodeTypes#Orbit - * @property {int} trigger=1 - Trigger. - * @property {generic_enum} [strategy="Around Point"] - Orbit Type. - * @property {double} magnitude=1 - Magnitude. - * @property {double} v0x=0 - Point X. - * @property {double} v0y=0 - Point Y. - * @property {double} v0z=0 - Point Z. - * @property {double} v1x=0 - Direction X. - * @property {double} v1y=0 - Direction Y. - * @property {double} v1z=1 - Direction Z. - */ - - -/** - * Attributes present in the node of type: 'ParticleGravity' - * @name NodeTypes#Gravity - * @property {int} trigger=1 - Trigger. - * @property {bool} applygravity=true - Apply Gravity. - * @property {double} directionx=0 - X Direction. - * @property {double} directiony=-1 - Y Direction. - * @property {double} directionz=0 - Z Direction. - * @property {bool} relativegravity=false - Apply Gravity between Particles (Relative Gravity). - * @property {double} relativemagnitude=1 - Relative Gravity Magnitude. - * @property {double} relativegravityepsilon=0.0010 - Relative Gravity Epsilon. - * @property {double} relativegravitymaxradius=2 - Relative Gravity Maximum Distance. - */ - - -/** - * Attributes present in the node of type: 'Particle3dRegion' - * @name NodeTypes#3D-Region - * @property {generic_enum} [shapetype="Sphere"] - Type. - * @property {double} sizex=6 - Width. - * @property {double} sizey=6 - Height. - * @property {double} sizez=6 - Depth. - * @property {double} outerradius=6 - Max. - * @property {double} innerradius=0 - Min. - */ - - -/** - * Attributes present in the node of type: 'ParticleSink' - * @name NodeTypes#Sink - * @property {int} trigger=1 - Trigger. - * @property {bool} ifinside=false - Invert. - */ - - -/** - * Attributes present in the node of type: 'ParticleRandom' - * @name NodeTypes#Random-Parameter - * @property {int} trigger=1 - Trigger. - * @property {generic_enum} [parametertorandomize="Speed"] - Parameter. - */ - - -/** - * Attributes present in the node of type: 'ParticleVortex' - * @name NodeTypes#Vortex - * @property {int} trigger=1 - Trigger. - * @property {double} vortexx=0 - X Direction. - * @property {double} vortexy=12 - Y Direction. - * @property {double} vortexz=0 - Z Direction. - * @property {double} vortexradius=4 - Radius. - * @property {double} vortexexponent=1 - Exponent (1=cone). - * @property {double} vortexupspeed=0.0050 - Up Acceleration. - * @property {double} vortexinspeed=0.0050 - In Acceleration. - * @property {double} vortexaroundspeed=0.0050 - Around Acceleration. - */ - - -/** - * Attributes present in the node of type: 'ParticleWindFriction' - * @name NodeTypes#Wind-Friction - * @property {int} trigger=1 - Trigger. - * @property {double} windfrictionx=0 - Friction/Wind X. - * @property {double} windfrictiony=0 - Friction/Wind Y. - * @property {double} windfrictionz=0 - Friction/Wind Z. - * @property {double} windfrictionminspeed=0 - Min Speed. - * @property {double} windfrictionmaxspeed=10 - Max Speed. - */ - - -/** - * Attributes present in the node of type: 'ParticleRotationVelocity' - * @name NodeTypes#Rotation-Velocity - * @property {int} trigger=1 - Trigger. - * @property {double} w0=0 - Minimum. - * @property {double} w1=5 - Maximum. - * @property {generic_enum} [axisstrategy="Constant Axis"] - Axis Type. - * @property {double} v0x=0 - Axis0 X. - * @property {double} v0y=0 - Axis0 Y. - * @property {double} v0z=1 - Axis0 Z. - * @property {double} v1x=0 - Axis1 X. - * @property {double} v1y=1 - Axis1 Y. - * @property {double} v1z=0 - Axis1 Z. - */ - - -/** - * Attributes present in the node of type: 'ParticleRepulse' - * @name NodeTypes#Repulse - * @property {int} trigger=1 - Trigger. - * @property {double} magnitude=1 - Magnitude. - * @property {double} lookahead=1 - Look Ahead. - * @property {double} epsilon=0.0010 - Epsilon. - */ - - -/** - * Attributes present in the node of type: 'ParticleJavascript' - * @name NodeTypes#Scripted-Action[Beta] - * @property {int} trigger=1 - Trigger. - * @property {file_editor} particle_action_script - . - * @property {file_library} files - . - */ - - -/** - * Attributes present in the node of type: 'ParticleVelocity' - * @name NodeTypes#Velocity - * @property {int} trigger=1 - Trigger. - * @property {generic_enum} [velocitytype="Constant Speed"] - Velocity Type. - * @property {double} v0x=1 - X. - * @property {double} v0y=0 - Y. - * @property {double} v0z=0 - Z. - * @property {double} minspeed=0.5000 - Minimum. - * @property {double} maxspeed=0.5000 - Maximum. - * @property {double} theta0=0 - Minimum Angle (degrees). - * @property {double} theta1=30 - Maximum Angle (degrees). - * @property {bool} bilateral=false - Bilateral. - */ - - -/** - * Attributes present in the node of type: 'ParticleSize' - * @name NodeTypes#Size - * @property {int} trigger=1 - Trigger. - * @property {generic_enum} [sizestrategy="Constant Size"] - Size Type. - * @property {double} particlesize=1 - Size. - */ - - -/** - * Attributes present in the node of type: 'ParticlePlanarRegion' - * @name NodeTypes#Planar-Region - * @property {generic_enum} [shapetype="Rectangle"] - Shape Type. - * @property {double} sizex=12 - Width. - * @property {double} sizey=12 - Height. - * @property {double} x1=0 - X. - * @property {double} y1=0 - Y. - * @property {double} x2=0 - X. - * @property {double} y2=0 - Y. - * @property {double} x3=1 - X. - * @property {double} y3=1 - Y. - * @property {double} minradius=0 - Minimum. - * @property {double} maxradius=6 - Maximum. - * @property {bool} mirrornegativeframes=false - Mirror Negative Frames. - */ - - -/** - * Attributes present in the node of type: 'ParticleBkerComposite' - * @name NodeTypes#Baker-Composite - */ - - -/** - * Attributes present in the node of type: 'ParticleSprite' - * @name NodeTypes#Sprite-Emitter - * @property {int} trigger=1 - Trigger. - * @property {double} ageatbirth=0 - Age at Birth. - * @property {double} ageatbirthstd=0 - Age at Birth Standard Deviation. - * @property {double} mass=1 - Particles Mass. - * @property {generic_enum} [typechoosingstrategy="Sequentially Assign Type Number"] - Type Generation Strategy. - * @property {int} particletype0=1 - Particle Type 0. - * @property {int} particletype1=1 - Particle Type 1. - * @property {double} particlesize=1 - Size over Age. - * @property {bool} overridevelocity=false - Align Initial Velocity. - * @property {generic_enum} [blend_mode="Normal"] - Blend Mode. - * @property {double} blendintensity=100 - Blend Intensity. - * @property {generic_enum} [colouringstrategy="Use Drawing Colour"] - Colouring Strategy. - * @property {color} particlecolour=ffffffff - Colour. - * @property {int} particlecolour.red=255 - Red. - * @property {int} particlecolour.green=255 - Green. - * @property {int} particlecolour.blue=255 - Blue. - * @property {int} particlecolour.alpha=255 - Alpha. - * @property {generic_enum} [particlecolour.preferred_ui="Separate"] - Preferred Editor. - * @property {bool} alignwithdirection=true - Align with Direction. - * @property {bool} userotation=false - Use Rotation of Particle. - * @property {bool} directionalscale=false - Directional Scale. - * @property {double} directionalscalefactor=1 - Directional Scale Exponent Factor. - * @property {bool} keepvolume=true - Keep Volume. - * @property {generic_enum} [blur="No Blur"] - Blur. - * @property {double} blurintensity=1 - Blur Intensity. - * @property {double} blurfallof=0.5000 - Falloff Rate. - * @property {bool} flipwithdirectionx=false - Flip X Axis to Match Direction. - * @property {bool} flipwithdirectiony=false - Flip Y Axis to Match Direction. - * @property {generic_enum} [alignwithdirectionaxis="Positive X"] - Axis to Align. - * @property {generic_enum} [renderingstrategy="Use Particle Type"] - Rendering Strategy. - * @property {generic_enum} [cycletype="No Cycle"] - Cycling. - * @property {int} cyclesize=5 - Number of Drawings in Cycle. - * @property {int} numberofparticles=100 - Number of Particles. - * @property {double} probabilityofgeneratingparticles=100 - Probability of Generating Any Particles. - * @property {int} indexselector=0 - Selector. - * @property {double} multisize=1 - Region Size for Baked Particle Input. - * @property {bool} copyvelocity=false - Copy Particle Velocity for Baked Particle Input. - * @property {double} mininitialangle=0 - Minimum Initial Rotation. - * @property {double} maxinitialangle=0 - Maximum Initial Rotation. - * @property {bool} copyage=false - Add Particle Age for Baked Particle Input. - * @property {bool} applyprobabilityforeachparticle=true - Apply Probability for Each Particle. - * @property {double} sourcetimespan=0 - Source Sampling Duration. - * @property {double} sourcesamplesperframe=16 - Source Samples per Frame. - * @property {int} seed=0 - Streak Seed. - * @property {double} streaksize=0 - Streak Size. - * @property {double} sourcetimeoffset=0 - Source Sampling Time Offset. - * @property {bool} setmaxlifespan=false - Set Maximum Lifespan. - * @property {double} maxlifespan=30 - Maximum Lifespan. - * @property {double} maxlifespansigma=0 - Maximum Lifespan Sigma. - */ - - -/** - * Attributes present in the node of type: 'ParticleRegionComposite' - * @name NodeTypes#Particle-Region-Composite - */ - - -/** - * Attributes present in the node of type: 'ParticleSystemComposite' - * @name NodeTypes#Particle-System-Composite - */ - - -/** - * Attributes present in the node of type: 'LensFlare' - * @name NodeTypes#LensFlare - * @property {generic_enum} [blend_mode="Normal"] - Blend Mode. - * @property {generic_enum} [flash_blend_mode="Normal"] - SWF Blend Mode. - * @property {bool} usergba=false - Blend Mode: Normal/Screen. - * @property {bool} brightenable=true - On/Off. - * @property {double} brightness=100 - Intensity. - * @property {color} brightcolor=ffffffff - Color. - * @property {int} brightcolor.red=255 - Red. - * @property {int} brightcolor.green=255 - Green. - * @property {int} brightcolor.blue=255 - Blue. - * @property {int} brightcolor.alpha=255 - Alpha. - * @property {generic_enum} [brightcolor.preferred_ui="Separate"] - Preferred Editor. - * @property {double} positionx=6 - PositionX. - * @property {double} positiony=6 - PositionY. - * @property {double} positionz=0 - PositionZ. - * @property {generic_enum} [flareconfig="Type 1"] - Flare Type. - * @property {bool} enable1=true - Enable/Disable. - * @property {double} size1=0.7500 - Size. - * @property {double} position1=0 - Position. - * @property {int} drawing1=1 - Drawing. - * @property {double} blur1=0 - Blur Intensity. - * @property {bool} enable2=true - Enable/Disable. - * @property {double} size2=0.8000 - Size. - * @property {double} position2=2 - Position. - * @property {int} drawing2=2 - Drawing. - * @property {double} blur2=0 - Blur Intensity. - * @property {bool} enable3=true - Enable/Disable. - * @property {double} size3=1.2000 - Size. - * @property {double} position3=-0.2000 - Position. - * @property {int} drawing3=3 - Drawing. - * @property {double} blur3=0 - Blur Intensity. - * @property {bool} enable4=true - Enable/Disable. - * @property {double} size4=0.6500 - Size. - * @property {double} position4=0.7500 - Position. - * @property {int} drawing4=4 - Drawing. - * @property {double} blur4=0 - Blur Intensity. - * @property {bool} enable5=true - Enable/Disable. - * @property {double} size5=1 - Size. - * @property {double} position5=2 - Position. - * @property {int} drawing5=5 - Drawing. - * @property {double} blur5=0 - Blur Intensity. - * @property {bool} enable6=true - Enable/Disable. - * @property {double} size6=1 - Size. - * @property {double} position6=0 - Position. - * @property {int} drawing6=6 - Drawing. - * @property {double} blur6=0 - Blur Intensity. - * @property {bool} enable7=true - Enable/Disable. - * @property {double} size7=0.8000 - Size. - * @property {double} position7=2 - Position. - * @property {int} drawing7=7 - Drawing. - * @property {double} blur7=0 - Blur Intensity. - * @property {bool} enable8=true - Enable/Disable. - * @property {double} size8=0.5500 - Size. - * @property {double} position8=-0.3000 - Position. - * @property {int} drawing8=8 - Drawing. - * @property {double} blur8=0 - Blur Intensity. - * @property {bool} enable9=true - Enable/Disable. - * @property {double} size9=0.6500 - Size. - * @property {double} position9=1.2500 - Position. - * @property {int} drawing9=9 - Drawing. - * @property {double} blur9=0 - Blur Intensity. - * @property {bool} enable10=true - Enable/Disable. - * @property {double} size10=0.5500 - Size. - * @property {double} position10=2.3000 - Position. - * @property {int} drawing10=10 - Drawing. - * @property {double} blur10=0 - Blur Intensity. - */ - - -/** - * Attributes present in the node of type: 'CROP' - * @name NodeTypes#Crop - * @property {int} res_x=1920 - X Resolution. - * @property {int} res_y=1080 - Y Resolution. - * @property {double} offset_x=0 - X Offset. - * @property {double} offset_y=0 - Y Offset. - * @property {bool} draw_frame=false - Draw Frame. - * @property {color} frame_color=ffffffff - Frame Color. - * @property {int} frame_color.red=255 - Red. - * @property {int} frame_color.green=255 - Green. - * @property {int} frame_color.blue=255 - Blue. - * @property {int} frame_color.alpha=255 - Alpha. - * @property {generic_enum} [frame_color.preferred_ui="Separate"] - Preferred Editor. - * @property {enable} [enabling="Always Enabled"] - Enabling. - * @property {generic_enum} [enabling.filter="Always Enabled"] - Filter. - * @property {string} enabling.filter_name - Filter name. - * @property {int} enabling.filter_res_x=720 - X resolution. - * @property {int} enabling.filter_res_y=540 - Y resolution. - */ - - -/** - * Attributes present in the node of type: 'GLUE' - * @name NodeTypes#Glue - * @property {bool} invert_matte_port=true - Invert Matte. - * @property {double} bias=0.5000 - Bias. - * @property {double} tension=1 - Tension. - * @property {generic_enum} [type="Curve"] - Type. - * @property {bool} use_z=true - Use Z for Composition Order. - * @property {bool} a_over_b=true - A Over B. - * @property {bool} spread_a=false - Spread A. - */ - - -/** - * Attributes present in the node of type: 'DeformTransformOut' - * @name NodeTypes#Point-Kinematic-Output - * @property {generic_enum} [sample="One-Point Sampling"] - Sampling Type. - * @property {position_2d} pivot1 - Main Position Tracker. - * @property {bool} pivot1.separate=Off - Separate. - * @property {double} pivot1.x=0 - Pos x. - * @property {double} pivot1.y=0 - Pos y. - * @property {point_2d} pivot1.2dpoint - Point. - * @property {position_2d} pivot2 - Tracker 2. - * @property {bool} pivot2.separate=Off - Separate. - * @property {double} pivot2.x=1 - Pos x. - * @property {double} pivot2.y=0 - Pos y. - * @property {point_2d} pivot2.2dpoint - Point. - * @property {position_2d} pivot3 - Tracker 3. - * @property {bool} pivot3.separate=Off - Separate. - * @property {double} pivot3.x=0 - Pos x. - * @property {double} pivot3.y=1 - Pos y. - * @property {point_2d} pivot3.2dpoint - Point. - * @property {double} volume=1 - Volume Modifier. - */ - - -/** - * Attributes present in the node of type: 'AmbientOcclusion' - * @name NodeTypes#Ambient-Occlusion - * @property {double} darkness=200 - Darkness. - * @property {double} zrange=1 - Shadow Max Depth Range. - * @property {double} bias=0 - Shadow Bias. - * @property {double} exponent=1 - Abruptness. - * @property {double} gamma=2 - Shadow Gamma. - * @property {double} blur=10 - Affected Range. - * @property {double} postblur=0 - Post-Blur. - * @property {double} postblurthreshold=0.1000 - Post-Blur Depth Threshold. - * @property {bool} useimagecolor=false - Use Image Colour. - * @property {color} color=ff000000 - Light Colour. - * @property {int} color.red=0 - Red. - * @property {int} color.green=0 - Green. - * @property {int} color.blue=0 - Blue. - * @property {int} color.alpha=255 - Alpha. - * @property {generic_enum} [color.preferred_ui="Separate"] - Preferred Editor. - * @property {double} imagecolorweight=50 - Image Colour Intensity. - * @property {bool} invert_matte_port=false - Invert Matte. - */ - - -/** - * Attributes present in the node of type: 'SHADOW' - * @name NodeTypes#Shadow - * @property {bool} truck_factor=true - Truck Factor. - * @property {generic_enum} [blur_type="Radial"] - Blur Type. - * @property {double} radius=2 - Radius. - * @property {double} directional_angle=0 - Directional Angle. - * @property {double} directional_falloff_rate=1 - Directional Falloff Rate. - * @property {bool} use_matte_color=false - Use Source Colour. - * @property {bool} invert_matte=false - Invert Matte. - * @property {color} color=649c9c9c - Color. - * @property {int} color.red=-100 - Red. - * @property {int} color.green=-100 - Green. - * @property {int} color.blue=-100 - Blue. - * @property {int} color.alpha=100 - Alpha. - * @property {generic_enum} [color.preferred_ui="Separate"] - Preferred Editor. - * @property {bool} multiplicative=false - Multiplicative. - * @property {double} colour_gain=1 - Intensity. - */ diff --git a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_nodeLink.js b/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_nodeLink.js deleted file mode 100644 index 07a4d147da..0000000000 --- a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_nodeLink.js +++ /dev/null @@ -1,1713 +0,0 @@ -////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// -// -// openHarmony Library v0.01 -// -// -// Developed by Mathieu Chaptel, Chris Fourney... -// -// -// This library is an open source implementation of a Document Object Model -// for Toonboom Harmony. It also implements patterns similar to JQuery -// for traversing this DOM. -// -// Its intended purpose is to simplify and streamline toonboom scripting to -// empower users and be easy on newcomers, with default parameters values, -// and by hiding the heavy lifting required by the official API. -// -// This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is guaranteed to work. Feel free to contribute -// improvements to its official github. If you do make sure you follow the provided -// template and naming conventions and document your new methods properly. -// -// This library doesn't overwrite any of the objects and classes of the official -// Toonboom API which must remains available. -// -// This library is made available under the MIT license. -// https://opensource.org/licenses/mit -// -// The repository for this library is available at the address: -// https://github.com/cfourney/OpenHarmony/ -// -// -// For any requests feel free to contact m.chaptel@gmail.com -// -// -// -// -////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oNodeLink class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * The base class for the oTimeline. - * @constructor - * @classdesc oTimeline Base Class - * @param {oNode} outNode The source oNode of the link. - * @param {int} outPort The outport of the outNode that is connecting the link. - * @param {oNode} inNode The destination oNode of the link. - * @param {int} inPort The inport of the inNode that is connecting the link. - * - * @property {bool} autoDisconnect Whether to auto-disconnect links if they already exist. Defaults to true. - * @example - * //Connect two pegs together. - * var peg1 = $.scene.getNodeByPath( "Top/Peg1" ); - * var peg2 = $.scene.getNodeByPath( "Top/Peg2" ); - * - * //Create a new $.oNodeLink -- We'll connect two pegs with this new nodeLink. - * var link = new $.oNodeLink( peg1, //Out Node - * 0, //Out Port - * peg2, //In Node - * 0 ); //In Port - * - * //The node link doesn't exist yet, but lets apply it. - * link.apply(); - * //This connection between peg1 and peg2 now exists. - * - * //We can also get the outlinks for the entire node and all of its outputs. - * var outLinks = peg2.outLinks; - * - * //Lets connect peg3 to the chain with this existing outLink. This will use an existing link if its already there, or create a new one if none exists. - * var peg3 = $.scene.getNodeByPath( "Top/Peg3" ); - * outLinks[0].linkIn( peg3, 0 ); - * - * //Uh oh! We need to connect a peg between 1 and 2. - * var peg4 = $.scene.getNodeByPath( "Top/Peg4" ); - * - * //The link we already created above can have a node inserted between it easily. - * link.insertNode( peg4, 0, 0 ); //Peg to insert, in port, out port. - * - * //Oh no! Peg 5 is in a group. Well, it still works! - * var peg5 = $.scene.getNodeByPath( "Top/Group/Peg5" ); - * var newLink = peg1.addOutLink( peg5 ); - */ -$.oNodeLink = function( outNode, outPort, inNode, inPort, outlink ){ - - //Public properties. - this.autoDisconnect = true; - this.path = false; - - //Private properties. - this._outNode = outNode; - this._outPort = outPort; - this._outLink = outlink; - - this._realOutNode = outNode; - this._realOutPort = 0; - - this._inNode = inNode; - this._inPort = inPort; - - this._stopUpdates = false; - this._newInNode = null; - this._newInPort = null; - this._newOutNode = null; - this._newOutPort = null; - this._exists = false; - this._validated = false; - - //Assume validation when providing all details. This is done to speed up subsequent lookups. - if( outNode && - inNode && - typeof outPort === 'number' && - typeof inPort === 'number' && - typeof outlink === 'number' - ){ - - //Skip validation in the event that we've beengiven all details -- this is to just speed up list generation. - return; - } - - this.validate(); -} - - -/** - * Whether the nodeLink exists in the provided state. - * @name $.oNodeLink#exists - * @type {bool} - * @example - * //Connect two pegs together. - * var peg1 = $.scene.getNodeByPath( "Top/Peg1" ); - * var peg2 = $.scene.getNodeByPath( "Top/NodeDoesntExist" ); - * var link = new $.oNodeLink( peg1, //Out Node - * 0, //Out Port - * peg2, //In Node - * 0 ); //In Port - * link.exists == false; //FALSE, This link doesnt exist in this context, because the node doesnt exist. - */ -Object.defineProperty($.oNodeLink.prototype, 'exists', { - get : function(){ - if( !this._validated ){ - this.validate(); - } - return this._exists; - } -}); - - -/** - * The outnode of this $.oNodeLink. The outNode that is outputting the connection for this link on its outPort and outLink. - * @name $.oNodeLink#outNode - * @type {$.oNode} - */ -Object.defineProperty($.oNodeLink.prototype, 'outNode', { - get : function(){ - return this._outNode; - - }, - set : function( val ){ - this._validated = false; - this._newOutNode = val; - - if( this.stopUpdates ){ - return; - } - - this.apply(); // do we really want to apply every time we set? - } -}); - - -/** - * The inNode of this $.oNodeLink. The inNode that is accepting this link on its inport. - * @name $.oNodeLink#inNode - * @type {$.oNode} - */ -Object.defineProperty($.oNodeLink.prototype, 'inNode', { - get : function(){ - return this._inNode; - }, - - set : function( val ){ - //PATH FIND UP TO THE INNODE. - this._validated = false; - this._newInNode = val; - - if( this.stopUpdates ){ - return; - } - - this.apply(); // do we really want to apply every time we set? - } -}); - - -/** - * The outport of this $.oNodeLink. The port that the outNode connected to for this link. - * @name $.oNodeLink#outPort - * @type {int} - */ -Object.defineProperty($.oNodeLink.prototype, 'outPort', { - get : function(){ - return this._outPort; - - }, - - set : function( val ){ - this._validated = false; - this._newOutPort = val; - - if( this.stopUpdates ){ - return; - } - - this.apply(); // do we really want to apply every time we set? - } -}); - - -/** - * The outLink of this $.oNodeLink. The link index that the outNode connected to for this link. - * @name $.oNodeLink#outLink - * @type {int} - */ -Object.defineProperty($.oNodeLink.prototype, 'outLink', { - get : function(){ - return this._outLink; - } -}); - - -/** - * The inPort of this $.oNodeLink. - * @name $.oNodeLink#inPort - * @type {oNode[]} - */ -Object.defineProperty($.oNodeLink.prototype, 'inPort', { - get : function(){ - return this._inPort; - }, - set : function( val ){ - this._validated = false; - this._newInPort = val; - - if( this.stopUpdates ){ - return; - } - - this.apply(); // do we really want to apply every time we set? - } -}); - - -/** - * When enabled, changes to the link will no longer update -- the changes will then apply when no longer stopped. - * @name $.oNodeLink#stopUpdates - * @private - * @type {bool} - */ -Object.defineProperty($.oNodeLink.prototype, 'stopUpdates', { - get : function(){ - return this._stopUpdates; - }, - set : function( val ){ - this._stopUpdates = val; - - if( !val ){ - this.apply(); - } - } -}); - - -/** - * Dereferences up a node's chain, in order to find the exact node its actually attached to. - * @private - * @param {oNode} onode The node to dereference the groups for. - * @param {int} port The port to dereference. - * @param {object[]} path The array path to pass along recursively.
[ { "node": src_node, "port":srcNodeInfo.port, "link":srcNodeInfo.link } ] - * @private - * @return {object} Object in form { "node":oNode, "port":int, "link": int } - */ -$.oNodeLink.prototype.findInputPath = function( onode, port, path ) { - var srcNodeInfo = node.srcNodeInfo( onode.path, port ); - if( !srcNodeInfo ){ - return path; - } - - var src_node = this.$.scene.getNodeByPath( srcNodeInfo.node ); - if( !src_node ){ - return path; - } - - if( src_node.type == "MULTIPORT_IN" ){ - //Continue to dereference until we find something other than a group/multiport in. - var ret = { "node": src_node, "port":srcNodeInfo.port, "link":srcNodeInfo.link }; - path.push( ret ); - - var src_node = src_node.group; - - var ret = { "node": src_node, "port":srcNodeInfo.port, "link":srcNodeInfo.link }; - path.push( ret ); - }else if( src_node.type == "GROUP" ){ - //Continue to dereference until we find something other than a group/multiport out. - var ret = { "node": src_node, "port":srcNodeInfo.port, "link":srcNodeInfo.link }; - path.push( ret ); - - var src_node = src_node.multiportOut; - - var ret = { "node": src_node, "port":srcNodeInfo.port, "link":srcNodeInfo.link }; - path.push( ret ); - }else{ - var ret = { "node": src_node, "port":srcNodeInfo.port, "link":srcNodeInfo.link }; - path.push( ret ); - return path; - } - - return this.findInputPath( src_node, srcNodeInfo.port, path ); -} - - -/** - * Changes both the in-node and in-port at once. - * @param {oNode} onode The node to link on the input. - * @param {int} port The port to link on the input. - * @example - * //Connect two pegs together. - * var peg1 = $.scene.getNodeByPath( "Top/Peg1" ); - * var peg2 = $.scene.getNodeByPath( "Top/Peg2" ); - * - * var outLinks = peg1.outLinks; - * outLinks[0].linkIn( peg2, 0 ); //Links the input of peg2, port 0 -- to this link, connecting its outNode [peg1] and outPort [0] and outLink [arbitrary]. - */ -$.oNodeLink.prototype.linkIn = function( onode, port ) { - this._validated = false; - var stopUpdates_val = this.stopUpdates; - this.stopUpdates = true; - - this.inNode = onode; - this.inPort = port; - - this.stopUpdates = stopUpdates_val; -} - - -/** - * Changes both the out-node and out-port at once. - * @param {oNode} onode The node to link on the output. - * @param {int} port The port to link on the output. - * @example - * //Connect two pegs together. - * var peg1 = $.scene.getNodeByPath( "Top/Peg1" ); - * var peg2 = $.scene.getNodeByPath( "Top/Peg2" ); - * - * var inLinks = peg1.inLinks; - * inLinks[0].linkOut( peg2, 0 ); //Links the output of peg2, port 0 -- to this link, connecting its inNode [peg1] and inPort [0]. - */ -$.oNodeLink.prototype.linkOut = function( onode, port ) { - this._validated = false; - - var stopUpdates_val = this.stopUpdates; - this.stopUpdates = true; - - this.outNode = onode; - this.outPort = port; - - this.stopUpdates = stopUpdates_val; -} - - -/** - * Insert a node in the middle of the link chain. - * @param {oNode} nodeToInsert The node to link on the output. - * @param {int} inPort The port to link on the output. - * @param {int} outPort The port to link on the output. - * @example - * //Connect two pegs together. - * var peg1 = $.scene.getNodeByPath( "Top/Peg1" ); - * var peg2 = $.scene.getNodeByPath( "Top/Peg2" ); - * - * //Create a new $.oNodeLink -- We'll connect two pegs with this new nodeLink. - * var link = new $.oNodeLink( peg1, //Out Node - * 0, //Out Port - * peg2, //In Node - * 0 ); //In Port - * - * //The link we already created above can have a node inserted between it easily. - * var peg4 = $.scene.getNodeByPath( "Top/Peg4" ); - * link.insertNode( peg4, 0, 0 ); //Peg to insert, in port, out port. - */ -$.oNodeLink.prototype.insertNode = function( nodeToInsert, inPort, outPort ) { - this.stopUpdates = true; - - var inNode = this.inNode; - var inPort = this.inPort; - - this.inNode = nodeToInsert; - this.inport = inPort; - - this.stopUpdates = false; - - var new_link = new this.$.oNodeLink( nodeToInsert, outPort, inNode, inPort, 0 ); - new_link.apply( true ); -} - -/** - * Apply the links as needed after unfreezing the oNodeLink - * @param {bool} force Forcefully reconnect/disconnect the note given the current settings of this nodelink. - * @example - * //Connect two pegs together. - * var peg1 = $.scene.getNodeByPath( "Top/Peg1" ); - * var peg2 = $.scene.getNodeByPath( "Top/Peg2" ); - * - * //Create a new $.oNodeLink -- We'll connect two pegs with this new nodeLink. - * var link = new $.oNodeLink( peg1, //Out Node - * 0, //Out Port - * peg2, //In Node - * 0 ); //In Port - * - * //The node link doesn't exist yet, but lets apply it. - * link.apply(); - */ -$.oNodeLink.prototype.apply = function( force ) { - this._stopUpdates = false; - this._validated = false; // ? Shouldn't we use this to bypass application if it's already been validated? - - var disconnect_in = false; - var disconnect_out = false; - var inports_removed = {}; - var outports_removed = {}; - - if( force || !this._exists ){ //Apply this. - this._newInNode = this._newInNode ? this._newInNode : this._inNode; - this._newOutNode = this._newOutNode ? this._newOutNode : this._outNode; - this._newOutPort = ( this._newOutPort === null ) ? this._outPort : this._newOutPort; - this._newInPort = ( this._newInPort === null ) ? this._inPort : this._newInPort; - - var force = true; - - disconnect_in = true; - disconnect_out = true; - }else{ - - //Force a reconnect -- track content as needed. - //Check and validate in ports. - var target_port = this._inPort; - if( this._newInPort !== null ){ - if( this._newInPort != this._inPort ){ - target_port = this._newInPort; - disconnect_in = true; - } - } - - var old_inPortCount = false; //Used to track if the inport count has changed upon its removal. - if( this._newInNode !== null ){ - if( this._newInNode ){ - if( !this._inNode || ( this._inNode.path != this._newInNode.path ) ){ - disconnect_in = true; - } - }else if( this._inNode ){ - disconnect_in = true; - } - } - - //Check and validate out ports. - if( this._newOutPort !== null ){ - if( ( this._newOutPort !== this._outPort ) ){ - disconnect_out = true; - } - } - - if( this._newOutNode !== null ){ - if( this._newOutNode ){ - if( !this._outNode || ( this._outNode.path != this._newOutNode.path ) ){ - disconnect_out = true; - } - }else if( this._outNode ){ - disconnect_out = true; - } - } - } - - if( !disconnect_in && !disconnect_out ){ - //Nothing happened. - // System.println( "NOTHING TO DO" ); - return; - } - - if( this._newInNode ){ - // if( this._newInNode.inNodes.length > target_port ){ - if( this._newInNode.inPorts > target_port ){ - // if( this._newInNode.inNodes[ target_port ] ){ - if( node.isLinked(this._newInNode.path, target_port) ){ - //-- Theres already a connection here-- lets remove it. - if( this.autoDisconnect ){ - node.unlink (this._newInNode.path, target_port) - // this._newInNode.unlinkInPort( target_port ); - inports_removed[ this._newInNode.path ] = target_port; - }else{ - throw "Unable to link "+this._outNode+" to "+this._newInNode+", port "+target_port+" is already occupied."; - } - } - } - } - - //We'll work with the new values -- pretend any new connection is a new one. - this._newInNode = this._newInNode ? this._newInNode : this._inNode; - this._newOutNode = this._newOutNode ? this._newOutNode : this._outNode; - this._newOutPort = ( this._newOutPort === null ) ? this._outPort : this._newOutPort; - this._newInPort = ( this._newInPort === null ) ? this._inPort : this._newInPort; - - - if( !this._newInNode || !this._newOutNode ){ - //Nothing to attach. - this._inNode = this._newInNode; - this._inPort = this._newInPort; - this._outNode = this._newOutNode; - this._outPort = this._newOutPort; - - return; - } - - if( !this._newInNode.exists || !this._newOutNode.exists ){ - this._inNode = this._newInNode; - this._inPort = this._newInPort; - this._outNode = this._newOutNode; - this._outPort = this._newOutPort; - - return; - } - - - //Kill and rebuild the current connection - but first, calculate existing port indices so they can be reconnected contextually. - // var newInPortCount = this._newInNode ? this._newInNode.inNodes.length : 0; - var newInPortCount = this._newInNode ? this._newInNode.inPorts : 0; - // var newOutPortCount = this._newOutNode ? this._newOutNode.outNodes.length : 0; - var newOutPortCount = this._newOutNode ? this._newOutNode.outPorts : 0; - - //Unlink it anyway! Dont worry, we'll reattach that after. - if( this._inNode ){ - // this._inNode.unlinkInPort( this._inPort ); - node.unlink (this._inNode.path, this._inPort) - if( this._outNode ) outports_removed[ this._outNode.path ] = this._outPort; - inports_removed[ this._inNode.path ] = this._inPort; - } - - //Cant connect without a valid port. - if( ( this._newOutPort === null ) || ( this._newOutPort === false ) ){ - this._inNode = this._newInNode; - this._inPort = this._newInPort; - this._outNode = this._newOutNode; - this._outPort = this._newOutPort; - - return; - } - if( ( this._newInPort === null ) || ( this._newInPort === false ) ){ - this._inNode = this._newInNode; - this._inPort = this._newInPort; - this._outNode = this._newOutNode; - this._outPort = this._newOutPort; - - return; - } - - //Check to see if any of the port values have changed. - var newInPortCount_result = this._newInNode ? this._newInNode.inNodes.length : 0; - var newOutPortCount_result = this._newOutNode ? this._newOutNode.outNodes.length : 0; - - if( newOutPortCount_result != newOutPortCount ){ - //Outport might have changed. React appropriately. - if( this._newOutNode.path in outports_removed ){ - if( this._newOutPort > outports_removed[ this._newOutNode.path ] ){ - this._newOutPort-=1; - } - } - } - - if( newInPortCount_result != newInPortCount ){ - //Outport might have changed. React appropriately. - if( this._newInNode.path in inports_removed ){ - if( this._newInPort > inports_removed[ this._newInNode.path ] ){ - this._newInPort-=1; - } - } - } - - var new_inGroup = this._newInNode.group; - var new_outGroup = this._newOutNode.group; - if( new_inGroup.path == new_outGroup.path ){ - //Simple direct connection within the same group. - node.link( _newOutNode.path, this._newInPort, this._newInNode.path, this._newOutPort); - //this._newOutNode.linkOutNode( this._newInNode, this._newInPort, this._newOutPort ); MCNote: use the API so we can replace stuff into it later - - }else{ - //Look for an access route. - - var common_path = []; - var split_in = new_inGroup.path.split( "/" ); - var split_out = new_outGroup.path.split( "/" ); - - //Find the common top path. - for( var n=0;n= 0; n-- ){ - var t_path = inward_path[n]; - if( !t_path.exists ){ - // t_path.from.linkOutNode( t_path.to, t_path.fromport, t_path.toport, t_path.createPort ); - node.link(t_path.from.path, t_path.fromport, t_path.to.path, t_path.toport, t_path.createPort, t_path.createPort); - // System.println( "RESULT IN: " + t_path.from + " : " + t_path.fromport + " -- " + t_path.to + " : " + t_path.toport + " " + t_path.createPort ); - } - } - } - - this._inNode = this._newInNode; - this._inPort = this._newInPort; - this._outNode = this._newOutNode; - this._outPort = this._newOutPort; - - this._newInNode = null; - this._newInPort = null; - this._newOutNode = null; - this._newOutPort = null; - - if( !this.validate() ){ - throw ReferenceError( "Failed to connect the targets appropriately." ); - } -} - - -/** - * findInwardPath. Used internally when applying link. - * finds the sequence of groups to go into to find the node to connect from a higher level - * @private - * @return {path} an array of path node objects : { "end" : bool, - * "exists" : bool, - * "from" : oNode, - * "fromport" : int, - * "to" : oNode, - * "toport" : int, - * "createPort" : bool - * } - */ -$.oNodeLink.prototype.findInwardPath = function( createPort ){ - var from_node = this._outNode; - var from_port = this._outPort; - var targ_node = this._inNode; - var targ_port = this._inPort; - var path = []; - - var length_parent = from_node.group.path.split("/").length; - var targ_grp = targ_path_split.slice( 0, length_parent+1 ).join("/"); - - if( targ_grp == targ_path ){ - //Should it create the port? - - path.push( { "end": true, "exists":false, "from":from_node, "fromport":from_port, "to":targ_node, "toport":targ_port, "createPort":createPort } ); - return path; - } - - //Find a common link from this target to the next. - var grp = this.$.scene.getNodeByPath( targ_grp ); - var mport = grp.multiportIn; - // var followPort = mport.outNodes.length; - var followPort = mport.outPorts; - - //Find if the outnodes of from, at the given outNode, connects to the multiportOut already. - try{ - var found_existing = false; - var createPortForward = true; - // if( from_node.outNodes.length>from_port ){ - if( from_node.outPorts > from_port){ - // var ops = from_node.outNodes[from_port]; - var ops = from_node.getOutLinksNumber(from_port); - // for( var n=0; nport ){ - if( from_node.outPorts > port ){ - for( var n = 0; n < from_node.outPorts; n++ ){ - // if( from_node.outNodes[port][n].path == mport.path ){ - if( node.dstNode(from_node.path, port, n) == mport.path ){ - //Dont add it as a new connection, add it as an existing one. - var info = node.dstNodeInfo( from_node.path, port, n ); - if( info ){ - found_existing = true; - followPort = info.port; - break; - } - } - } - } - - path.push( { "end" : false, "exists":found_existing, "from":from_node, "fromport":port, "to":mport, "toport":followPort } ); - // path = find_outward( grp, followPort, targ, path ); - var checkLink = new this.$.oNodeLink(grp, followPort, this._inNode) - path = path.concat( checkLink.findOutwardPath()); - }catch(err){ - this.$.debug( "ERR: " + err.message + " " + err.lineNumber + " : " + err.fileName , this.$.DEBUG_LEVEL.ERROR); - } - - }else{ - path.push( { "end": true, "exists":true, "from":from_node, "fromport":port, "to":false, "toport":false } ); - } - - return path; -} - - -/** - * Validates the details of a given connection. Used internally when details change. - * @private - * @return {bool} Whether the connection is a valid connection that exists currently in the node system. - */ -$.oNodeLink.prototype.validate = function ( ) { - //Initialize the connection and get the information. - //First check to see if the path is valid. - this._exists = false; - this._validated = true; - - var inportProvided = !(!this._inPort && this._inPort!== 0); - var outportProvided = !(!this._outPort && this._outPort!== 0); - - if( !inportProvided && !outportProvided ){ - //inport is the safest to determine contextually. - //If either has 1 input. - if( this._inNode && this._inNode.inNodes.length == 1 ){ - this._inPort = 0; - inportProvided = true; - } - } - - if( !this._outNode && !this._inNode ){ - //Unable to comply, need at least the nodes. - this._exists = false; - return false; - }else if( !this._outNode ){ - //No outnode. Just look for one above it given the inport. - //Lets derive up the chain. - if( inportProvided ){ - this.validateUpwards( this._inPort ); - - if( !this.path || this.path.length==0 ){ - return false; - } - - this._outNode = this.path[ this.path.length-1 ].node; - this._outPort = this.path[ this.path.length-1 ].port; - this._outLink = this.path[ this.path.length-1 ].link; - - this._realOutNode = this.path[ 0 ].node; - this._realOutPort = this.path[ 0 ].port; - this._realOutLink = this.path[ 0 ].link; - - this._exists = true; - return true; - } - }else if( !this._inNode ){ - //There can be multiple links. This is very difficult and only possible if theres only a singular path, we'll have to derive them all downwards. - //This is just hopeful thinking that there is only one valid path. - - this._outLink = this._outLink ? this._outLink : 0; - - var huntInNode = function( currentNode, port, link ){ - try{ - // var on = currentNode.outNodes[port]; - var numOutLinks = currentNode.getOutLinksNumber(port); - - // if( on.length != 1 ){ - if( numOutLinks != 1 ){ - return false; - } - - var dstNodeInfo = node.dstNodeInfo( currentNode.path, port, link ); - if( !dstNodeInfo ){ - return false; - } - - var outNode = this.$.scene.getNodeByPath(node.dstNode( currentNode.path, port, 0 )) - - // if( on[0].type == "MULTIPORT_OUT" ){ - if( outNode.type == "MULTIPORT_OUT" ){ - return huntInNode( currentNode.grp, dstNodeInfo.port ); - // }else if( on[0].type == "GROUP" ){ - }else if( outNode.type == "GROUP" ){ - return huntInNode( outNode.multiportIn, dstNodeInfo.port, dstNodeInfo.link ); - }else{ - // var ret = { "node": on[0], "port":dstNodeInfo.port }; - var ret = { "node": outNode, "port":dstNodeInfo.port }; - return ret; - } - }catch(err){ - this.$.debug( err , this.$.DEBUG_LEVEL.ERROR); - return false; - } - } - - //Find the in node recursively. - var res = huntInNode( this._outNode, this._outPort, this._outLink ); - if( !res ){ - this._exists = false; - return false; - } - - if( inportProvided ){ - if( res.port != this._inPort ){ - this._exists = false; - return false; - } - } - - this._inNode = res.node; - this._inPort = res.port; - inportProvided = true; - } - - if( !this._outNode || !this._inNode ){ - this._exists = false; - return false; - } - - if( !inportProvided && !outportProvided ){ - //Still no ports provided. - //Just simply assume the 0 port on the input. - this._inPort = 0; - inportProvided = true; - } - - if( !inportProvided ){ - //Derive upwards for each input, if its valid, keep it. - var inNodes = this._inNode.inNodes; - for( var n=0;n - * A $.oLink object is always describing just one connection between two nodes in the same group. For distant nodes in separate groups, use $.oLinkPath. - * @constructor - * @param {$.oNode} outNode The node from which the link is coming out. - * @param {$.oNode} inNode The node into which the link is connected. - * @param {oScene} [outPortNum] The out-port of the outNode used by this link. - * @param {oScene} [inPortNum] The in-port of the inNode used by this link. - * @param {oScene} [outLinkNum] The link index coming out of the out-port. - * @param {bool} [isValid=false] Bypass checks and assume this link is connected. - * @example - * // find out if two nodes are linked, and through which ports - * var doc = $.scn; - * var myNode = doc.root.$node("Drawing"); - * var sceneComp = doc.root.$node("Composite"); - * - * var myLink = new $.oLink(myNode, sceneComp); - * - * log(myLink.linked+" "+myLink.inPort+" "+myLink.outPort+" "+myLink.outLink); // trace the details of the connection. - * - * // activate/deactivate connections simply: - * myLink.connect(); - * log (myLink.linked) // true - * - * myLink.disconnect(); - * log (myLink.linked) // false - * - * // it is also possible to set the linked status directly on the linked property: - * myLink.linked = true; - * - * // however, changing the ports of the link object don't physically change the connection - * - * myLink.inPort = 2 // the connection didn't change, the link object simply represents now a different connection possible. - * log (myLink.linked) // false - * - * myLink.connect() // this will connect the nodes once more, with different ports. A new connection is created. - */ -$.oLink = function(outNode, inNode, outPortNum, inPortNum, outLinkNum, isValid){ - this._outNode = outNode; - this._inNode = inNode; - this._outPort = (typeof outPortNum !== 'undefined')? outPortNum:undefined; - this._outLink = (typeof outLinkNum !== 'undefined')? outLinkNum:undefined; - this._inPort = (typeof inPortNum !== 'undefined')? inPortNum:undefined; - this._linked = (typeof isValid !== 'undefined')? isValid:false; -} - - -/** - * The node that the link is coming out of. Changing this value doesn't reconnect the link, just changes the connection described by the link object. - * @name $.oLink#outNode - * @type {$.oNode} - */Object.defineProperty($.oLink.prototype, 'outNode', { - get : function(){ - return this._outNode; - }, - - set : function(newOutNode){ - this._outNode = newOutNode; - this._linked = false; - } -}); - - -/** - * The node that the link is connected into. Changing this value doesn't reconnect the link, just changes the connection described by the link object. - * @name $.oLink#inNode - * @type {$.oNode} - */ -Object.defineProperty($.oLink.prototype, 'inNode', { - get : function(){ - return this._inNode; - }, - - set: function(newInNode){ - this._inNode = newInNode; - this._linked = false; - } -}); - - -/** - * The in-port used by the link. Changing this value doesn't reconnect the link, just changes the connection described by the link object. - *
In the event this value wasn't known by the link object but the link is actually connected, the correct value will be found. - * @name $.oLink#inPort - * @type {int} - */ -Object.defineProperty($.oLink.prototype, 'inPort', { - get : function(){ - if (this.linked) return this._inPort; // cached value was correct - - var _found = this.findPorts(); - if (_found) return this._inPort; - - // nodes are not connected - return null; - }, - - set : function(newInPort){ - this._inPort = newInPort; - this._linked = false; - } -}); - - -/** - * The out-port used by the link. Changing this value doesn't reconnect the link, just changes the connection described by the link object. - *
In the event this value wasn't known by the link object but the link is actually connected, the correct value will be found. - * @name $.oLink#outPort - * @type {int} - */ -Object.defineProperty($.oLink.prototype, 'outPort', { - get : function(){ - if (this.linked) return this._outPort; // cached value was correct - - var _found = this.findPorts(); - if (_found) return this._outPort; - - // nodes are not connected - return null; - }, - - set : function(newOutPort){ - this._outPort = newOutPort; - this._linked = false; - } -}); - - -/** - * The index of the link coming out of the out-port. - *
In the event this value wasn't known by the link object but the link is actually connected, the correct value will be found. - * @name $.oLink#outLink - * @readonly - * @type {int} - */ -Object.defineProperty($.oLink.prototype, 'outLink', { - get : function(){ - if (this.linked) return this._outLink; - - var _found = this.findPorts(); - if (_found) return this._outLink; - - // nodes are not connected - return null; - } -}); - - -/** - * Get and set the linked status of a link - * @name $.oLink#linked - * @type {bool} - */ -Object.defineProperty($.oLink.prototype, 'linked', { - get : function(){ - if (this._linked) return this._linked; - - // first check if node object refers to two valid nodes - if (this.outNode === undefined || this.inNode === undefined){ - this.$.debug("checking 'linked' for invalid link: "+this.outNode+">"+this.inNode, this.$.DEBUG_LEVEL.ERROR) - return false; - } - - // if ports/links unknown, get a valid link we can check - if (this._outPort === undefined || this._inPort === undefined || this._outLink === undefined){ - if (!this.findPorts()){ - return false; - } - } - - // if ports/links are specified, we check the if the nodes connected to each port correspond with the link values - var _linkedOutNode = this.outNode.getLinkedOutNode(this._outPort, this._outLink); - var _linkedInNode = this.inNode.getLinkedInNode(this._inPort); - - if (_linkedOutNode == null || _linkedInNode == null) return false; - - var validOutLink = (_linkedOutNode.path == this.inNode.path); - var validInLink = (_linkedInNode.path == this.outNode.path); - - if (validOutLink && validInLink){ - this._linked = true; - return true; - } - return false; - }, - - set : function(newLinkedStatus){ - if (newLinkedStatus){ - this.connect(); - }else{ - this.disconnect(); - } - } -}); - - -/** - * Compares the start and end nodes groups to see if the path traverses several groups or not. - * @name $.oLink#isMultiLevel - * @readonly - * @type {bool} - */ -Object.defineProperty($.oLink.prototype, 'isMultiLevel', { - get : function(){ - //this.$.debug("isMultiLevel? "+this.outNode +" "+this.inNode, this.$.DEBUG_LEVEL.LOG); - if (!this.outNode || !this.outNode.group || !this.inNode || !this.inNode.group) return false; - return this.outNode.group.path != this.inNode.group.path; - } -}); - - -/** - * Compares the start and end nodes groups to see if the path traverses several groups or not. - * @name $.oLink#isMultiLevel - * @readonly - * @type {bool} - */ -Object.defineProperty($.oLink.prototype, 'waypoints', { - get : function(){ - if (!this.linked) return [] - var _waypoints = waypoint.getAllWaypointsAbove (this.inNode, this.inPort) - return _waypoints; - } -}); - - -/** - * Get a link that can be connected by working out ports that can be used. If a link already exists, it will be returned. - * @return {$.oLink} A separate $.oLink object that can be connected. Null if none could be constructed. - */ -$.oLink.prototype.getValidLink = function(createOutPorts, createInPorts){ - if (typeof createOutPorts === 'undefined') var createOutPorts = false; - if (typeof createInPorts === 'undefined') var createInPorts = true; - var start = this.outNode; - var end = this.inNode; - var outPort = this._outPort; - var inPort = this._inPort; - - if (!start || !end) { - $.debug("A valid link can't be found: node missing in link "+this.toString(), this.$.DEBUG_LEVEL.ERROR) - return null; - } - - if (this.isMultiLevel) return null; - - var _link = new this.$.oLink(start, end, outPort, inPort); - _link.findPorts(); - - // if can't be found, choose a new non existent link - if (!_link.linked){ - if (typeof outPort === 'undefined' || outPort === undefined){ - _link._outPort = start.getFreeOutPort(createOutPorts); - // if (_link._outPort == null) _link._outPort = 0; // just use a current port and add a link - } - - _link._outLink = start.getOutLinksNumber(_link._outPort); - - if (typeof inPort === 'undefined' || inPort === undefined){ - _link._inPort = end.getFreeInPort(createInPorts); - if (_link._inPort == null){ - this.$.debug("can't create link because the node "+end+" can't create a free inPort", this.$.DEBUG_LEVEL.ERROR); - return null; // can't create a valid link. - } - - }else{ - _link._inPort = inPort; - - if (end.getInLinksNumber(inPort)!= 0 && !end.canCreateInPorts){ - this.$.debug("can't create link because the requested port "+_link._inPort+" of node "+end+" isn't free", this.$.DEBUG_LEVEL.ERROR); - return null; - } - } - } - - return _link; -} - - -/** - * Attempts to connect a link. Will guess the ports if not provided. - * @return {bool} - */ -$.oLink.prototype.connect = function(){ - if (this._linked){ - return true; - } - - // do we want to just always get a valid link here or do we want it to fail if not set properly? - if (!this.findPorts()){ - var _validLink = this.getValidLink(this.outNode.canCreateInPorts, this.inNode.canCreateInPorts); - if (!_validLink) return false; - this.inPort = _validLink.inPort; - this.outPort = _validLink.outPort; - this.outLink = _validLink.outLink; - }; - - if (this.inNode.getInLinksNumber(this._inPort) > 0 && !this.inNode.canCreateInPorts) return false; // can't connect if the in-port is already connected - - var createOutPorts = (this.outNode.outPorts <= this._outPort && this.outNode.canCreateOutPorts); - var createInPorts = ((this.inNode.inPorts <= this._inPort || this.inNode.getInLinksNumber(this._inPort)>0) && this.inNode.canCreateInPorts); - - if (this._outNode.type == "GROUP" && createOutPorts) this._outNode.addOutPort(this._outPort); - if (this._inNode.type == "GROUP" && createInPorts) this._inNode.addInPort(this._inPort); - - try{ - this.$.debug("linking nodes "+this._outNode+" to "+this._inNode+" through outPort: "+this._outPort+", inPort: "+this._inPort+" and create ports: "+createOutPorts+" "+createInPorts, this.$.DEBUG_LEVEL.LOG); - - var success = node.link(this._outNode, this._outPort, this._inNode, this._inPort, createOutPorts, createInPorts); - this._linked = success; - - if (!success) throw new Error(); - return success; - - }catch(err){ - this.$.debug("linking nodes "+this._outNode+" to "+this._inNode+" through outPort: "+this._outPort+", inPort: "+this._inPort+", create outports: "+createOutPorts+", create inports:"+createInPorts, this.$.DEBUG_LEVEL.ERROR); - this.$.debug("Error linking nodes: " +err, this.$.DEBUG_LEVEL.ERROR); - return false; - } -} - - -/** - * Disconnects a link. - * @return {bool} Whether disconnecting was successful; - */ -$.oLink.prototype.disconnect = function(){ - if (!this._linked) return true; - - if (!this.findPorts()) return false; - - node.unlink(this._inNode, this._inPort); - this._linked = false; - return true; -} - - -/** - * Finds ports missing or undefined ports in the link object if it is linked, and update the object accordingly.
- * This will not update ports if the link isn't connected. Use getValidLink to get a connectable unconnected link. - * @private - * @return {bool} Whether finding ports was successful. - */ -$.oLink.prototype.findPorts = function(){ - // Unless some ports are specified, this will always find the first link and stop there. Provide more info in case of multiple links - - if (!this.outNode|| !this.inNode) { - this.$.debug("calling 'findPorts' for invalid link: "+this.outNode+" > "+this.inNode, this.$.DEBUG_LEVEL.ERROR); - return false; - } - - if (this._inPort !== undefined && this._outPort!== undefined && this._outLink!== undefined) return true; // ports already are valid, even if link might not be linked - - var _inNodePath = this.inNode.path; - var _outNodePath = this.outNode.path; - - // Try to find outPort based on inPort - // most likely to be missing is outLink, and this is the quickest way to find it. - if (this._inPort != undefined){ - var _nodeInfo = node.srcNodeInfo(_inNodePath, this._inPort); - if (_nodeInfo && _nodeInfo.node == _outNodePath && (this._outPort == undefined || this._outPort == _nodeInfo.port)){ - this._outPort = _nodeInfo.port; - this._outLink = _nodeInfo.link; - this._linked = true; - - // this.$.log("found ports through provided inPort: "+ this._inPort) - return true; - } - } - - // Try to find ports based on outLink/outPort - if (this._outPort !== undefined && this._outLink !== undefined){ - var _nodeInfo = node.dstNodeInfo(_outNodePath, this._outPort, this._outLink); - if (_nodeInfo && _nodeInfo.node == _inNodePath){ - this._inPort = _nodeInfo.port; - this._linked = true; - - // this.$.log("found ports through provided outPort/outLink: "+this._outPort+" "+this._outLink) - return true; - } - } - - // Find the ports if we are missing all of them, looking at in-ports to avoid messing with outLinks - var _inPorts = this.inNode.inPorts; - for (var i = 0; i<_inPorts; i++){ - var _nodeInfo = node.srcNodeInfo(_inNodePath, i); - if (_nodeInfo && _nodeInfo.node == _outNodePath){ - if (this._outPort !== undefined && this._outPort !== _nodeInfo.port) continue; - - this._inPort = i; - this._outPort = _nodeInfo.port; - this._outLink = _nodeInfo.link; - - // this.$.log("found ports through iterations") - this._linked = true; - - return true; - } - } - - // The nodes are not linked - this._linked = false; - return false; -} - - -/** - * Connects the given node in the middle of the link. The link must be connected. - * @param {$.oNode} oNode The node to insert in the link - * @param {int} [nodeInPort = 0] The inPort to use on the inserted node - * @param {int} [nodeOutPort = 0] The outPort to use on the inserted node - * @param {int} [nodeOutLink = 0] The outLink to use on the inserted node - * @return {$.oLink[]} an Array of two oLink objects that describe the new connections. - * @example - * include("openHarmony.js") - * doc = $.scn - * var node1 = doc.$node("Top/Drawing") - * var node2 = doc.$node("Top/Composite") - * var node3 = doc.$node("Top/Transparency") - * - * var link = new $.oLink(node1, node2) - * link.insertNode(node3) // insert the Transparency node between the Drawing and Composite - */ -$.oLink.prototype.insertNode = function(oNode, nodeInPort, nodeOutPort, nodeOutLink){ - if (!this.linked) return // can't insert a node if the link isn't connected - - this.$.beginUndo("oh_insertNode") - - var _inNode = this.inNode - var _outNode = this.outNode - var _inPort = this.inPort - var _outPort = this.outPort - var _outLink = this.outLink - - var _topLink = new this.$.oLink(_outNode, oNode, _outPort, nodeInPort, _outLink) - var _lowerLink = new this.$.oLink(oNode, _inNode, nodeOutPort, _inPort, nodeOutLink) - - this.linked = false; - var success = (_topLink.connect() && _lowerLink.connect()); - - this.$.endUndo() - - if (success) { - return [_topLink, _lowerLink] - } else{ - // we restore the links to default state and return false - this.$.debug("failed to insert node "+oNode+" into link "+this) - this.$.undo() - return false - } -} - -/** - * Converts the node link to a string. - * @private - */ -$.oLink.prototype.toString = function( ) { - return ('link: {"'+this._outNode+'" ['+this._outPort+', '+this._outLink+'] -> "'+this._inNode+'" ['+this._inPort+']} linked:'+this._linked); - // return '{outNode:'+this.outNode+' inNode:'+this.inNode+' }'; -} - - - - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oLinkPath class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * Constructor for $.oLinkPath class - * @classdesc - * The $.oLinkPath class allows to figure out paths as a series of links between distant nodes.
- * It can either look for existing paths and check that two distant nodes are connected or create new ones that can then be connected. - * @constructor - * @param {$.oNode} startNode The first node from which the link is coming out. - * @param {$.oNode} endNode The last node into which the link is connected. - * @param {oScene} [outPortNum] The out-port of the startNode. - * @param {oScene} [inPortNum] The in-port of the endNode. - * @param {oScene} [outLinkNum] The link index coming out of the out-port of the startNode. - * @see NodeType - */ -$.oLinkPath = function( startNode, endNode, outPort, inPort, outLink){ - this.startNode = startNode; - this.endNode = endNode; - this.outPort = (typeof outPort !== 'undefined')? outPort:undefined; - this.inPort = (typeof inPort !== 'undefined')? inPort:undefined; - this.outLink = (typeof outLink !== 'undefined')? outLink:undefined; -} - - -/** - * Compares the start and end nodes groups to see if the path traverses several groups or not. - * @name $.oLinkPath#isMultiLevel - * @readonly - * @type {bool} - */ -Object.defineProperty($.oLinkPath.prototype, 'isMultiLevel', { - get : function(){ - //this.$.log(this.startNode+" "+this.endNode) - return this.startNode.group.path != this.endNode.group.path; - } -}); - - -/** - * Identifies the group in which the two nodes will connect if they are at different levels of depth. - * @name $.oLinkPath#lowestCommonGroup - * @readonly - * @type {$.oGroupNode} - */ -Object.defineProperty($.oLinkPath.prototype, 'lowestCommonGroup', { - get : function(){ - var startPath = this.startNode.group.path.split("/"); - var endPath = this.endNode.group.path.split("/"); - - var commonPath = []; - for (var i=0; iAll preferences that have been written to the file are accessible as properties of this class.
- * Alternatively, new preferences can be retrieved with the .get function. - * @constructor - * @example - * var pref = $.getPreferences(); - * pref.create( "MyNewPreferenceName", "MyPreferenceValue" ); - * pref["MyNewPreferenceName"]; // Provides: MyPreferenceValue - * pref.get("MyNewPreferenceName"); // Provides: MyPreferenceValue - */ -$.oPreferences = function( ){ - this._type = "preferences"; - this._addedPreferences = [] - - this.refresh(); -} - - -/** - * Refreshes the preferences by re-reading the preference file and ingesting their values appropriately. They are then available as properties of this class.
- * Note, any new preferences will not be available as properties until Harmony saves the preference file at exit. In order to reference new preferences, use the get function. - * @name $.oPreferences#refresh - * @function - */ -$.oPreferences.prototype.refresh = function(){ - var fl = specialFolders.userConfig + "/Harmony Premium-pref.xml"; - var nfl = new this.$.oFile( fl ); - if( !nfl.exists ){ - System.println( "Unable to find preference file: " + fl ); - this.$.debug( "Unable to find preference file: " + fl, this.$.DEBUG_LEVEL.ERROR ); - return; - } - - var xmlDom = new QDomDocument(); - xmlDom.setContent( nfl.read() ); - - if( !xmlDom ){ - return; - } - - var prefXML = xmlDom.elementsByTagName( "preferences" ); - if( prefXML.length() == 0 ){ - this.$.debug( "Unable to find preferences in file: " + fl, this.$.DEBUG_LEVEL.ERROR ); - return; - } - - var XMLpreferences = prefXML.at(0); - - //Clear this objects previous getter/setters to make room for new ones. - if( this._preferences ){ - for( n in this._preferences ){ //Remove them if they've disappeared. - Object.defineProperty( this, n, { - enumerable : false, - configurable: true, - set : function(){}, - get : function(){} - }); - } - } - this._preferences = {}; - - if( !XMLpreferences.hasChildNodes() ){ - this.$.debug( "Unable to find preferences in file: " + fl, this.$.DEBUG_LEVEL.ERROR ); - return; - } - - //THE DEFAULT SETTER - var set_val = function( pref, name, val ){ - var prefObj = pref._preferences[name]; - - //Check against types, unable to set types differently. - switch( typeof val ){ - case 'string': - if( prefObj["type"] != "string" ){ - throw ReferenceError( "Harmony does not support preference type-changes. Preference must remain " + prefObj["type"] ); - } - preferences.setString( name, val ); - break; - case 'number': - if( prefObj["type"] == "int" ){ - val = Math.floor( val ); - preferences.setInt( name, val ); - }else if( prefObj["type"] == "double" ){ - //This is fine. - preferences.setDouble( name, val ); - }else{ - throw ReferenceError( "Harmony does not support preference type-changes. Preference must remain " + prefObj["type"] ); - } - break - case 'boolean': - case 'undefined': - case 'null': - if( prefObj["type"] != "bool" ){ - throw ReferenceError( "Harmony does not support preference type-changes. Preference must remain " + prefObj["type"] ); - } - preferences.setBool( name, val ? true:false ); - break - case 'object': - default: - var set = false; - try{ - if( val.r && val.g && val.b && val.a ){ - if( prefObj["type"] != "color" ){ - throw ReferenceError( "Harmony does not support preference type-changes. Preference must remain " + prefObj["type"] ); - } - - value = preferences.setColor( name, new ColorRGBA( val.r, val.g, val.b, val.a ) ); - set = true; - } - }catch(err){ - } - - if(!set){ - if( prefObj["type"] != "string" ){ - throw ReferenceError( "Harmony does not support preference type-changes. Preference must remain " + prefObj["type"] ); - } - var json_val = 'json('+JSON.stringify( val )+')'; - preferences.setString( name, json_val ); - } - break - } - - { - pref._preferences[name].value = val; - } - } - - //THE DEFAULT GETTER - var get_val = function( pref, name ){ - return pref._preferences[name].value; - } - - - var getterSetter_create = function( targ, id, type ){ - switch( type ){ - case 'color': - var tempVal = preferences.getColor( id, new ColorRGBA () ); - value = new $.oColorValue( tempVal.r, tempVal.g, tempVal.b, tempVal.a ); - break; - case 'int': - value = preferences.getInt( id, 0 ); - break - case 'double': - value = preferences.getDouble( id, 0.0 ); - break - case 'bool': - value = preferences.getBool( id, false ); - break - case 'string': - value = preferences.getString( id, "unknown" ); - if( value.slice( 0, 5 ) == "json(" ){ - var obj = value.slice( 5, value.length-1 ); - value = JSON.parse( obj ); - } - break - default: - break; - } - if( value === null ) return; - - targ._preferences[ id ] = { "value": value, "type":type }; - - //Create a getter/setter for it! - Object.defineProperty( targ, id, { - enumerable : true, - configurable: true, - set : eval( 'val = function(val){ set_val( targ, "'+id+'", val ); }' ), - get : eval( 'val = function(){ return get_val( targ, "'+id+'"); }' ) - }); - } - - - //Get all the children preferences. - var childNodes = XMLpreferences.childNodes(); - for( var cn=0;cnNote- A new preference isn't actively written into the Harmony's preference file until created and the application closed. Use preference.get for newly created preferences. - * @name $.oPreferences#create - * @param {string} name The name of the new preference to create. - * @param {object} val The value of the new preference created. - */ -$.oPreferences.prototype.create = function( name, val ){ - if( this[ name ] ){ - throw ReferenceError( "Preference already exists by name: " + name ); - } - - var type = ''; - //Check against types, unable to set types differently. - switch( typeof val ){ - case 'string': - type = 'string'; - preferences.setString( name, val ); - break; - case 'number': - type = 'double'; - preferences.setDouble( name, val ); - break - case 'boolean': - case 'undefined': - case 'null': - type = 'bool'; - preferences.setBool( name, val ? true:false ); - break - case 'object': - default: - var set = false; - try{ - if( val.r && val.g && val.b && val.a ){ - type = 'color'; - value = preferences.setColor( name, new ColorRGBA( val.r, val.g, val.b, val.a ) ); - set = true; - } - }catch(err){ - } - - if(!set){ - type = 'string'; - var json_val = 'json('+JSON.stringify( val )+')'; - preferences.setString( name, json_val ); - } - break - } - - this._addedPreferences.push( {"type":type, "name":name } ); - this.refresh(); -} - - -/** - * Retrieves a preference and attempts to identify its type automatically.
This is generally useful for accessing newly created preferences that have not been written to disk. - * @name $.oPreferences#get - * @param {string} name The name of the preference to retrieve. - * @example - * var pref = $.getPreferences(); - * pref.create( "MyNewPreferenceName", "MyPreferenceValue" ); - * //This new preference won't be available in the file until Harmony closes. - * //So if preferences are reinstantiated, it won't be readily available -- but it can still be retrieved with get. - * - * var pref2 = $.getPreferences(); - * pref["MyNewPreferenceName"]; // Provides: undefined -- its not in the Harmony preference file. - * pref.get("MyNewPreferenceName"); // Provides: MyPreferenceValue, its still available - */ -$.oPreferences.prototype.get = function( name ){ - if( this[name] ){ - return this[name]; - } - - var testTime = (new Date()).getTime(); - var doubleExist = preferences.getDouble( name, testTime ); - if( doubleExist!= testTime ){ - this._addedPreferences.push( {"type":'double', "name":name } ); - this.refresh(); - - return doubleExist; - } - - var intExist = preferences.getInt( name, testTime ); - if( intExist!= testTime ){ - this._addedPreferences.push( {"type":'int', "name":name } ); - this.refresh(); - - return intExist; - } - - - var colorExist = preferences.getColor( name, new ColorRGBA(1,2,3,4) ); - if( !( (colorExist.r==1) && (colorExist.g==2) && (colorExist.b==3) && (colorExist.a==4) ) ){ - this._addedPreferences.push( {"type":'color', "name":name } ); - this.refresh(); - - return colorExist; - } - - var stringExist = preferences.getString( name, "doesntExist" ); - if( stringExist != "doesntExist" ){ - this._addedPreferences.push( {"type":'color', "name":name } ); - this.refresh(); - - return this[name]; - } - - return preferences.getBool( name, false ); -} - - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oPreference class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - -/** - * The constructor for the oPreference Class. - * @classdesc - * The oPreference class wraps a single preference item. - * @constructor - * @param {string} category The category of the preference - * @param {string} keyword The keyword used by the preference - * @param {string} type The type of value held by the preference - * @param {string} description A short string of description - * @param {string} descriptionText The complete tooltip text for the preference - * @example - * // To access the preferences of Harmony, grab the preference object in the $.oApp class: - * var prefs = $.app.preferences; - * - * // It's then possible to access all available preferences of the software: - * for (var i in prefs){ - * log (i+" "+prefs[i]); - * } - * - * // accessing the preference value can be done directly by using the dot notation: - * prefs.USE_OVERLAY_UNDERLAY_ART = true; - * log (prefs.USE_OVERLAY_UNDERLAY_ART); - * - * //the details objects of the preferences object allows access to more information about each preference - * var details = prefs.details - * log(details.USE_OVERLAY_UNDERLAY_ART.category+" "+details.USE_OVERLAY_UNDERLAY_ART.id+" "+details.USE_OVERLAY_UNDERLAY_ART.type); - * - * for (var i in details){ - * log(i+" "+JSON.stringify(details[i])) // each object inside detail is a complete oPreference instance - * } - * - * // the preference object also holds a categories array with the list of all categories - * log (prefs.categories) - */ -$.oPreference = function(category, keyword, type, value, description, descriptionText){ - this.category = category; - this.keyword = keyword; - this.type = type; - this.description = description; - this.descriptionText = descriptionText; - this.defaultValue = value; -} - - -/** - * get and set a preference value - * @name $.oPreference#value - */ -Object.defineProperty ($.oPreference.prototype, 'value', { - get: function(){ - try{ - switch(this.type){ - case "bool": - var _value = preferences.getBool(this.keyword, this.defaultValue); - break - case "int": - var _value = preferences.getInt(this.keyword, this.defaultValue); - break; - case "double": - var _value = preferences.getDouble(this.keyword, this.defaultValue); - break; - case "color": - var _value = preferences.getColor(this.keyword, this.defaultValue); - _value = new this.$.oColorValue(_value.r, _value.g, _value.b, _value.a) - break; - default: - var _value = preferences.getString(this.keyword, this.defaultValue); - } - }catch(err){ - this.$.debug(err, this.$.DEBUG_LEVEL.ERROR) - } - this.$.debug("Getting value of Preference "+this.keyword+" : "+_value, this.$.DEBUG_LEVEL.LOG) - return _value; - }, - - set : function(newValue){ - switch(this.type){ - case "bool": - preferences.setBool(this.keyword, newValue); - break - case "int": - preferences.setInt(this.keyword, newValue); - break; - case "double": - preferences.setDouble(this.keyword, newValue); - break; - case "color": - if (typeof newValue == String) newValue = (new oColorValue()).fromColorString(newValue); - preferences.setColor(this.keyword, new ColorRGBA(newValue.r, newValue.g, newValue.b, newValue.a)); - break; - default: - preferences.setString(this.keyword, newValue); - } - this.$.debug("Preference "+this.keyword+" was set to : "+newValue, this.$.DEBUG_LEVEL.LOG) - } -}) - - -/** - * Creates getter setters on a simple object for the preference described by the params - * @private - * @param {string} category The category of the preference - * @param {string} keyword The keyword used by the preference - * @param {string} type The type of value held by the preference - * @param {string} description A short string of description - * @param {string} descriptionText The complete tooltip text for the preference - * @param {Object} prefObject The preference object that will receive the getter setter property (usually $.oApp._prefObject) - */ -$.oPreference.createPreference = function(category, keyword, type, value, description, descriptionText, prefObject){ - if (!prefObject.details.hasOwnProperty(keyword)){ - var pref = new $.oPreference(category, keyword, type, value, description, descriptionText); - Object.defineProperty(prefObject, keyword,{ - enumerable: true, - get : function(){ - return pref.value; - }, - set : function(newValue){ - pref.value = newValue; - } - }) - }else{ - var pref = prefObject.details[keyword] - } - - return pref; -} \ No newline at end of file diff --git a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_scene.js b/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_scene.js deleted file mode 100644 index 8100df3a1c..0000000000 --- a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_scene.js +++ /dev/null @@ -1,2345 +0,0 @@ -////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// -// -// openHarmony Library -// -// -// Developped by Mathieu Chaptel, Chris Fourney -// -// -// This library is an open source implementation of a Document Object Model -// for Toonboom Harmony. It also implements patterns similar to JQuery -// for traversing this DOM. -// -// Its intended purpose is to simplify and streamline toonboom scripting to -// empower users and be easy on newcomers, with default parameters values, -// and by hiding the heavy lifting required by the official API. -// -// This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is garanteed to work. Feel free to contribute -// improvements to its official github. If you do make sure you follow the provided -// template and naming conventions and document your new methods properly. -// -// This library doesn't overwrite any of the objects and classes of the official -// Toonboom API which must remains available. -// -// This library is made available under the Mozilla Public license 2.0. -// https://www.mozilla.org/en-US/MPL/2.0/ -// -// The repository for this library is available at the address: -// https://github.com/cfourney/OpenHarmony/ -// -// -// For any requests feel free to contact m.chaptel@gmail.com -// -// -// -// -////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oScene class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -//TODO: Metadata, settings, aspect, camera peg, view. -/** - * The constructor for $.oScene. - * @classdesc - * The base Class to access all the contents of the scene, and add elements.
This is the main class to do exporting operations as well as column/element/palette creation. - * @constructor - * @example - * // Access to the direct dom object. Available and automatically instantiated as $.getScene, $.scene, $.scn, $.s - * var doc = $.getScene ; - * var doc = $.scn ; - * ver doc = $.s ; // all these are equivalents - * - * // To grab the scene from a QWidget Dialog callback, store the $ object in a local variable to access all the fonctions from the library. - * function myCallBackFunction(){ - * var this.$ = $; - * - * var doc = this.$.scn; - * } - * - * - */ -$.oScene = function( ){ - // $.oScene.nodes property is a class property shared by all instances, so it can be passed by reference and always contain all nodes in the scene - - //var _topNode = new this.$.oNode("Top"); - //this.__proto__.nodes = _topNode.subNodes(true); - - this._type = "scene"; -} - - -//------------------------------------------------------------------------------------- -//--- $.oScene Objects Properties -//------------------------------------------------------------------------------------- -//------------------------------------------------------------------------------------- - - -/** - * The folder that contains this scene. - * @name $.oScene#path - * @type {$.oFolder} - * @readonly - */ -Object.defineProperty($.oScene.prototype, 'path', { - get : function(){ - return new this.$.oFolder( scene.currentProjectPathRemapped() ); - } -}); - -/** - * The stage file of the scene. - * @name $.oScene#stage - * @type {$.oFile} - * @readonly - */ -Object.defineProperty($.oScene.prototype, 'stage', { - get : function(){ - if (this.online) return this.path + "/stage/" + this.name + ".stage"; - return this.path + "/" + this.version + ".xstage"; - } -}); - -/** - * The folder that contains this scene. - * @name $.oScene#paletteFolder - * @type {$.oFolder} - * @readonly - */ -Object.defineProperty($.oScene.prototype, 'paletteFolder', { - get : function(){ - return new this.$.oFolder( this.path+"/palette-library" ); - } -}); - - -/** - * The temporary folder where files are created before being saved. - * If the folder doesn't exist yet, it will be created. - * @name $.oScene#tempFolder - * @type {$.oFolder} - * @readonly - */ -Object.defineProperty($.oScene.prototype, 'tempFolder', { - get : function(){ - if (!this.hasOwnProperty("_tempFolder")){ - this._tempFolder = new this.$.oFolder(scene.tempProjectPathRemapped()); - if (!this._tempFolder.exists) this._tempFolder.create() - } - return this._tempFolder; - } -}); - -/** - * The name of the scene. - * @name $.oScene#name - * @readonly - * @type {string} - */ -Object.defineProperty($.oScene.prototype, 'name', { - get : function(){ - return scene.currentScene(); - } -}); - - -/** - * Wether the scene is hosted on a Toonboom database. - * @name $.oScene#online - * @readonly - * @type {bool} - */ -Object.defineProperty($.oScene.prototype, 'online', { - get : function(){ - return about.isDatabaseMode() - } -}); - -/** - * The name of the scene. - * @name $.oScene#environnement - * @readonly - * @type {string} - */ -Object.defineProperty($.oScene.prototype, 'environnement', { - get : function(){ - if (!this.online) return null; - return scene.currentEnvironment(); - } -}); - - -/** - * The name of the scene. - * @name $.oScene#job - * @readonly - * @type {string} - */ -Object.defineProperty($.oScene.prototype, 'job', { - get : function(){ - if (!this.online) return null; - return scene.currentJob(); - } -}); - - -/** - * The name of the scene. - * @name $.oScene#version - * @readonly - * @type {string} - */ -Object.defineProperty($.oScene.prototype, 'version', { - get : function(){ - return scene.currentVersionName(); - } -}); - - -/** - * The sceneName file of the scene. - * @Deprecated - * @readonly - * @name $.oScene#sceneName - * @type {string} - */ -Object.defineProperty($.oScene.prototype, 'sceneName', { - get : function(){ - return this.name; - } -}); - - - -/** - * The startframe to the playback of the scene. - * @name $.oScene#startPreview - * @type {int} - */ -Object.defineProperty($.oScene.prototype, 'startPreview', { - get : function(){ - return scene.getStartFrame(); - }, - set : function(val){ - scene.setStartFrame( val ); - } -}); - -/** - * The stopFrame to the playback of the scene. - * @name $.oScene#stopPreview - * @type {int} - */ -Object.defineProperty($.oScene.prototype, 'stopPreview', { - get : function(){ - return scene.getStopFrame()+1; - }, - set : function(val){ - scene.setStopFrame( val-1 ); - } -}); - -/** - * The frame rate of the scene. - * @name $.oScene#framerate - * @type {float} - */ -Object.defineProperty($.oScene.prototype, 'framerate', { - get : function(){ - return scene.getFrameRate(); - }, - set : function(val){ - return scene.setFrameRate( val ); - } -}); - - -/** - * The Field unit aspect ratio as a coefficient (width/height). - * @name $.oScene#unitsAspectRatio - * @type {double} - */ - Object.defineProperty($.oScene.prototype, 'unitsAspectRatio', { - get : function(){ - return this.aspectRatioX/this.aspectRatioY; - } -}); - - -/** - * The horizontal aspect ratio of Field units. - * @name $.oScene#aspectRatioX - * @type {double} - */ -Object.defineProperty($.oScene.prototype, 'aspectRatioX', { - get : function(){ - return scene.unitsAspectRatioX(); - }, - set : function(val){ - scene.setUnitsAspectRatio( val, this.aspectRatioY ); - } -}); - -/** - * The vertical aspect ratio of Field units. - * @name $.oScene#aspectRatioY - * @type {double} - */ -Object.defineProperty($.oScene.prototype, 'aspectRatioY', { - get : function(){ - return scene.unitsAspectRatioY(); - }, - set : function(val){ - scene.setUnitsAspectRatio( this.aspectRatioY, val ); - } -}); - -/** - * The horizontal Field unit count. - * @name $.oScene#unitsX - * @type {double} - */ -Object.defineProperty($.oScene.prototype, 'unitsX', { - get : function(){ - return scene.numberOfUnitsX(); - }, - set : function(val){ - scene.setNumberOfUnits( val, this.unitsY, this.unitsZ ); - } -}); - -/** - * The vertical Field unit count. - * @name $.oScene#unitsY - * @type {double} - */ -Object.defineProperty($.oScene.prototype, 'unitsY', { - get : function(){ - return scene.numberOfUnitsY(); - }, - set : function(val){ - scene.setNumberOfUnits( this.unitsX, val, this.unitsZ ); - } -}); - -/** - * The depth Field unit count. - * @name $.oScene#unitsZ - * @type {double} - */ -Object.defineProperty($.oScene.prototype, 'unitsZ', { - get : function(){ - return scene.numberOfUnitsZ(); - }, - set : function(val){ - scene.setNumberOfUnits( this.unitsX, this.unitsY, val ); - } -}); - - -/** - * The center coordinates of the scene. - * @name $.oScene#center - * @type {$.oPoint} - */ -Object.defineProperty($.oScene.prototype, 'center', { - get : function(){ - return new this.$.oPoint( scene.coordAtCenterX(), scene.coordAtCenterY(), 0.0 ); - }, - set : function( val ){ - scene.setCoordAtCenter( val.x, val.y ); - } -}); - - -/** - * The amount of drawing units represented by 1 field on the horizontal axis. - * @name $.oScene#fieldVectorResolutionX - * @type {double} - * @readonly - */ -Object.defineProperty($.oScene.prototype, 'fieldVectorResolutionX', { - get : function(){ - var yUnit = this.fieldVectorResolutionY; - var unit = yUnit * this.unitsAspectRatio; - return unit - } -}); - - -/** - * The amount of drawing units represented by 1 field on the vertical axis. - * @name $.oScene#fieldVectorResolutionY - * @type {double} - * @readonly - */ -Object.defineProperty($.oScene.prototype, 'fieldVectorResolutionY', { - get : function(){ - var verticalResolution = 1875 // the amount of drawing units for the max vertical field value - var unit = verticalResolution/12; // the vertical number of units on drawings is always 12 regardless of $.scn.unitsY - return unit - } -}); - - -/** - * The horizontal resolution in pixels (for rendering). - * @name $.oScene#resolutionX - * @readonly - * @type {int} - */ -Object.defineProperty($.oScene.prototype, 'resolutionX', { - get : function(){ - return scene.currentResolutionX(); - } -}); - -/** - * The vertical resolution in pixels (for rendering). - * @name $.oScene#resolutionY - * @type {int} - */ -Object.defineProperty($.oScene.prototype, 'resolutionY', { - get : function(){ - return scene.currentResolutionY(); - } -}); - -/** - * The default horizontal resolution in pixels. - * @name $.oScene#defaultResolutionX - * @type {int} - */ -Object.defineProperty($.oScene.prototype, 'defaultResolutionX', { - get : function(){ - return scene.defaultResolutionX(); - }, - set : function(val){ - scene.setDefaultResolution( val, this.defaultResolutionY, this.fov ); - } -}); - -/** - * The default vertical resolution in pixels. - * @name $.oScene#defaultResolutionY - * @type {int} - */ -Object.defineProperty($.oScene.prototype, 'defaultResolutionY', { - get : function(){ - return scene.defaultResolutionY(); - }, - set : function(val){ - scene.setDefaultResolution( this.defaultResolutionX, val, this.fov ); - } -}); - -/** - * The field of view of the scene. - * @name $.oScene#fov - * @type {double} - */ -Object.defineProperty($.oScene.prototype, 'fov', { - get : function(){ - return scene.defaultResolutionFOV(); - }, - set : function(val){ - scene.setDefaultResolution( this.defaultResolutionX, this.defaultResolutionY, val ); - } -}); - - -/** - * The default Display of the scene. - * @name $.oScene#defaultDisplay - * @type {oNode} - */ -Object.defineProperty($.oScene.prototype, 'defaultDisplay', { - get : function(){ - return this.getNodeByPath(scene.getDefaultDisplay()); - }, - - set : function(newDisplay){ - node.setAsGlobalDisplay(newDisplay.path); - } -}); - - -/** - * Whether the scene contains unsaved changes. - * @name $.oScene#unsaved - * @readonly - * @type {bool} - */ -Object.defineProperty($.oScene.prototype, 'unsaved', { - get : function(){ - return scene.isDirty(); - } -}); - - -/** - * The root group of the scene. - * @name $.oScene#root - * @type {$.oGroupNode} - * @readonly - */ -Object.defineProperty($.oScene.prototype, 'root', { - get : function(){ - var _topNode = this.getNodeByPath( "Top" ); - return _topNode - } -}); - - -/** - * Contains the list of all the nodes present in the scene. - * @name $.oScene#nodes - * @readonly - * @type {$.oNode[]} - */ -Object.defineProperty($.oScene.prototype, 'nodes', { - get : function(){ - var _topNode = this.root; - return _topNode.subNodes( true ); - } -}); - - -/** - * Contains the list of columns present in the scene. - * @name $.oScene#columns - * @readonly - * @type {$.oColumn[]} - * @todo add attribute finding to get complete column objects - */ -Object.defineProperty($.oScene.prototype, 'columns', { - get : function(){ - var _columns = []; - for (var i=0; i0){ - frame.insert(_length-1, _toAdd) - }else{ - frame.remove(_length-1, _toAdd) - } - } -}); - - -/** - * The current frame of the scene. - * @name $.oScene#currentFrame - * @type {int} - */ -Object.defineProperty($.oScene.prototype, 'currentFrame', { - get : function(){ - return frame.current(); - }, - - set : function( frm ){ - return frame.setCurrent( frm ); - } -}); - - -/** - * Retrieve and change the selection of nodes. - * @name $.oScene#selectedNodes - * @type {$.oNode[]} - */ -Object.defineProperty($.oScene.prototype, 'selectedNodes', { - get : function(){ - return this.getSelectedNodes(); - }, - - set : function(nodesToSelect){ - selection.clearSelection (); - for (var i in nodesToSelect){ - selection.addNodeToSelection(nodesToSelect[i].path); - }; - } -}); - - -/** - * Retrieve and change the selected frames. This is an array with two values, one for the start and one for the end of the selection (not included). - * @name $.oScene#selectedFrames - * @type {int[]} - */ -Object.defineProperty($.oScene.prototype, 'selectedFrames', { - get : function(){ - if (selection.isSelectionRange()){ - var _selectedFrames = [selection.startFrame(), selection.startFrame()+selection.numberOfFrames()]; - }else{ - var _selectedFrames = [this.currentFrame, this.currentFrame+1]; - } - - return _selectedFrames; - }, - - set : function(frameRange){ - selection.setSelectionFrameRange(frameRange[0], frameRange[1]-frameRange[0]); - } -}); - - -/** - * Retrieve and set the selected palette from the scene palette list. - * @name $.oScene#selectedPalette - * @type {$.oPalette} - */ -Object.defineProperty($.oScene.prototype, "selectedPalette", { - get: function(){ - var _paletteList = PaletteObjectManager.getScenePaletteList() - var _id = PaletteManager.getCurrentPaletteId() - if (_id == "") return null; - var _palette = new this.$.oPalette(_paletteList.getPaletteById(_id), _paletteList); - return _palette; - }, - - set: function(newSelection){ - var _id = newSelection.id; - PaletteManager.setCurrentPaletteById(_id); - } -}) - - -/** - * The selected strokes on the currently active Drawing - * @name $.oScene#selectedShapes - * @type {$.oStroke[]} - */ -Object.defineProperty($.oScene.prototype, "selectedShapes", { - get : function(){ - var _currentDrawing = this.activeDrawing; - var _shapes = _currentDrawing.selectedShapes; - - return _shapes; - } -}) - - -/** - * The selected strokes on the currently active Drawing - * @name $.oScene#selectedStrokes - * @type {$.oStroke[]} - */ -Object.defineProperty($.oScene.prototype, "selectedStrokes", { - get : function(){ - var _currentDrawing = this.activeDrawing; - var _strokes = _currentDrawing.selectedStrokes; - - return _strokes; - } -}) - - -/** - * The selected strokes on the currently active Drawing - * @name $.oScene#selectedContours - * @type {$.oContour[]} - */ -Object.defineProperty($.oScene.prototype, "selectedContours", { - get : function(){ - var _currentDrawing = this.activeDrawing; - var _strokes = _currentDrawing.selectedContours; - - return _strokes; - } -}) - - -/** - * The currently active drawing in the harmony UI. - * @name $.oScene#activeDrawing - * @type {$.oDrawing} - */ -Object.defineProperty($.oScene.prototype, 'activeDrawing', { - get : function(){ - var _curDrawing = Tools.getToolSettings().currentDrawing; - if (!_curDrawing) return null; - - var _element = this.selectedNodes[0].element; - var _drawings = _element.drawings; - for (var i in _drawings){ - if (_drawings[i].id == _curDrawing.drawingId) return _drawings[i]; - } - - return null - }, - - set : function( newCurrentDrawing ){ - newCurrentDrawing.setAsActiveDrawing(); - } -}); - - -/** - * The current timeline using the default Display. - * @name $.oScene#currentTimeline - * @type {$.oTimeline} - * @readonly - */ -Object.defineProperty($.oScene.prototype, 'currentTimeline', { - get : function(){ - if (!this.hasOwnProperty("_timeline")){ - this._timeline = this.getTimeline(); - } - return this._timeline; - } -}); - - - - -//------------------------------------------------------------------------------------- -//--- $.oScene Objects Methods -//------------------------------------------------------------------------------------- -//------------------------------------------------------------------------------------- - - -/** - * Gets a node by the path. - * @param {string} fullPath The path of the node in question. - * - * @return {$.oNode} The node found given the query. - */ -$.oScene.prototype.getNodeByPath = function(fullPath){ - var _type = node.type(fullPath); - if (_type == "") return null; - - var _node; - switch(_type){ - case "READ" : - _node = new this.$.oDrawingNode( fullPath, this ); - break; - case "PEG" : - _node = new this.$.oPegNode( fullPath, this ); - break; - case "COLOR_OVERRIDE_TVG" : - _node = new this.$.oColorOverrideNode( fullPath, this ); - break; - case "TransformationSwitch" : - _node = new this.$.oTransformSwitchNode( fullPath, this ); - break; - case "GROUP" : - _node = new this.$.oGroupNode( fullPath, this ); - break; - default: - _node = new this.$.oNode( fullPath, this ); - } - - return _node; -} - - /** - * Returns the nodes of a certain type in the entire scene. - * @param {string} typeName The name of the node. - * - * @return {$.oNode[]} The nodes found. - */ -$.oScene.prototype.getNodesByType = function(typeName){ - return this.root.getNodesByType(typeName, true); -} - -/** - * Gets a column by the name. - * @param {string} uniqueName The unique name of the column as a string. - * @param {$.oAttribute} oAttributeObject The oAttributeObject owning the column. - * @todo cache and find attribute if it is missing - * - * @return {$.oColumn} The column found given the query. - */ -$.oScene.prototype.getColumnByName = function( uniqueName, oAttributeObject ){ - var _type = column.type(uniqueName); - - switch (_type) { - case "" : - return null; - case "DRAWING" : - return new this.$.oDrawingColumn(uniqueName, oAttributeObject); - default : - return new this.$.oColumn(uniqueName, oAttributeObject); - } -} - - -/** - * Gets an element by Id. - * @param {string} id The unique name of the column as a string. - * @param {$.oColumn} [oColumnObject] The oColumn object linked to the element in case of duplicate. - * - * @return {$.oElement} The element found given the query. In case of an element linked to several column, only the first one will be returned, unless the column is specified - */ -$.oScene.prototype.getElementById = function( id, oColumnObject ){ - if (element.getNameById(id) == "") return null; - - var _sceneElements = this.elements.filter(function(x){return x.id == id}); - if (typeof oColumnObject !== 'undefined') _sceneElements = _sceneElements.filter(function(x){return x.column.uniqueName == oColumnObject.uniqueName}); - - if (_sceneElements.length > 0) return _sceneElements[0]; - return null; -} - - -/** - * Gets the selected Nodes. - * @param {bool} recurse Whether to recurse into groups. - * - * @return {$.oNode[]} The selected nodes. - */ -$.oScene.prototype.getSelectedNodes = function( recurse, sortResult ){ - if (typeof recurse === 'undefined') var recurse = false; - if (typeof sort_result === 'undefined') var sortResult = false; //Avoid sorting, save time, if unnecessary and used internally. - - var _selection = selection.selectedNodes(); - - var _selectedNodes = []; - for (var i = 0; i<_selection.length; i++){ - - var _oNodeObject = this.$node(_selection[i]) - - _selectedNodes.push(_oNodeObject) - if (recurse && node.isGroup(_selection[i])){ - _selectedNodes = _selectedNodes.concat(_oNodeObject.subNodes(recurse)) - } - } - - // sorting by timeline index - if( sortResult ){ - var _timeline = this.getTimeline(); - _selectedNodes = _selectedNodes.sort(function(a, b){return a.timelineIndex(_timeline)-b.timelineIndex(_timeline)}) - } - - return _selectedNodes; -} - - -/** - * Searches for a node based on the query. - * @param {string} query The query for finding the node[s]. - * - * @return {$.oNode[]} The node[s] found given the query. - */ -$.oScene.prototype.nodeSearch = function( query, sort_result ){ - if (typeof sort_result === 'undefined') var sort_result = true; //Avoid sorting, save time, if unnecessary and used internally. - - //----------------------------------- - //Breakdown with regexp as needed, find the query details. - //----------------------------------- - - // NAME, NODE, WILDCARDS, ATTRIBUTE VALUE MATCHING, SELECTION/OPTIONS, COLOURS - - //---------------------------------------------- - // -- PATH/WILDCARD#TYPE[ATTRIBUTE:VALUE,ATTRIBUTE:VALUE][OPTION:VALUE,OPTION:VALUE] - // ^(.*?)(\#.*?)?(\[.*\])?(\(.*\))?$ - - //ALLOW USAGE OF AN INPUT LIST, LIST OF NAMES, OR OBJECTS, - - //-------------------------------------------------- - //-- EASY RETURNS FOR FAST OVERLOADS. - - //* -- OVERRIDE FOR ALL NODES - - if( query == "*" ){ - return this.nodes; - - //(SELECTED) SELECTED -- OVERRIDE FOR ALL SELECTED NODES - }else if( query == "(SELECTED)" || query == "SELECTED" ){ - - return this.getSelectedNodes( true, sort_result ); - - //(NOT SELECTED) !SELECTED NOT SELECTED -- OVERRIDE FOR ALL SELECTED NODES - - }else if( query == "(NOT SELECTED)" || - query == "NOT SELECTED" || - query == "(! SELECTED)" || - query == "! SELECTED" || - query == "(UNSELECTED)" || - query == "UNSELECTED" - ){ - - var nodes_returned = []; - - var sel_list = {}; - for( var p=0;p 1 && query_match[1] && query_match[1].length > 0 ){ - //CONSIDER A LIST, COMMA SEPARATION, AND ESCAPED COMMAS. - var query_list = []; - var last_str = ''; - var split_list = query_match[1].split( "," ); - - for( var n=0; n0 ){ - query_list.push( last_str ); - } - - this.$.debug( "GETTING NODE LIST FROM QUERY", this.$.DEBUG_LEVEL.LOG ); - //NOW DEAL WITH WILDCARDS - - var added_nodes = {}; //Add the full path to a list when adding/querying existing. Prevent duplicate attempts. - var all_nodes = false; - for( var x=0; x=0) || (query_list[x].indexOf("?")>=0) ){ - //THERE ARE WILDCARDS. - this.$.debug( "WILDCARD NODE QUERY: "+query_list[x], this.$.DEBUG_LEVEL.LOG ); - //Make a wildcard search for the nodes. - - if( all_nodes === false ){ - all_nodes = this.nodes; - } - - //Run the Wildcard regexp against the available nodes. - var regexp = query_list[x]; - regexp = regexp.split( "?" ).join( "." ); - regexp = regexp.split( "*" ).join( ".*?" ); - regexp = '^'+regexp+'$'; - - this.$.debug( "WILDCARD QUERY REGEXP: "+regexp, this.$.DEBUG_LEVEL.LOG ); - - var regexp_filter = RegExp( regexp, 'gi' ); - for( var n=0;n=3 && query_list[x]=="re:" ){ - //THERE ARE WILDCARDS. - this.$.debug( "REGEXP NODE QUERY: "+query_list[x], this.$.DEBUG_LEVEL.LOG ); - //Make a wildcard search for the nodes. - - if( all_nodes === false ){ - all_nodes = this.nodes; - } - - //Run the Wildcard regexp against the available nodes. - var regexp = query_list[x]; - this.$.debug( "REGEXP QUERY REGEXP: "+regexp, this.$.DEBUG_LEVEL.LOG ); - - var regexp_filter = RegExp( regexp, 'gi' ); - for( var n=0;n 2 ){ - var filtered_nodes = nodes_returned; - for( var n=2;n=0; j--){ - //if (nodes[j].attributes.drawing.element.frames[_frame].isBlank) continue; - - DrawingTools.setCurrentDrawingFromNodeName( nodes[j].path, _frame ); - Action.perform("selectAll()", "cameraView"); - - // select all and check. If empty, operation ends for the current frame - if (Action.validate("copy()", "cameraView").enabled){ - Action.perform("copy()", "cameraView"); - DrawingTools.setCurrentDrawingFromNodeName( _mergedNode.path, _frame ); - Action.perform("paste()", "cameraView"); - } - } - } - - _mergedNode.attributes.drawing.element.column.extendExposures(); - _mergedNode.placeAtCenter(nodes) - - // connect to the same composite as the first node, at the same place - // delete nodes that were merged if parameter is specified - if (deleteMerged){ - for (var i in nodes){ - nodes[i].remove(); - } - } - return _mergedNode; -} - - -/** - * export a template from the specified nodes. - * @param {$.oNodes[]} nodes The list of nodes included in the template. - * @param {bool} [exportPath] The path of the TPL file to export. - * @param {string} [exportPalettesMode='usedOnly'] can have the values : "usedOnly", "all", "createPalette" - * @param {string} [renameUsedColors=] if creating a palette, optionally set here the name for the colors (they will have a number added to each) - * @param {copyOptions} [copyOptions] An object containing paste options as per Harmony's standard paste options. - * - * @return {bool} The success of the export. - * @todo turn exportPalettesMode into an enum? - * @example - * // how to export a clean palette with no extra drawings and everything renamed by frame, and only the necessary colors gathered in one palette: - * - * $.beginUndo(); - * - * var doc = $.scn; - * var nodes = doc.getSelectedNodes(); - * - * for (var i in nodes){ - * if (nodes[i].type != "READ") continue; - * - * var myColumn = nodes[i].element.column; // we grab the column directly from the element of the node - * myColumn.removeUnexposedDrawings(); // remove extra unused drawings - * myColumn.renameAllByFrame(); // rename all drawings by frame - * } - * - * doc.exportTemplate(nodes, "C:/templateExample.tpl", "createPalette"); // "createPalette" value will create one palette for all colors - * - * $.endUndo(); - */ -$.oScene.prototype.exportTemplate = function(nodes, exportPath, exportPalettesMode, renameUsedColors, copyOptions){ - if (typeof exportPalettesMode === 'undefined') var exportPalettesMode = "usedOnly"; - if (typeof copyOptions === 'undefined') var copyOptions = copyPaste.getCurrentCreateOptions(); - if (typeof renameUsedColors === 'undefined') var renameUsedColors = false; - - if (!Array.isArray(nodes)) nodes = [nodes]; - - // add nodes included in groups as they'll get automatically exported - var _allNodes = nodes; - for (var i in nodes){ - if (nodes[i].type == "GROUP") _allNodes = _allNodes.concat(nodes[i].subNodes(true)); - } - - var _readNodes = _allNodes.filter(function (x){return x.type == "READ";}); - - var _templateFolder = new this.$.oFolder(exportPath); - while (_templateFolder.exists) _templateFolder = new this.$.oFolder(_templateFolder.path.replace(".tpl", "_1.tpl")); - - var _name = _templateFolder.name.replace(".tpl", ""); - var _folder = _templateFolder.folder.path; - - // create the palette with only the colors contained in the layers - if (_readNodes.length > 0){ - if(exportPalettesMode == "usedOnly"){ - var _usedPalettes = []; - var _usedPalettePaths = []; - for (var i in _readNodes){ - var _palettes = _readNodes[i].getUsedPalettes(); - for (var j in _palettes){ - if (_usedPalettePaths.indexOf(_palettes[j].path.path) == -1){ - _usedPalettes.push(_palettes[j]); - _usedPalettePaths.push(_palettes[j].path.path); - } - } - } - this.$.debug("found palettes : "+_usedPalettes.map(function(x){return x.name}), this.$.DEBUG_LEVEL.LOG); - } - - if (exportPalettesMode == "createPalette"){ - var templatePalette = this.createPaletteFromNodes(_readNodes, _name, renameUsedColors); - var _usedPalettes = [templatePalette]; - } - } - - - this.selectedNodes = _allNodes; - this.selectedFrames = [this.startPreview, this.stopPreview]; - - this.$.debug("exporting selection :"+this.selectedFrames+"\n\n"+this.selectedNodes.join("\n")+"\n\n to folder : "+_folder+"/"+_name, this.$.DEBUG_LEVEL.LOG) - - try{ - var success = copyPaste.createTemplateFromSelection (_name, _folder); - if (success == "") throw new Error("export failed") - }catch(error){ - this.$.debug("Export of template "+_name+" failed. Error: "+error, this.$.DEBUG_LEVEL.ERROR); - return false; - } - - this.$.debug("export of template "+_name+" finished, cleaning palettes", this.$.DEBUG_LEVEL.LOG); - - if (_readNodes.length > 0 && exportPalettesMode != "all"){ - // deleting the extra palettes from the exported template - var _paletteFolder = new this.$.oFolder(_templateFolder.path+"/palette-library"); - var _paletteFiles = _paletteFolder.getFiles(); - var _paletteNames = _usedPalettes.map(function(x){return x.name}); - - for (var i in _paletteFiles){ - var _paletteName = _paletteFiles[i].name; - if (_paletteNames.indexOf(_paletteName) == -1) _paletteFiles[i].remove(); - } - - // building the template palette list - var _listFile = ["ToonBoomAnimationInc PaletteList 1"]; - - if (exportPalettesMode == "createPalette"){ - _listFile.push("palette-library/"+_name+' LINK "'+_paletteFolder+"/"+_name+'.plt"'); - }else if (exportPalettesMode == "usedOnly"){ - for (var i in _usedPalettes){ - this.$.debug("palette "+_usedPalettes[i].name+" to be included in template", this.$.DEBUG_LEVEL.LOG); - _listFile.push("palette-library/"+_usedPalettes[i].name+' LINK "'+_paletteFolder+"/"+_usedPalettes[i].name+'.plt"'); - } - } - - var _paletteListFile = new this.$.oFile(_templateFolder.path+"/PALETTE_LIST"); - try{ - _paletteListFile.write(_listFile.join("\n")); - }catch(err){ - this.$.debug(err, this.$.DEBUG_LEVEL.ERROR) - } - - // remove the palette created for the template - if (exportPalettesMode == "createPalette"){ - var _paletteFile = _paletteFolder.getFiles()[0]; - if (_paletteFile){ - _paletteFile.rename(_name); - if (templatePalette) templatePalette.remove(true); - } - } - } - - selection.clearSelection(); - return true; -} - - -/** - * Imports the specified template into the scene. - * @deprecated - * @param {string} tplPath The path of the TPL file to import. - * @param {string} [group] The path of the existing target group to which the TPL is imported. - * @param {$.oNode[]} [destinationNodes] The nodes affected by the template. - * @param {bool} [extendScene] Whether to extend the exposures of the content imported. - * @param {$.oPoint} [nodePosition] The position to offset imported new nodes. - * @param {object} [pasteOptions] An object containing paste options as per Harmony's standard paste options. - * - * @return {$.oNode[]} The resulting pasted nodes. - */ -$.oScene.prototype.importTemplate = function( tplPath, group, destinationNodes, extendScene, nodePosition, pasteOptions ){ - if (typeof group === 'undefined') var group = this.root; - var _group = (group instanceof this.$.oGroupNode)?group:this.$node(group); - - if (_group != null && _group instanceof this.$.oGroupNode){ - this.$.log("oScene.importTemplate is deprecated. Use oGroupNode.importTemplate instead") - var _node = _group.addNode(tplPath, destinationNodes, extendScene, nodePosition, pasteOptions ) - return _nodes; - }else{ - throw new Error (group+" is an invalid group to import the template into.") - } -} - - -/** - * Exports a png of the selected node/frame. if no node is given, all layers will be visible. - * @param {$.oFile} path The path in which to save the image. Image will be outputted as PNG. - * @param {$.oNode} [includedNodes] The nodes to include in the rendering. If no node is specified, all layers will be visible. - * @param {int} [exportFrame] The frame at which to create the image. By default, the timeline current Frame. - * @param {bool} [exportCameraFrame=false] Whether to export the camera frames - * @param {bool} [exportBackground=false] Whether to add a white background. - * @param {float} [frameScale=1] A factor by which to scale the frame. ex: 1.05 will add a 10% margin (5% on both sides) - */ -$.oScene.prototype.exportLayoutImage = function (path, includedNodes, exportFrame, exportCameraFrame, exportBackground, frameScale, format){ - if (typeof includedNodes === 'undefined') var includedNodes = []; - if (typeof exportCameraFrame === 'undefined') var exportCameraFrame = false; - if (typeof exportBackground === 'undefined') var exportBackground = false; - if (typeof frameScale === 'undefined') var frameScale = 1; - if (typeof frame === 'undefined') var frame = 1; - if (typeof format === 'undefined') var format = "PNG4"; - if (typeof path != this.$.oFile) path = new $.oFile(path); - - var exporter = new LayoutExport(); - var params = new LayoutExportParams(); - params.renderStaticCameraAtSceneRes = true; - params.fileFormat = format; - params.borderScale = frameScale; - params.exportCameraFrame = exportCameraFrame; - params.exportAllCameraFrame = false; - params.filePattern = path.name; - params.fileDirectory = path.folder; - params.whiteBackground = exportBackground; - - includedNodes = includedNodes.filter(function(x){return ["CAMERA", "READ", "COLOR_CARD", "GRADIENT"].indexOf(x.type) != -1 && x.enabled }) - var _timeline = new this.$.oTimeline(); - includedNodes = includedNodes.sort(function (a, b){return b.timelineIndex(_timeline) - a.timelineIndex(_timeline)}) - - if (includedNodes.length == 0) { - params.node = this.root; - params.frame = exportFrame; - params.layoutname = this.name; - exporter.addRender(params); - if (!exporter.save(params)) throw new Error("failed to export layer "+oNode.name+" at location "+path); - }else{ - for (var i in includedNodes){ - var includedNode = includedNodes[i]; - params.whiteBackground = (i==0 && exportBackground); - params.node = includedNode.path; - params.frame = exportFrame; - params.layoutname = includedNode.name; - params.exportCameraFrame = ((i == includedNodes.length-1) && exportCameraFrame); - exporter.addRender(params); - if (!exporter.save(params)) throw new Error("failed to export layer "+oNode.name+" at location "+path); - } - } - - exporter.flush(); - - return path; -} - - -/** - * Export the scene as a single PSD file, with layers described by the layerDescription array. This function is not supported in batch mode. - * @param {$.oFile} path - * @param {float} margin a factor by which to increase the rendering area. for example, 1.05 creates a 10% margin. (5% on each side) - * @param {Object[]} layersDescription must be an array of objects {layer: $.oNode, frame: int} which describe all the images to export. By default, will include all visible layers of the timeline. - */ -$.oScene.prototype.exportPSD = function (path, margin, layersDescription){ - if (typeof margin === 'undefined') var margin = 1; - if (typeof layersDescription === 'undefined') { - // export the current frame for each drawing layer present in the default timeline. - var _allNodes = this.nodes.filter(function(x){return ["READ", "COLOR_CARD", "GRADIENT"].indexOf(x.type) != -1 && x.enabled }) - var _timeline = new this.$.oTimeline(); - _allNodes = _allNodes.sort(function (a, b){return b.timelineIndex(_timeline) - a.timelineIndex(_timeline)}) - var _scene = this; - var layersDescription = _allNodes.map(function(x){return ({layer: x, frame: _scene.currentFrame})}) - } - if (typeof path != this.$.oFile) path = new $.oFile(path) - var tempPath = new $.oFile(path.folder+"/"+path.name+"~") - - var errors = []; - - // setting up render - var exporter = new LayoutExport(); - var params = new LayoutExportParams(); - params.renderStaticCameraAtSceneRes = true; - params.fileFormat = "PSD4"; - params.borderScale = margin; - params.exportCameraFrame = false; - params.exportAllCameraFrame = false; - params.filePattern = tempPath.name; - params.fileDirectory = tempPath.folder; - params.whiteBackground = false; - - // export layers - for (var i in layersDescription){ - var _frame = layersDescription[i].frame; - var _layer = layersDescription[i].layer; - - params.node = _layer.path; - params.frame = _frame; - params.layoutname = _layer.name; - params.exportCameraFrame = (i == layersDescription.length-1); - exporter.addRender(params); - - if (!exporter.save(params)) errors.push(params.layoutname); - } - - if (errors.length > 0) throw new Error("errors during export of file "+path+" with layers "+errors) - - // write file - exporter.flush(); - - if (path.exists) path.remove(); - log(tempPath.exist+" "+tempPath); - tempPath.rename(path.name+".psd"); -} - - -/** - * Imports a PSD to the scene. - * @Deprecated use oGroupNode.importPSD instead - * @param {string} path The palette file to import. - * @param {string} [group] The path of the existing group to import the PSD into. - * @param {$.oPoint} [nodePosition] The position for the node to be placed in the network. - * @param {bool} [separateLayers] Separate the layers of the PSD. - * @param {bool} [addPeg] Whether to add a peg. - * @param {bool} [addComposite] Whether to add a composite. - * @param {string} [alignment] Alignment type. - * - * @return {$.oNode[]} The nodes being created as part of the PSD import. - */ -$.oScene.prototype.importPSD = function( path, group, nodePosition, separateLayers, addPeg, addComposite, alignment ){ - if (typeof group === 'undefined') var group = this.root; - var _group = (group instanceof this.$.oGroupNode)?group:this.$node(group); - - if (_group != null && _group instanceof this.$.oGroupNode){ - this.$.log("oScene.importPSD is deprecated. Use oGroupNode.importPSD instead") - var _node = _group.importPSD(path, separateLayers, addPeg, addComposite, alignment, nodePosition) - return _node; - }else{ - throw new Error (group+" is an invalid group to import a PSD file to.") - } -} - - -/** - * Updates a previously imported PSD by matching layer names. - * @deprecated - * @param {string} path The PSD file to update. - * @param {bool} [separateLayers] Whether the PSD was imported as separate layers. - * - * @returns {$.oNode[]} The nodes affected by the update - */ -$.oScene.prototype.updatePSD = function( path, group, separateLayers ){ - if (typeof group === 'undefined') var group = this.root; - var _group = (group instanceof this.$.oGroupNode)?group:this.$node(group); - - if (_group != null && _group instanceof this.$.oGroupNode){ - this.$.log("oScene.updatePSD is deprecated. Use oGroupNode.updatePSD instead") - var _node = _group.updatePSD(path, separateLayers) - return _node; - }else{ - throw new Error (group+" is an invalid group to update a PSD file in.") - } -} - - -/** - * Imports a sound into the scene - * @param {string} path The sound file to import. - * @param {string} layerName The name to give the layer created. - * - * @return {$.oNode} The imported sound column. - */ - $.oScene.prototype.importSound = function(path, layerName){ - var _audioFile = new this.$.oFile(path); - if (typeof layerName === 'undefined') var layerName = _audioFile.name; - - // creating an audio column for the sound - var _soundColumn = this.addColumn("SOUND", layerName); - column.importSound( _soundColumn.name, 1, path); - - return _soundColumn; - } - - - /** - * Exports a QT of the scene - * @param {string} path The path to export the quicktime file to. - * @param {string} display The name of the display to use to export. - * @param {double} scale The scale of the export compared to the scene resolution. - * @param {bool} exportSound Whether to include the sound in the export. - * @param {bool} exportPreviewArea Whether to only export the preview area of the timeline. - * - * @return {bool} The success of the export - */ -$.oScene.prototype.exportQT = function( path, display, scale, exportSound, exportPreviewArea){ - if (typeof display === 'undefined') var display = node.getName(node.getNodes(["DISPLAY"])[0]); - if (typeof exportSound === 'undefined') var exportSound = true; - if (typeof exportPreviewArea === 'undefined') var exportPreviewArea = false; - if (typeof scale === 'undefined') var scale = 1; - - if (display instanceof oNode) display = display.name; - - var _startFrame = exportPreviewArea?scene.getStartFrame():1; - var _stopFrame = exportPreviewArea?scene.getStopFrame():this.length-1; - var _resX = this.defaultResolutionX*scale - var _resY= this.defaultResolutionY*scale - return exporter.exportToQuicktime ("", _startFrame, _stopFrame, exportSound, _resX, _resY, path, display, true, 1); -} - - -/** - * Imports a QT into the scene - * @Deprecated - * @param {string} path The quicktime file to import. - * @param {string} group The group to import the QT into. - * @param {$.oPoint} nodePosition The position for the node to be placed in the network. - * @param {bool} extendScene Whether to extend the scene to the duration of the QT. - * @param {string} alignment Alignment type. - * - * @return {$.oNode} The imported Quicktime Node. - */ -$.oScene.prototype.importQT = function( path, group, importSound, nodePosition, extendScene, alignment ){ - if (typeof group === 'undefined') var group = this.root; - var _group = (group instanceof this.$.oGroupNode)?group:this.$node(group); - - if (_group != null && _group instanceof this.$.oGroupNode){ - this.$.log("oScene.importQT is deprecated. Use oGroupNode.importQTs instead") - var _node = _group.importQT(path, importSound, extendScene, alignment, nodePosition) - return _node; - }else{ - throw new Error (group+" is an invalid group to import a QT file to.") - } -} - - -/** - * Adds a backdrop to a group in a specific position. - * @Deprecated - * @param {string} groupPath The group in which this backdrop is created. - * @param {string} title The title of the backdrop. - * @param {string} body The body text of the backdrop. - * @param {$.oColorValue} color The oColorValue of the node. - * @param {float} x The X position of the backdrop, an offset value if nodes are specified. - * @param {float} y The Y position of the backdrop, an offset value if nodes are specified. - * @param {float} width The Width of the backdrop, a padding value if nodes are specified. - * @param {float} height The Height of the backdrop, a padding value if nodes are specified. - * - * @return {$.oBackdrop} The created backdrop. - */ -$.oScene.prototype.addBackdrop = function( groupPath, title, body, color, x, y, width, height ){ - if (typeof group === 'undefined') var group = this.root; - var _group = (group instanceof this.$.oGroupNode)?group:this.$node(group); - - if (_group != null && _group instanceof this.$.oGroupNode){ - this.$.log("oScene.addBackdrop is deprecated. Use oGroupNode.addBackdrop instead") - var _backdrop = _group.addBackdrop(title, body, color, x, y, width, height) - return _backdrop; - }else{ - throw new Error (groupPath+" is an invalid group to add the BackDrop to.") - } -}; - - -/** - * Adds a backdrop to a group around specified nodes - * @Deprecated - * @param {string} groupPath The group in which this backdrop is created. - * @param {$.oNode[]} nodes The nodes that the backdrop encompasses. - * @param {string} title The title of the backdrop. - * @param {string} body The body text of the backdrop. - * @param {$.oColorValue} color The oColorValue of the node. - * @param {float} x The X position of the backdrop, an offset value if nodes are specified. - * @param {float} y The Y position of the backdrop, an offset value if nodes are specified. - * @param {float} width The Width of the backdrop, a padding value if nodes are specified. - * @param {float} height The Height of the backdrop, a padding value if nodes are specified. - * - * @return {$.oBackdrop} The created backdrop. - */ -$.oScene.prototype.addBackdropToNodes = function( groupPath, nodes, title, body, color, x, y, width, height ){ - if (typeof group === 'undefined') var group = this.root; - var _group = (group instanceof this.$.oGroupNode)?group:this.$node(group); - - if (_group != null && _group instanceof this.$.oGroupNode) { - this.$.log("oScene.addBackdropToNodes is deprecated. Use oGroupNode.addBackdropToNodes instead") - var _backdrop = _group.addBackdropToNodes(nodes, title, body, color, x, y, width, height) - return _backdrop; - }else{ - throw new Error (groupPath+" is an invalid group to add the BackDrop to.") - } -}; - - -/** - * Saves the scene. - */ -$.oScene.prototype.save = function( ){ - scene.saveAll(); -} - - -/** - * Saves the scene in a different location (only available on offline scenes). - * @param {string} newPath the new location for the scene (must be a folder path and not a .xstage) - */ -$.oScene.prototype.saveAs = function(newPath){ - if (this.online) { - this.$.debug("Can't use saveAs() in database mode.", this.$.DEBUG_LEVEL.ERROR); - return; - } - - if (newPath instanceof this.$.oFile) newPath = newPath.path; - return scene.saveAs(newPath); -} - - -/** - * Saves the scene as new version. - * @param {string} newVersionName The name for the new version - * @param {bool} markAsDefault Wether to make this new version the default version that will be opened from the database. - */ -$.oScene.prototype.saveNewVersion = function(newVersionName, markAsDefault){ - if (typeof markAsDefault === 'undefined') var markAsDefault = true; - - return scene.saveAsNewVersion (newVersionName, markAsDefault); -} - - -/** - * Renders the write nodes of the scene. This action saves the scene. - * @param {bool} [renderInBackground=true] Whether to do the render on the main thread and block script execution - * @param {int} [startFrame=1] The first frame to render - * @param {int} [endFrame=oScene.length] The end of the render (non included) - * @param {int} [resX] The horizontal resolution of the render. Uses the scene resolution by default. - * @param {int} [resY] The vertical resolution of the render. Uses the scene resolution by default. - * @param {string} [preRenderScript] The path to the script to execute on the scene before doing the render - * @param {string} [postRenderScript] The path to the script to execute on the scene after the render is finished - * @return {$.oProcess} In case of using renderInBackground, will return the oProcess object doing the render - */ -$.oScene.prototype.renderWriteNodes = function(renderInBackground, startFrame, endFrame, resX, resY, preRenderScript, postRenderScript){ - if (typeof renderInBackground === 'undefined') var renderInBackground = true; - if (typeof startFrame === 'undefined') var startFrame = 1; - if (typeof endFrame === 'undefined') var endFrame = this.length+1; - if (typeof resX === 'undefined') var resX = this.resolutionX; - if (typeof resY === 'undefined') var resY = this.resolutionY; - - this.save(); - var harmonyBin = specialFolders.bin+"/HarmonyPremium.exe"; - - var args = ["-batch", "-frames", startFrame, endFrame, "-res", resX, resY, this.fov]; - - if (typeof preRenderScript !== 'undefined'){ - args.push("-preRenderScript"); - args.push(preRenderScript); - } - - if (typeof postRenderScript !== 'undefined'){ - args.push("-postRenderScript"); - args.push(postRenderScript); - } - - if (this.online){ - args.push("-env"); - args.push(this.environnement); - args.push("-job"); - args.push(this.job); - args.push("-scene"); - args.push(this.name); - }else{ - args.push(this.stage); - } - - var p = new this.$.oProcess(harmonyBin, args); - p.readChannel = "All"; - - this.$.log("Starting render of scene "+this.name); - if (renderInBackground){ - var length = endFrame - startFrame + 1; - - var progressDialogue = new this.$.oProgressDialog("Rendering : ",length,"Render Write Nodes", true); - - var cancelRender = function(){ - p.kill(); - this.$.alert("Render was canceled.") - } - - var renderProgress = function(message){ - // reporting progress to log window - var progressRegex = /Rendered Frame ([0-9]+)/igm; - var matches = []; - while (match = progressRegex.exec(message)) { - matches.push(match[1]); - } - if (matches.length!=0){ - var progress = parseInt(matches.pop(), 10) - startFrame; - progressDialogue.label = "Rendering Frame: " + progress + "/" + length; - progressDialogue.value = progress; - var percentage = Math.round(progress/length * 100); - this.$.log("render : " + percentage + "% complete"); - } - } - - var renderFinished = function(exitCode){ - if (exitCode == 0){ - // render success - progressDialogue.label = "Rendering Finished" - progressDialogue.value = length; - this.$.log(exitCode + " : render finished"); - }else{ - this.$.log(exitCode + " : render cancelled"); - } - } - - progressDialogue.canceled.connect(this, cancelRender); - p.readyRead.connect(this, renderProgress); - p.finished.connect(this, renderFinished); - p.launchAndRead(); - return p; - }else{ - var readout = p.execute(); - this.$.log("render finished"); - return readout; - } -} - -/** - * Closes the scene. - * @param {bool} [exit] Whether it should exit after closing. - */ -$.oScene.prototype.close = function( exit ){ - if (typeof nodePosition === 'undefined') exit = false; - - if( exit ){ - scene.closeSceneAndExit(); - }else{ - scene.closeScene(); - } -} - -/** - * Gets the current camera matrix. - * - * @return {Matrix4x4} The matrix of the camera. - */ -$.oScene.prototype.getCameraMatrix = function( ){ - return scene.getCameraMatrix(); -} - -/** - * Gets the current projection matrix. - * - * @return {Matrix4x4} The projection matrix of the camera/scene. - */ -$.oScene.prototype.getProjectionMatrix = function( ){ - var fov = this.fov; - var f = scene.toOGL( new Point3d( 0.0, 0.0, this.unitsZ ) ).z; - var n = 0.00001; - - //Standard pprojection matrix derivation. - var S = 1.0 / Math.tan( ( fov/2.0 ) * ( $.pi/180.0 ) ); - var projectionMatrix = [ S, 0.0, 0.0, 0.0, - 0.0, S, 0.0, 0.0, - 0.0, 0.0, -1.0*(f/(f-n)), -1.0, - 0.0, 0.0, -1.0*((f*n)/(f-n)), 0.0 - ]; - - var newMatrix = new Matrix4x4(); - for( var r=0;r<4;r++ ){ - for( var c=0;c<4;c++ ){ - newMatrix["m"+r+""+c] = projectionMatrix[ (c*4.0)+r ]; - } - } - return newMatrix; -} - - -/** - * Gets the current scene's metadata. - * - * @see $.oMetadata - * @return {$.oMetadata} The metadata of the scene. - */ -$.oScene.prototype.getMetadata = function( ){ - return new this.$.oMetadata( ); -} - - -// Short Notations - -/** - * Gets a node by the path. - * @param {string} fullPath The path of the node in question. - * - * @return {$.oNode} The node found given the query. - */ -$.oScene.prototype.$node = function( fullPath ){ - return this.getNodeByPath( fullPath ); -} - -/** - * Gets a column by the name. - * @param {string} uniqueName The unique name of the column as a string. - * @param {$.oAttribute} oAttributeObject The oAttribute object the column is linked to. - * - * @return {$.oColumn} The node found given the query. - */ -$.oScene.prototype.$column = function( uniqueName, oAttributeObject ){ - return this.getColumnByName( uniqueName, oAttributeObject ); -} - - -/** - * Gets a palette by its name. - * @param {string} name The name of the palette. - * - * @return {$.oPalette} The node found given the query. - */ -$.oScene.prototype.$palette = function( name ){ - return this.getPaletteByName( name ); -} diff --git a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_threading.js b/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_threading.js deleted file mode 100644 index 064791f851..0000000000 --- a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony/openHarmony_threading.js +++ /dev/null @@ -1,684 +0,0 @@ -////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// -// -// openHarmony Library -// -// -// Developped by Mathieu Chaptel, Chris Fourney -// -// -// This library is an open source implementation of a Document Object Model -// for Toonboom Harmony. It also implements patterns similar to JQuery -// for traversing this DOM. -// -// Its intended purpose is to simplify and streamline toonboom scripting to -// empower users and be easy on newcomers, with default parameters values, -// and by hiding the heavy lifting required by the official API. -// -// This library is provided as is and is a work in progress. As such, not every -// function has been implemented or is garanteed to work. Feel free to contribute -// improvements to its official github. If you do make sure you follow the provided -// template and naming conventions and document your new methods properly. -// -// This library doesn't overwrite any of the objects and classes of the official -// Toonboom API which must remains available. -// -// This library is made available under the Mozilla Public license 2.0. -// https://www.mozilla.org/en-US/MPL/2.0/ -// -// The repository for this library is available at the address: -// https://github.com/cfourney/OpenHarmony/ -// -// -// For any requests feel free to contact m.chaptel@gmail.com -// -// -// -// -////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////////////// - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oThread class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * The base class for the $.oThread -- WIP, NOT TRULY THREADED AS THE EVENT MANAGER DOESNT ALLOW FOR THREADS YET. - * @constructor - * @classdesc $.oThread Base Class - * @param {function} kernel The kernel that is iterating. - * @param {object[]} list The list of elements to iterate upon. - * @param {int} [threadCount] The amount of threads to initiate. Default: 5 - * @param {bool} [start] Whether to start on instantiation, or to wait until prompted. Default: false - * @param {int} [timeout] Timeout in MS - * @param {bool} [reserveThread] Whether to reserve a thread for this to process while blocking. - * - * @property {int} threadCount The amount of threads to initiate. - * @property {QTimer[]} threads The underlying QTimers that behave as threads. - * @property {object[]} results_thread The results from the kernel, should match indices of provided list. - * @property {string[]} error_thread The errors from the kernel, in the event there are code errors. - * @property {bool[]} complete_thread The completion (note: not success) state of the thread. Success state would be the result. - * @property {bool} started The start state of all threads. - * @property {int} timeout MS timeout for blocking processes. - */ -$.oThread = function( kernel, list, threadCount, start, timeout, reserveThread ){ - if (typeof threadCount === 'undefined') var threadCount = "2"; - if (typeof start === 'undefined') var start = false; - if (typeof reserveThread === 'undefined') reserveThread = true; - - threadCount = Math.min( threadCount, list.length ); - - this.list = list; - this.threadCount = threadCount; - this.threads = []; - this.started_thread = []; - this.results_thread = []; - this.error_thread = []; - this.complete_thread = []; - - this.started = false; - - this.startAtInstantiation = start; - this.threads_available = false; - this.reserveThread = reserveThread; - this.reservedThread = false; - - this.timeout = 1000.0 * 60.0; - if ( timeout ) this.timeout = timeout; - - //Instantiate the results. - for( var n=0;n"; -} - - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oNodeLayer class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - -/** - * Constructor for $.oNodeLayer class - * @classdesc - * The $.oNodeLayer class represents a timeline layer corresponding to a node from the scene. - * @constructor - * @extends $.oLayer - * @param {oTimeline} oTimelineObject The timeline associated to this layer. - * @param {int} layerIndex The index of the layer on the timeline. - * - * @property {int} index The index of the layer on the timeline. - * @property {oTimeline} timeline The timeline associated to this layer. - * @property {oNode} node The node associated to the layer. - */ -$.oNodeLayer = function( oTimelineObject, layerIndex){ - this.$.oLayer.apply(this, [oTimelineObject, layerIndex]); -} -$.oNodeLayer.prototype = Object.create($.oLayer.prototype); - - -/** - * The name of this layer/node. - * @name $.oNodeLayer#name - * @type {string} - */ -Object.defineProperty($.oNodeLayer.prototype, "name", { - get: function(){ - return this.node.name; - }, - set: function(newName){ - this.node.name = newName; - } -}) - - -/** - * The layer index when ignoring subLayers. - * @name $.oNodeLayer#layerIndex - * @type {int} -*/ -Object.defineProperty($.oNodeLayer.prototype, "layerIndex", { - get: function(){ - var _layers = this.timeline.layers.map(function(x){return x.node.path}); - return _layers.indexOf(this.node.path); - } -}) - - -/** - * wether or not the layer is selected. - * @name $.oNodeLayer#selected - * @type {bool} - */ -Object.defineProperty($.oNodeLayer.prototype, "selected", { - get: function(){ - if ($.batchMode) return this.node.selected; - - var selectionLength = Timeline.numLayerSel - for (var i=0; i"; -} - - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oDrawingLayer class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - -/** - * Constructor for $.oDrawingLayer class - * @classdesc - * The $.oDrawingLayer class represents a timeline layer corresponding to a 'READ' node (or Drawing in Toonboom UI) from the scene. - * @constructor - * @extends $.oNodeLayer - * @param {oTimeline} oTimelineObject The timeline associated to this layer. - * @param {int} layerIndex The index of the layer on the timeline. - * - * @property {int} index The index of the layer on the timeline. - * @property {oTimeline} timeline The timeline associated to this layer. - * @property {oNode} node The node associated to the layer. - */ -$.oDrawingLayer = function( oTimelineObject, layerIndex){ - this.$.oNodeLayer.apply(this, [oTimelineObject, layerIndex]); -} -$.oDrawingLayer.prototype = Object.create($.oNodeLayer.prototype); - - -/** - * The oFrame objects that hold the drawings for this layer. - * @name oDrawingLayer#drawingColumn - * @type {oFrame[]} - */ - Object.defineProperty($.oDrawingLayer.prototype, "drawingColumn", { - get: function(){ - return this.node.attributes.drawing.elements.column; - } -}) - - -/** - * The oFrame objects that hold the drawings for this layer. - * @name oDrawingLayer#exposures - * @type {oFrame[]} - */ -Object.defineProperty($.oDrawingLayer.prototype, "exposures", { - get: function(){ - return this.drawingColumn.frames; - } -}) - - -/** - * @private - */ - $.oDrawingLayer.prototype.toString = function(){ - return "<$.oDrawingLayer '"+this.name+"'>"; -} - - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oColumnLayer class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// -/** - * Constructor for $.oColumnLayer class - * @classdesc - * The $.oColumnLayer class represents a timeline layer corresponding to the animated values of a column linked to a node. - * @constructor - * @extends $.oLayer - * @param {oTimeline} oTimelineObject The timeline associated to this layer. - * @param {int} layerIndex The index of the layer on the timeline. - * - * @property {int} index The index of the layer on the timeline. - * @property {oTimeline} timeline The timeline associated to this layer. - * @property {oNode} node The node associated to the layer. - */ -$.oColumnLayer = function( oTimelineObject, layerIndex){ - this.$.oLayer.apply(this, [oTimelineObject, layerIndex]); -} -$.oColumnLayer.prototype = Object.create($.oLayer.prototype); - - -/** - * The name of this layer. - * (corresponding to the display name of the column, not the name displayed in timeline, not exposed by the Toonboom API). - * @name $.oColumnLayer#name - * @type {string} - */ -Object.defineProperty($.oColumnLayer.prototype, "name", { - get: function(){ - return this.column.name; - } -}) - - - -/** - * the node attribute associated with this layer. Only available if the attribute has a column. - * @name $.oColumnLayer#attribute - * @type {$.oColumn} - */ -Object.defineProperty($.oColumnLayer.prototype, "attribute", { - get: function(){ - if (!this._attribute){ - this._attribute = this.column.attributeObject; - } - return this._attribute - } -}) - - - -/** - * the node associated with this layer - * @name $.oColumnLayer#column - * @type {$.oColumn} - */ -Object.defineProperty($.oColumnLayer.prototype, "column", { - get: function(){ - if (!this._column){ - var _name = Timeline.layerToColumn(this.index); - var _attribute = this.node.getAttributeByColumnName(_name); - this._column = _attribute.column; - } - return this._column; - } -}) - - -/** - * The layer representing the node to which this column is linked - */ -Object.defineProperty($.oColumnLayer.prototype, "nodeLayer", { - get: function(){ - var _node = this.node; - var _nodeLayerType = this.$.oNodeLayer; - this.timeline.allLayers.filter(function (x){return x.node == _node && x instanceof _nodeLayerType})[0]; - } -}) - - - -/** - * @private - */ - $.oColumnLayer.prototype.toString = function(){ - return "<$.oColumnLayer '"+this.name+"'>"; -} - - - -////////////////////////////////////// -////////////////////////////////////// -// // -// // -// $.oTimeline class // -// // -// // -////////////////////////////////////// -////////////////////////////////////// - - -/** - * The $.oTimeline constructor. - * @constructor - * @classdesc The $.oTimeline class represents a timeline corresponding to a specific display. - * @param {string} [display] The display node's path. By default, the defaultDisplay of the scene. - * - * @property {string} display The display node's path. - */ -$.oTimeline = function(display){ - if (typeof display === 'undefined') var display = this.$.scn.defaultDisplay; - if (display instanceof this.$.oNode) display = display.path; - - this.display = display; -} - - -/** - * Gets the list of node layers in timeline. - * @name $.oTimeline#layers - * @type {$.oLayer[]} - */ -Object.defineProperty($.oTimeline.prototype, 'layers', { - get : function(){ - var nodeLayer = this.$.oNodeLayer; - return this.allLayers.filter(function (x){return x instanceof nodeLayer}) - } -}); - - -/** - * Gets the list of all layers in timeline, nodes and columns. In batchmode, will only return the nodes, not the sublayers. - * @name $.oTimeline#allLayers - * @type {$.oLayer[]} - */ -Object.defineProperty($.oTimeline.prototype, 'allLayers', { - get : function(){ - if (!this._layers){ - var _layers = []; - - if (!$.batchMode){ - for( var i=0; i < Timeline.numLayers; i++ ){ - if (Timeline.layerIsNode(i)){ - var _layer = new this.$.oNodeLayer(this, i); - if (_layer.node.type == "READ") var _layer = new this.$.oDrawingLayer(this, i); - }else if (Timeline.layerIsColumn(i)) { - var _layer = new this.$.oColumnLayer(this, i); - }else{ - var _layer = new this.$.oLayer(this, i); - } - _layers.push(_layer); - } - } else { - var _tl = this; - var _layers = this.nodes.map(function(x, index){ - if (x.type == "READ") return new _tl.$.oDrawingLayer(_tl, index); - return new _tl.$.oNodeLayer(_tl, index) - }) - } - - this._layers = _layers; - } - return this._layers; - } -}); - - -/** - * Gets the list of selected layers as oTimelineLayer objects. - * @name $.oTimeline#selectedLayers - * @type {oTimelineLayer[]} - */ -Object.defineProperty($.oTimeline.prototype, 'selectedLayers', { - get : function(){ - return this.allLayers.filter(function(x){return x.selected}); - } -}); - - - - -/** - * The node layers in the scene, based on the timeline's order given a specific display. - * @name $.oTimeline#compositionLayers - * @type {oNode[]} - * @deprecated use oTimeline.nodes instead if you want the nodes - */ -Object.defineProperty($.oTimeline.prototype, 'compositionLayers', { - get : function(){ - return this.nodes; - } -}); - - -/** - * The nodes present in the timeline. - * @name $.oTimeline#nodes - * @type {oNode[]} - */ -Object.defineProperty($.oTimeline.prototype, 'nodes', { - get : function(){ - var _timeline = this.compositionLayersList; - var _scene = this.$.scene; - - _timeline = _timeline.map( function(x){return _scene.getNodeByPath(x)} ); - - return _timeline; - } -}); - - -/** - * Gets the paths of the nodes displayed in the timeline. - * @name $.oTimeline#nodesList - * @type {string[]} - * @deprecated only returns node path strings, use oTimeline.layers insteads - */ -Object.defineProperty($.oTimeline.prototype, 'nodesList', { - get : function(){ - return this.compositionLayersList; - } -}); - - -/** - * Gets the paths of the layers in order, given the specific display's timeline. - * @name $.oTimeline#compositionLayersList - * @type {string[]} - * @deprecated only returns node path strings - */ -Object.defineProperty($.oTimeline.prototype, 'compositionLayersList', { - get : function(){ - var _composition = this.composition; - var _timeline = _composition.map(function(x){return x.node}) - - return _timeline; - } -}); - - -/** - * gets the composition for this timeline (array of native toonboom api 'compositionItems' objects) - * @deprecated exposes native harmony api objects - */ -Object.defineProperty($.oTimeline.prototype, "composition", { - get: function(){ - return compositionOrder.buildCompositionOrderForDisplay(this.display); - } -}) - - - -/** - * Refreshes the oTimeline's cached listing- in the event it changes in the runtime of the script. - * @deprecated oTimeline.composition is now always refreshed when accessed. - */ -$.oTimeline.prototype.refresh = function( ){ - if (!node.type(this.display)) { - this.composition = compositionOrder.buildDefaultCompositionOrder(); - }else{ - this.composition = compositionOrder.buildCompositionOrderForDisplay(this.display); - } -} - - -/** - * Build column to oNode/Attribute lookup cache. Makes the layer generation faster if using oTimeline.layers, oTimeline.selectedLayers - * @deprecated - */ -$.oTimeline.prototype.buildLayerCache = function( forced ){ - if (typeof forced === 'undefined') forced = false; - - var cdate = (new Date).getTime(); - var rebuild = forced; - if( !this.$.cache_columnToNodeAttribute_date ){ - rebuild = true; - }else if( !rebuild ){ - if( ( cdate - this.$.cache_columnToNodeAttribute_date ) > 1000*10 ){ - rebuild = true; - } - } - - if(rebuild){ - var nodeLayers = this.compositionLayers; - - if( this.$.cache_nodeAttribute ){ - this.$.cache_columnToNodeAttribute = {}; - } - - for( var n=0;n - - OpenHarmonyToolInstaller - - - - 0 - 0 - 547 - 642 - - - - OpenHarmony Tool Installer - - - - - - - 3 - 0 - - - - Available Tools - - - - - - - - - - - - - - - - 4 - 0 - - - - Details - - - - - - - 0 - 0 - - - - - - - - - - - - - - - INSTALL/REMOVE - - - - - - - - - - - diff --git a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony_install.js b/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony_install.js deleted file mode 100644 index 6282bc4947..0000000000 --- a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/openHarmony_install.js +++ /dev/null @@ -1,282 +0,0 @@ -function openHarmony_install_main(){ - try{ - var d = new Dialog(); - d.title = "Install/Update OpenHarmony"; - d.cancelButtonText = "Cancel"; - - //Standard install paths. - var install_base = specialFolders.userScripts; - var library_base = install_base; - - var libdir = new Dir(library_base); - var label = new Label; - label.text = "Install openHarmony libraries?\n"; - - d.add( label ); - - if ( !d.exec() ){ - return; - } - - if( !libdir.exists ){ - MessageBox.information( "Failed to create folders for openHarmony - please check permissions." ); - } - - var apic = api_call( "https://api.github.com/repos/cfourney/OpenHarmony/branches" ); - if( !apic ){ - MessageBox.information( "API Error - Failed to get available branches." ); - return; - } - - var branch_names = apic.map(function(x, index){return index+": "+x.name.toUpperCase()}) - - var res = Input.getItem( "Which Branch", branch_names ); - if( !res ){ return; } - - var branch_data = false; - var fnd = false; - for( var x=0;x= m.availableItems.length ){ - return false; - } - var item = m.availableItems[ indx ]; - return item; - }catch(err){ - $.debug( err + " ("+err.fileName+" "+err.lineNumber+")", $.DEBUG_LEVEL["ERROR"] ); - } - } - } - - - //---------------------------------------------- - //-- GET THE FILE CONTENTS IN A DIRECTORY ON GIT - this.recurse_files = function( contents, arr_files ){ - with( context.$.global ){ - try{ - var $ = context.$; - var m = context; - for( var n=0;n 0 && local_path.toUpperCase().indexOf(".JS")>0 ){ - script_files.push( local_path ); - } - - var lpth = install_base + "/" + local_path; - install_files.push( lpth ); - - var lfl = new $.oFile( lpth ); - if( lfl.exists && !overwrite ){ - //Confirm deletion? - if( !confirmDialog( "Overwrite File", "Overwrite " + lpth, "Overwrite", "Cancel" ) ){ continue; } - } - - install_instructions.push( { "url": url, "path": lpth } ); - }catch(err){ - continue; - } - } - - var downloaded = $.network.downloadMulti( install_instructions, true ); - - var all_success = true; - for( var x=0;x0 ){ - var str_limited = []; - for( var t=0;t<( Math.min(script_files.length,4) );t++ ){ - str_limited.push( " " + script_files[t] ); - } - if( script_files.length>4 ){ - str_limited.push( " " + "And More!" ); - } - str = str_limited.join( "\n" ); - } - - m.installButton.text = "INSTALLED!"; - m.installButton.setEnabled( false ); - MessageBox.information( "Installed " + item["name"] + "!\n\nThe installed scripts include:\n" + str ); - - //TODO: Create the install script with details. - var install_detail_script = oh_install + "/" + item["name"]; - var install_details_text = []; - - var install_fl = new $.oFile( install_detail_script ); - install_fl.write( item["sha"] + "\n" + install_files.join( "\n" ) ); - - m.get_tools(); - }catch(err){ - $.debug( err + " ("+err.fileName+" "+err.lineNumber+")", $.DEBUG_LEVEL["ERROR"] ); - } - } - } - - this.basePath = ''; - - this.removeAction = function( ev ){ - with( context.$.global ){ - try{ - var $ = context.$; - var m = context; - - var item = m.getItem(); - if( !item ){ - $.debug( "Failed to install - no item seems to be selected.", $.DEBUG_LEVEL["ERROR"] ); - return; - } - - var install_detail_script = oh_install + "/" + item["name"]; - var install_file = new $.oFile( install_detail_script ); - - if( install_file.exists ){ - //--The file exists. It might be an remove if same version, or an upgrade. - var read_file = install_file.read().split("\n"); - - for( var n=1;nThe openHarmony library enables people to create scripts for Harmony using less code and a simpler synthax.

The complete documentation is available at this address:https://cfourney.github.io/OpenHarmony/

Install this library to be able to use the scripts that require it.

", - "repository": "https://github.com/cfourney/OpenHarmony/", - "isPackage": false, - "files": [ - "openHarmony.js", - "openHarmony/" - ], - "keywords": [ - "openHarmony", - "library" - ], - "author": "OpenHarmony", - "license": "MPL-2.0", - "website": "https://github.com/cfourney/OpenHarmony/", - "localFiles": "" - }, - { - "name": "oH Anim tools - Smartkey", - "version": "1.0.0", - "compatibility": "Harmony Premium 15", - "description": "This script creates a key frame on the current timeline layer, and set the stop motion or interpolated mode of the key according to the surrounding keyframes. A Keyframe placed on an interpolation will remain interpolated, and a key placed between stop motion keyframes will also be set to stop motion.\n

This script uses the OpenHarmony library. Install it first to be able to use it.

\n\n

Assign this script to a shortcut with the script ScriptShortcuts.

", - "repository": "https://github.com/cfourney/OpenHarmony/", - "isPackage": false, - "files": [ - "tools/OpenHarmony_basic/openHarmony_anim_tools.js" - ], - "keywords": [ - "openHarmony", - "animation" - ], - "author": "Chris F", - "license": "MPL-v2.0", - "website": "https://github.com/cfourney/OpenHarmony/", - "localFiles": "" - }, - { - "name": "oH Rigging tools", - "version": "1.0.0", - "compatibility": "Harmony Premium 15", - "description": "OpenHarmony Rigging Tools\n

Those scripts require the openHarmony lib to work. Install it first for the scripts to work.

\n

Add Centered Weighted Peg
Adds a peg with a pivot at the center of the selected drawing.

\n\n

Place Pivot with Click
Place the pivot with a simple click.

\n\n

Clean Unused Palettes
\nFinds and removes all unnecessary palettes files from the filesystem. Doesn't support Element Palettes yet!

\n\n

Create Backdrop on Selection
Set up backdrops easily on the selection with this script.

\n", - "repository": "https://github.com/cfourney/OpenHarmony/", - "isPackage": false, - "files": [ - "tools/OpenHarmony_basic/openHarmony_rigging_tools.js", - "tools/OpenHarmony_basic/openHarmony_basic_backdropPicker.ui" - ], - "keywords": [ - "openHarmony", - "palettes" - ], - "author": "Chris F", - "license": "MPL-v2.0", - "website": "https://github.com/cfourney/OpenHarmony/", - "localFiles": "" - } - ] -} \ No newline at end of file diff --git a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/tools/OpenHarmony_basic/INSTALL b/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/tools/OpenHarmony_basic/INSTALL deleted file mode 100644 index 528dc4eeda..0000000000 --- a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/tools/OpenHarmony_basic/INSTALL +++ /dev/null @@ -1 +0,0 @@ -scripts \ No newline at end of file diff --git a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/tools/OpenHarmony_basic/README b/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/tools/OpenHarmony_basic/README deleted file mode 100644 index 4ba312ab4c..0000000000 --- a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/tools/OpenHarmony_basic/README +++ /dev/null @@ -1 +0,0 @@ -Basic Helper Scripts, used for rigging, animation and compositing. \ No newline at end of file diff --git a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/tools/OpenHarmony_basic/openHarmony_anim_tools.js b/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/tools/OpenHarmony_basic/openHarmony_anim_tools.js deleted file mode 100644 index 222169080b..0000000000 --- a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/tools/OpenHarmony_basic/openHarmony_anim_tools.js +++ /dev/null @@ -1,119 +0,0 @@ -/** - * Load the Open Harmony Library as needed. - */ -try{ - var oh_incl = preferences.getString( 'openHarmonyIncludeDebug', false ); - if( oh_incl=="false" ) oh_incl = preferences.getString( 'openHarmonyInclude', false ); - if( oh_incl=="false" ) oh_incl = "openHarmony.js"; - include(oh_incl); -}catch(err){ - MessageBox.information ("OpenHarmony is not installed. Get it here: \nhttps://github.com/cfourney/OpenHarmony") -} - - -/** - * Smart key button. Only adds a key if a column already exists. Maintains sections that are tweens and other sections that are stop-motion/holds. - */ -function oh_anim_smartKey(){ - System.println(""); - - scene.beginUndoRedoAccum( "oh_anim_smartKey" ); - - var timeline = $.scene.getTimeline(); - var layers = timeline.selectedLayers; - - //-------------------------------------------------- - //--- The key function, used - - var smart_key_item = function( attr ){ - var cfrm = $.scene.currentFrame; - - var frame = attr.frames[ cfrm ]; - - - if( attr.node.type == "READ" ){ - - if( attr.column.type == "DRAWING" ){ - frame.isKeyFrame = true; - return; - } - - //DONT KEY THE OFFSETS IF ITS NOT ANIMATEABLE. - var check_pos = { - "offset.x" : true, - "offset.y" : true, - "offset.z" : true, - "skew" : true, - "scale.x" : true, - "scale.y" : true, - "scale.z" : true, - "rotation.anglez" : true - } - if( !attr.node["can_animate"] ){ - return; - } - } - - if( !frame.isKeyFrame ){ - var lk = frame.keyframeLeft; - frame.isKeyFrame = true; - - if(!lk){ - //Consider this as static. - frame.constant = true; - }else{ - if( lk.constant ){ - frame.constant = true; - // lk.constant = true; //UNNECESSARY, DEFAULT APPRAOCH TO isKeyFrame = true; - }else{ - var rk = frame.keyframeRight; - - if( rk ){ - //Something is to the right, keep the tween. - frame.constant = false; - // lk.constant = false; //UNNECESSARY, DEFAULT APPRAOCH TO isKeyFrame = true; - }else{ - frame.constant = true; - lk.constant = true; - } - } - } - } - } - - - if( layers.length == 0 ){ - var layers = timeline.compositionLayers; - - var items = []; - for( var n=0;n - - Dialog - - - - 0 - 0 - 471 - 223 - - - - Backdrop Details - - - true - - - - - - - - - 75 - 0 - - - - Name - - - - - - - - - - - - - - - 75 - 0 - - - - Text - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - - - - - - - - - - - - 74 - 0 - - - - Color - - - - - - - - 1 - 0 - - - - - - - - - - - Change Color - - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - buttonBox - accepted() - Dialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - Dialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff --git a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/tools/OpenHarmony_basic/openHarmony_rigging_tools.js b/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/tools/OpenHarmony_basic/openHarmony_rigging_tools.js deleted file mode 100644 index 7eba5617d0..0000000000 --- a/server_addon/harmony/client/ayon_harmony/vendor/OpenHarmony/tools/OpenHarmony_basic/openHarmony_rigging_tools.js +++ /dev/null @@ -1,411 +0,0 @@ -/** - * Load the Open Harmony Library as needed. - */ - -try{ - var oh_incl = preferences.getString( 'openHarmonyIncludeDebug', false ); - if( oh_incl=="false" ) oh_incl = preferences.getString( 'openHarmonyInclude', false ); - if( oh_incl=="false" ) oh_incl = "openHarmony.js"; - include(oh_incl); -}catch(err){ - MessageBox.information ("OpenHarmony is not installed. Get it here: \nhttps://github.com/cfourney/OpenHarmony") -} - -/** - * Finds and removes all unnecessary asset files from the filesystem. - */ -function oh_rigging_removeUnnecesaryPaletteFiles(){ - var palette_list = $.scene.palettes; - var registered_palette_files = {}; - - //Find the path of all registered palettes. Add it to a group for easy lookup. - for( var n=0;n3 ){ - labelText += '\n and '+(unreferenced_palettes.length-3)+' more . . .'; - } - - var confirmation = $.dialog.confirm( "Remove Palettes", labelText ); - - if( confirmation ){ - //Delete all palettes from disk. - var prog = new $.dialog.Progress( "Removing Palettes", unreferenced_palettes.length, true ); - - for( var n=0;n2 ){ - var clean_lcs = lcs.sequence; - - if( clean_lcs.slice( clean_lcs.length-1 ) == ("_") ){ - clean_lcs = clean_lcs.slice( 0, clean_lcs.length-1 ); - } - - if( clean_lcs.slice( 0,1 ) == ("_") ){ - clean_lcs = clean_lcs.slice( 1 ); - } - - if(!common_substrings[clean_lcs]){ - common_substrings[clean_lcs] = 0; - } - - common_substrings[clean_lcs]++; - } - } - - laststring = bnm; - } - - var names = []; - for( var n in common_substrings ){ - names.push( n ); - } - - //Now compare cleaned LCS and accumulate them as votes as well. - for( var n=0;n2 ){ - var clean_lcs = lcs.sequence; - - if( clean_lcs.slice( clean_lcs.length-1 ) == ("_") ){ - clean_lcs = clean_lcs.slice( 0, clean_lcs.length-1 ); - } - if( clean_lcs.slice( 0,1 ) == ("_") ){ - clean_lcs = clean_lcs.slice( 1 ); - } - - if(!common_substrings[clean_lcs]){ - common_substrings[clean_lcs] = 0; - } - common_substrings[clean_lcs]++; - - if( equivalent[clean_lcs] ){ - var clean_lcs2 = equivalent[clean_lcs]; - if(!common_substrings[clean_lcs2]){ - common_substrings[clean_lcs2] = 0; - } - common_substrings[clean_lcs2]++; - } - } - } - } - - //Find the highest voted LCS. - var highest = 0; - var common_name = 'Backdrop'; - for( var n in common_substrings ){ - if( common_substrings[n] > highest ){ - if( n.toUpperCase()=="DRAWING" ){ - continue; - } - - highest = common_substrings[n]; - common_name = n; - } - } - - var res = color_selector.exec( common_name, "", "" ); - if( !res ){ //A cancel option was selected. - continue; - } - - //Add that beautiful backdrop. - $.scene.addBackdropToNodes( grp, grp_items, res.name, res.text, res.color, 0, 0, 35, 35 ); - } - - scene.endUndoRedoAccum( ); -} - - -/** - * Sets the peg's pivot based on a clicked position in the interface. - */ -function oh_rigging_setSelectedPegPivotWithClick(){ - var nodes = $.scene.nodeSearch( "#PEG(SELECTED)" ); - - if( nodes.length == 0 ){ - $.dialog.alert( "No peg selected." ); - return; - } - - Action.perform( "onActionChoosePencilTool()" ); - var context = this; - - var setPiv = function( res ){ - var $ = context.$; - var m = context; - - $.beginUndo(); - try{ - for( var n=0;n0.3.2", -} -ayon_compatible_addons = {} diff --git a/server_addon/harmony/server/__init__.py b/server_addon/harmony/server/__init__.py deleted file mode 100644 index 154618241e..0000000000 --- a/server_addon/harmony/server/__init__.py +++ /dev/null @@ -1,11 +0,0 @@ -from ayon_server.addons import BaseServerAddon - -from .settings import HarmonySettings, DEFAULT_HARMONY_SETTING - - -class Harmony(BaseServerAddon): - settings_model = HarmonySettings - - async def get_default_settings(self): - settings_model_cls = self.get_settings_model() - return settings_model_cls(**DEFAULT_HARMONY_SETTING) diff --git a/server_addon/harmony/server/settings/__init__.py b/server_addon/harmony/server/settings/__init__.py deleted file mode 100644 index 4a8118d4da..0000000000 --- a/server_addon/harmony/server/settings/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -from .main import ( - HarmonySettings, - DEFAULT_HARMONY_SETTING, -) - - -__all__ = ( - "HarmonySettings", - "DEFAULT_HARMONY_SETTING", -) diff --git a/server_addon/harmony/server/settings/imageio.py b/server_addon/harmony/server/settings/imageio.py deleted file mode 100644 index 02f39a9d1b..0000000000 --- a/server_addon/harmony/server/settings/imageio.py +++ /dev/null @@ -1,70 +0,0 @@ -from pydantic import validator -from ayon_server.settings import BaseSettingsModel, SettingsField -from ayon_server.settings.validators import ensure_unique_names - - -class ImageIOConfigModel(BaseSettingsModel): - """[DEPRECATED] Addon OCIO config settings. Please set the OCIO config - path in the Core addon profiles here - (ayon+settings://core/imageio/ocio_config_profiles). - """ - - override_global_config: bool = SettingsField( - False, - title="Override global OCIO config", - description=( - "DEPRECATED functionality. Please set the OCIO config path in the " - "Core addon profiles here (ayon+settings://core/imageio/" - "ocio_config_profiles)." - ), - ) - filepath: list[str] = SettingsField( - default_factory=list, - title="Config path", - description=( - "DEPRECATED functionality. Please set the OCIO config path in the " - "Core addon profiles here (ayon+settings://core/imageio/" - "ocio_config_profiles)." - ), - ) - - -class ImageIOFileRuleModel(BaseSettingsModel): - name: str = SettingsField("", title="Rule name") - pattern: str = SettingsField("", title="Regex pattern") - colorspace: str = SettingsField("", title="Colorspace name") - ext: str = SettingsField("", title="File extension") - - -class ImageIOFileRulesModel(BaseSettingsModel): - activate_host_rules: bool = SettingsField(False) - rules: list[ImageIOFileRuleModel] = SettingsField( - default_factory=list, - title="Rules" - ) - - @validator("rules") - def validate_unique_outputs(cls, value): - ensure_unique_names(value) - return value - - -class ImageIORemappingRulesModel(BaseSettingsModel): - host_native_name: str = SettingsField( - title="Application native colorspace name" - ) - ocio_name: str = SettingsField(title="OCIO colorspace name") - - -class HarmonyImageIOModel(BaseSettingsModel): - activate_host_color_management: bool = SettingsField( - True, title="Enable Color Management" - ) - ocio_config: ImageIOConfigModel = SettingsField( - default_factory=ImageIOConfigModel, - title="OCIO config" - ) - file_rules: ImageIOFileRulesModel = SettingsField( - default_factory=ImageIOFileRulesModel, - title="File Rules" - ) diff --git a/server_addon/harmony/server/settings/main.py b/server_addon/harmony/server/settings/main.py deleted file mode 100644 index 8a72c966d8..0000000000 --- a/server_addon/harmony/server/settings/main.py +++ /dev/null @@ -1,57 +0,0 @@ -from ayon_server.settings import BaseSettingsModel, SettingsField - -from .imageio import HarmonyImageIOModel -from .publish_plugins import HarmonyPublishPlugins - - -class HarmonySettings(BaseSettingsModel): - """Harmony Project Settings.""" - - imageio: HarmonyImageIOModel = SettingsField( - default_factory=HarmonyImageIOModel, - title="OCIO config" - ) - publish: HarmonyPublishPlugins = SettingsField( - default_factory=HarmonyPublishPlugins, - title="Publish plugins" - ) - - -DEFAULT_HARMONY_SETTING = { - "load": { - "ImageSequenceLoader": { - "family": [ - "shot", - "render", - "image", - "plate", - "reference" - ], - "representations": [ - "jpeg", - "png", - "jpg" - ] - } - }, - "publish": { - "CollectPalettes": { - "allowed_tasks": [ - ".*" - ] - }, - "ValidateAudio": { - "enabled": True, - "optional": True, - "active": True - }, - "ValidateSceneSettings": { - "enabled": True, - "optional": True, - "active": True, - "frame_check_filter": [], - "skip_resolution_check": [], - "skip_timelines_check": [] - } - } -} diff --git a/server_addon/harmony/server/settings/publish_plugins.py b/server_addon/harmony/server/settings/publish_plugins.py deleted file mode 100644 index 2d976389f6..0000000000 --- a/server_addon/harmony/server/settings/publish_plugins.py +++ /dev/null @@ -1,61 +0,0 @@ -from ayon_server.settings import BaseSettingsModel, SettingsField - - -class CollectPalettesPlugin(BaseSettingsModel): - """Set regular expressions to filter triggering on specific task names. '.*' means on all.""" # noqa - - allowed_tasks: list[str] = SettingsField( - default_factory=list, - title="Allowed tasks" - ) - - -class ValidateAudioPlugin(BaseSettingsModel): - """Check if scene contains audio track.""" # - _isGroup = True - enabled: bool = True - optional: bool = SettingsField(False, title="Optional") - active: bool = SettingsField(True, title="Active") - - -class ValidateSceneSettingsPlugin(BaseSettingsModel): - """Validate if FrameStart, FrameEnd and Resolution match shot data in DB. - Use regular expressions to limit validations only on particular asset - or task names.""" - _isGroup = True - enabled: bool = True - optional: bool = SettingsField(False, title="Optional") - active: bool = SettingsField(True, title="Active") - - frame_check_filter: list[str] = SettingsField( - default_factory=list, - title="Skip Frame check for Assets with name containing" - ) - - skip_resolution_check: list[str] = SettingsField( - default_factory=list, - title="Skip Resolution Check for Tasks" - ) - - skip_timelines_check: list[str] = SettingsField( - default_factory=list, - title="Skip Timeline Check for Tasks" - ) - - -class HarmonyPublishPlugins(BaseSettingsModel): - - CollectPalettes: CollectPalettesPlugin = SettingsField( - title="Collect Palettes", - default_factory=CollectPalettesPlugin, - ) - - ValidateAudio: ValidateAudioPlugin = SettingsField( - title="Validate Audio", - default_factory=ValidateAudioPlugin, - ) - - ValidateSceneSettings: ValidateSceneSettingsPlugin = SettingsField( - title="Validate Scene Settings", - default_factory=ValidateSceneSettingsPlugin, - ) diff --git a/server_addon/hiero/client/ayon_hiero/__init__.py b/server_addon/hiero/client/ayon_hiero/__init__.py deleted file mode 100644 index 2dc490c1e9..0000000000 --- a/server_addon/hiero/client/ayon_hiero/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -from .version import __version__ -from .addon import ( - HIERO_ADDON_ROOT, - HieroAddon, -) - - -__all__ = ( - "__version__", - - "HIERO_ADDON_ROOT", - "HieroAddon", -) diff --git a/server_addon/hiero/client/ayon_hiero/addon.py b/server_addon/hiero/client/ayon_hiero/addon.py deleted file mode 100644 index 671e29151b..0000000000 --- a/server_addon/hiero/client/ayon_hiero/addon.py +++ /dev/null @@ -1,67 +0,0 @@ -import os -import platform -from ayon_core.addon import AYONAddon, IHostAddon - -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_ADDON_ROOT, "api", "startup") - ] - old_hiero_path = env.get("HIERO_PLUGIN_PATH") or "" - for path in old_hiero_path.split(os.pathsep): - if not path: - continue - - norm_path = os.path.normpath(path) - if norm_path not in new_hiero_paths: - new_hiero_paths.append(norm_path) - - env["HIERO_PLUGIN_PATH"] = os.pathsep.join(new_hiero_paths) - # Remove auto screen scale factor for Qt - # - let Hiero decide it's value - env.pop("QT_AUTO_SCREEN_SCALE_FACTOR", None) - # Remove tkinter library paths if are set - env.pop("TK_LIBRARY", None) - env.pop("TCL_LIBRARY", None) - - # Add vendor to PYTHONPATH - python_path = env["PYTHONPATH"] - python_path_parts = [] - if python_path: - python_path_parts = python_path.split(os.pathsep) - vendor_path = os.path.join(HIERO_ADDON_ROOT, "vendor") - python_path_parts.insert(0, vendor_path) - env["PYTHONPATH"] = os.pathsep.join(python_path_parts) - - # Set default values if are not already set via settings - defaults = { - "LOGLEVEL": "DEBUG" - } - for key, value in defaults.items(): - if not env.get(key): - env[key] = value - - # Try to add QuickTime to PATH - quick_time_path = "C:/Program Files (x86)/QuickTime/QTSystem" - if platform.system() == "windows" and os.path.exists(quick_time_path): - path_value = env.get("PATH") or "" - path_paths = [ - path - for path in path_value.split(os.pathsep) - if path - ] - path_paths.append(quick_time_path) - env["PATH"] = os.pathsep.join(path_paths) - - def get_workfile_extensions(self): - return [".hrox"] diff --git a/server_addon/hiero/client/ayon_hiero/api/__init__.py b/server_addon/hiero/client/ayon_hiero/api/__init__.py deleted file mode 100644 index 099db14794..0000000000 --- a/server_addon/hiero/client/ayon_hiero/api/__init__.py +++ /dev/null @@ -1,131 +0,0 @@ -from .workio import ( - open_file, - save_file, - current_file, - has_unsaved_changes, - file_extensions, - work_root -) - -from .pipeline import ( - launch_workfiles_app, - ls, - install, - uninstall, - reload_config, - containerise, - publish, - maintained_selection, - parse_container, - update_container, - reset_selection -) - -from .constants import ( - OPENPYPE_TAG_NAME, - DEFAULT_SEQUENCE_NAME, - DEFAULT_BIN_NAME -) - -from .lib import ( - flatten, - get_track_items, - get_current_project, - get_current_sequence, - get_timeline_selection, - get_current_track, - get_track_item_tags, - get_track_openpype_tag, - set_track_openpype_tag, - get_track_openpype_data, - get_track_item_pype_tag, - set_track_item_pype_tag, - get_track_item_pype_data, - get_trackitem_openpype_tag, - set_trackitem_openpype_tag, - get_trackitem_openpype_data, - set_publish_attribute, - get_publish_attribute, - imprint, - get_selected_track_items, - set_selected_track_items, - create_nuke_workfile_clips, - create_bin, - apply_colorspace_project, - apply_colorspace_clips, - is_overlapping, - get_sequence_pattern_and_padding -) - -from .plugin import ( - CreatorWidget, - Creator, - PublishClip, - SequenceLoader, - ClipLoader -) - -__all__ = [ - # avalon pipeline module - "launch_workfiles_app", - "ls", - "install", - "uninstall", - "reload_config", - "containerise", - "publish", - "maintained_selection", - "parse_container", - "update_container", - "reset_selection", - - # Workfiles API - "open_file", - "save_file", - "current_file", - "has_unsaved_changes", - "file_extensions", - "work_root", - - # Constants - "OPENPYPE_TAG_NAME", - "DEFAULT_SEQUENCE_NAME", - "DEFAULT_BIN_NAME", - - # Lib functions - "flatten", - "get_track_items", - "get_current_project", - "get_current_sequence", - "get_timeline_selection", - "get_current_track", - "get_track_item_tags", - "get_track_openpype_tag", - "set_track_openpype_tag", - "get_track_openpype_data", - "get_trackitem_openpype_tag", - "set_trackitem_openpype_tag", - "get_trackitem_openpype_data", - "set_publish_attribute", - "get_publish_attribute", - "imprint", - "get_selected_track_items", - "set_selected_track_items", - "create_nuke_workfile_clips", - "create_bin", - "is_overlapping", - "apply_colorspace_project", - "apply_colorspace_clips", - "get_sequence_pattern_and_padding", - # deprecated - "get_track_item_pype_tag", - "set_track_item_pype_tag", - "get_track_item_pype_data", - - # plugins - "CreatorWidget", - "Creator", - "PublishClip", - "SequenceLoader", - "ClipLoader" -] diff --git a/server_addon/hiero/client/ayon_hiero/api/constants.py b/server_addon/hiero/client/ayon_hiero/api/constants.py deleted file mode 100644 index 61a780af33..0000000000 --- a/server_addon/hiero/client/ayon_hiero/api/constants.py +++ /dev/null @@ -1,3 +0,0 @@ -OPENPYPE_TAG_NAME = "openpypeData" -DEFAULT_SEQUENCE_NAME = "openpypeSequence" -DEFAULT_BIN_NAME = "openpypeBin" diff --git a/server_addon/hiero/client/ayon_hiero/api/events.py b/server_addon/hiero/client/ayon_hiero/api/events.py deleted file mode 100644 index 663004abd2..0000000000 --- a/server_addon/hiero/client/ayon_hiero/api/events.py +++ /dev/null @@ -1,136 +0,0 @@ -import os - -import hiero.core.events - -from ayon_core.lib import Logger, register_event_callback - -from .lib import ( - sync_avalon_data_to_workfile, - launch_workfiles_app, - before_project_save, - apply_colorspace_project -) -from .tags import add_tags_to_workfile -from .menu import update_menu_task_label - -log = Logger.get_logger(__name__) - - -def startupCompleted(event): - log.info("startup competed event...") - return - - -def shutDown(event): - log.info("shut down event...") - return - - -def beforeNewProjectCreated(event): - log.info("before new project created event...") - return - - -def afterNewProjectCreated(event): - log.info("after new project created event...") - # sync avalon data to project properties - sync_avalon_data_to_workfile() - - # add tags from preset - add_tags_to_workfile() - - # Workfiles. - if int(os.environ.get("WORKFILES_STARTUP", "0")): - hiero.core.events.sendEvent("kStartWorkfiles", None) - # reset workfiles startup not to open any more in session - os.environ["WORKFILES_STARTUP"] = "0" - - apply_colorspace_project() - - -def beforeProjectLoad(event): - log.info("before project load event...") - return - - -def afterProjectLoad(event): - log.info("after project load event...") - # sync avalon data to project properties - sync_avalon_data_to_workfile() - - # add tags from preset - add_tags_to_workfile() - - -def beforeProjectClosed(event): - log.info("before project closed event...") - return - - -def afterProjectClosed(event): - log.info("after project closed event...") - return - - -def beforeProjectSaved(event): - log.info("before project saved event...") - return - - -def afterProjectSaved(event): - log.info("after project saved event...") - return - - -def register_hiero_events(): - log.info( - "Registering events for: kBeforeNewProjectCreated, " - "kAfterNewProjectCreated, kBeforeProjectLoad, kAfterProjectLoad, " - "kBeforeProjectSave, kAfterProjectSave, kBeforeProjectClose, " - "kAfterProjectClose, kShutdown, kStartup, kSelectionChanged" - ) - - # hiero.core.events.registerInterest( - # "kBeforeNewProjectCreated", beforeNewProjectCreated) - hiero.core.events.registerInterest( - "kAfterNewProjectCreated", afterNewProjectCreated) - - # hiero.core.events.registerInterest( - # "kBeforeProjectLoad", beforeProjectLoad) - hiero.core.events.registerInterest( - "kAfterProjectLoad", afterProjectLoad) - - hiero.core.events.registerInterest( - "kBeforeProjectSave", before_project_save) - # hiero.core.events.registerInterest( - # "kAfterProjectSave", afterProjectSaved) - # - # hiero.core.events.registerInterest( - # "kBeforeProjectClose", beforeProjectClosed) - # hiero.core.events.registerInterest( - # "kAfterProjectClose", afterProjectClosed) - # - # hiero.core.events.registerInterest("kShutdown", shutDown) - # hiero.core.events.registerInterest("kStartup", startupCompleted) - - # INFO: was disabled because it was slowing down timeline operations - # hiero.core.events.registerInterest( - # ("kSelectionChanged", "kTimeline"), selection_changed_timeline) - - # workfiles - try: - hiero.core.events.registerEventType("kStartWorkfiles") - hiero.core.events.registerInterest( - "kStartWorkfiles", launch_workfiles_app) - except RuntimeError: - pass - - -def register_events(): - """ - Adding all callbacks. - """ - - # if task changed then change notext of hiero - register_event_callback("taskChanged", update_menu_task_label) - log.info("Installed event callback for 'taskChanged'..") diff --git a/server_addon/hiero/client/ayon_hiero/api/launchforhiero.py b/server_addon/hiero/client/ayon_hiero/api/launchforhiero.py deleted file mode 100644 index c2186e1d2a..0000000000 --- a/server_addon/hiero/client/ayon_hiero/api/launchforhiero.py +++ /dev/null @@ -1,85 +0,0 @@ -import logging - -from scriptsmenu import scriptsmenu -from qtpy import QtWidgets - - -log = logging.getLogger(__name__) - - -def _hiero_main_window(): - """Return Hiero's main window""" - for obj in QtWidgets.QApplication.topLevelWidgets(): - if (obj.inherits('QMainWindow') and - obj.metaObject().className() == 'Foundry::UI::DockMainWindow'): - return obj - raise RuntimeError('Could not find HieroWindow instance') - - -def _hiero_main_menubar(): - """Retrieve the main menubar of the Hiero window""" - hiero_window = _hiero_main_window() - menubar = [i for i in hiero_window.children() if isinstance( - i, - QtWidgets.QMenuBar - )] - - assert len(menubar) == 1, "Error, could not find menu bar!" - return menubar[0] - - -def find_scripts_menu(title, parent): - """ - Check if the menu exists with the given title in the parent - - Args: - title (str): the title name of the scripts menu - - parent (QtWidgets.QMenuBar): the menubar to check - - Returns: - QtWidgets.QMenu or None - - """ - - menu = None - search = [i for i in parent.children() if - isinstance(i, scriptsmenu.ScriptsMenu) - and i.title() == title] - if search: - assert len(search) < 2, ("Multiple instances of menu '{}' " - "in menu bar".format(title)) - menu = search[0] - - return menu - - -def main(title="Scripts", parent=None, objectName=None): - """Build the main scripts menu in Hiero - - Args: - title (str): name of the menu in the application - - parent (QtWidgets.QtMenuBar): the parent object for the menu - - objectName (str): custom objectName for scripts menu - - Returns: - scriptsmenu.ScriptsMenu instance - - """ - hieromainbar = parent or _hiero_main_menubar() - try: - # check menu already exists - menu = find_scripts_menu(title, hieromainbar) - if not menu: - log.info("Attempting to build menu ...") - object_name = objectName or title.lower() - menu = scriptsmenu.ScriptsMenu(title=title, - parent=hieromainbar, - objectName=object_name) - except Exception as e: - log.error(e) - return - - return menu diff --git a/server_addon/hiero/client/ayon_hiero/api/lib.py b/server_addon/hiero/client/ayon_hiero/api/lib.py deleted file mode 100644 index 2a6038fb98..0000000000 --- a/server_addon/hiero/client/ayon_hiero/api/lib.py +++ /dev/null @@ -1,1381 +0,0 @@ -""" -Host specific functions where host api is connected -""" - -from copy import deepcopy -import os -import re -import platform -import functools -import warnings -import json -import ast -import secrets -import hiero - -from qtpy import QtWidgets, QtCore -import ayon_api -try: - from PySide import QtXml -except ImportError: - from PySide2 import QtXml - -from ayon_core.settings import get_project_settings -from ayon_core.pipeline import ( - Anatomy, - get_current_project_name, - AYON_INSTANCE_ID, - AVALON_INSTANCE_ID, -) -from ayon_core.pipeline.load import filter_containers -from ayon_core.lib import Logger -from . import tags -from .constants import ( - OPENPYPE_TAG_NAME, - DEFAULT_SEQUENCE_NAME, - DEFAULT_BIN_NAME -) - - -class _CTX: - has_been_setup = False - has_menu = False - parent_gui = None - - -class DeprecatedWarning(DeprecationWarning): - pass - - -def deprecated(new_destination): - """Mark functions as deprecated. - - It will result in a warning being emitted when the function is used. - """ - - func = None - if callable(new_destination): - func = new_destination - new_destination = None - - def _decorator(decorated_func): - if new_destination is None: - warning_message = ( - " Please check content of deprecated function to figure out" - " possible replacement." - ) - else: - warning_message = " Please replace your usage with '{}'.".format( - new_destination - ) - - @functools.wraps(decorated_func) - def wrapper(*args, **kwargs): - warnings.simplefilter("always", DeprecatedWarning) - warnings.warn( - ( - "Call to deprecated function '{}'" - "\nFunction was moved or removed.{}" - ).format(decorated_func.__name__, warning_message), - category=DeprecatedWarning, - stacklevel=4 - ) - return decorated_func(*args, **kwargs) - return wrapper - - if func is None: - return _decorator - return _decorator(func) - - -log = Logger.get_logger(__name__) - - -def flatten(list_): - for item_ in list_: - if isinstance(item_, (list, tuple)): - for sub_item in flatten(item_): - yield sub_item - else: - yield item_ - - -def get_current_project(remove_untitled=False): - projects = hiero.core.projects() - if not remove_untitled: - return projects[0] - - # if remove_untitled - for proj in projects: - if "Untitled" in proj.name(): - proj.close() - else: - return proj - - -def get_current_sequence(name=None, new=False): - """ - Get current sequence in context of active project. - - Args: - name (str)[optional]: name of sequence we want to return - new (bool)[optional]: if we want to create new one - - Returns: - hiero.core.Sequence: the sequence object - """ - sequence = None - project = get_current_project() - root_bin = project.clipsBin() - - if new: - # create new - name = name or DEFAULT_SEQUENCE_NAME - sequence = hiero.core.Sequence(name) - root_bin.addItem(hiero.core.BinItem(sequence)) - elif name: - # look for sequence by name - sequences = project.sequences() - for _sequence in sequences: - if _sequence.name() == name: - sequence = _sequence - if not sequence: - # if nothing found create new with input name - sequence = get_current_sequence(name, True) - else: - # if name is none and new is False then return current open sequence - sequence = hiero.ui.activeSequence() - - return sequence - - -def get_timeline_selection(): - active_sequence = hiero.ui.activeSequence() - timeline_editor = hiero.ui.getTimelineEditor(active_sequence) - return list(timeline_editor.selection()) - - -def get_current_track(sequence, name, audio=False): - """ - Get current track in context of active project. - - Creates new if none is found. - - Args: - sequence (hiero.core.Sequence): hiero sequence object - name (str): name of track we want to return - audio (bool)[optional]: switch to AudioTrack - - Returns: - hiero.core.Track: the track object - """ - tracks = sequence.videoTracks() - - if audio: - tracks = sequence.audioTracks() - - # get track by name - track = None - for _track in tracks: - if _track.name() == name: - track = _track - - if not track: - if not audio: - track = hiero.core.VideoTrack(name) - else: - track = hiero.core.AudioTrack(name) - - sequence.addTrack(track) - - return track - - -def get_track_items( - selection=False, - sequence_name=None, - track_item_name=None, - track_name=None, - track_type=None, - check_enabled=True, - check_locked=True, - check_tagged=False): - """Get all available current timeline track items. - - Attribute: - selection (list)[optional]: list of selected track items - sequence_name (str)[optional]: return only clips from input sequence - track_item_name (str)[optional]: return only item with input name - track_name (str)[optional]: return only items from track name - track_type (str)[optional]: return only items of given type - (`audio` or `video`) default is `video` - check_enabled (bool)[optional]: ignore disabled if True - check_locked (bool)[optional]: ignore locked if True - - Return: - list or hiero.core.TrackItem: list of track items or single track item - """ - track_type = track_type or "video" - selection = selection or [] - return_list = [] - - # get selected track items or all in active sequence - if selection: - try: - for track_item in selection: - log.info("___ track_item: {}".format(track_item)) - # make sure only trackitems are selected - if not isinstance(track_item, hiero.core.TrackItem): - continue - - if _validate_all_atrributes( - track_item, - track_item_name, - track_name, - track_type, - check_enabled, - check_tagged - ): - log.info("___ valid trackitem: {}".format(track_item)) - return_list.append(track_item) - except AttributeError: - pass - - # collect all available active sequence track items - if not return_list: - sequence = get_current_sequence(name=sequence_name) - tracks = [] - if sequence is not None: - # get all available tracks from sequence - tracks.extend(sequence.audioTracks()) - tracks.extend(sequence.videoTracks()) - - # loop all tracks - for track in tracks: - if check_locked and track.isLocked(): - continue - if check_enabled and not track.isEnabled(): - continue - # and all items in track - for track_item in track.items(): - # make sure no subtrackitem is also track items - if not isinstance(track_item, hiero.core.TrackItem): - continue - - if _validate_all_atrributes( - track_item, - track_item_name, - track_name, - track_type, - check_enabled, - check_tagged - ): - return_list.append(track_item) - - return return_list - - -def _validate_all_atrributes( - track_item, - track_item_name, - track_name, - track_type, - check_enabled, - check_tagged -): - def _validate_correct_name_track_item(): - if track_item_name and track_item_name in track_item.name(): - return True - elif not track_item_name: - return True - - def _validate_tagged_track_item(): - if check_tagged and track_item.tags(): - return True - elif not check_tagged: - return True - - def _validate_enabled_track_item(): - if check_enabled and track_item.isEnabled(): - return True - elif not check_enabled: - return True - - def _validate_parent_track_item(): - if track_name and track_name in track_item.parent().name(): - # filter only items fitting input track name - return True - elif not track_name: - # or add all if no track_name was defined - return True - - def _validate_type_track_item(): - if track_type == "video" and isinstance( - track_item.parent(), hiero.core.VideoTrack): - # only video track items are allowed - return True - elif track_type == "audio" and isinstance( - track_item.parent(), hiero.core.AudioTrack): - # only audio track items are allowed - return True - - # check if track item is enabled - return all([ - _validate_enabled_track_item(), - _validate_type_track_item(), - _validate_tagged_track_item(), - _validate_parent_track_item(), - _validate_correct_name_track_item() - ]) - - -def get_track_item_tags(track_item): - """ - Get track item tags excluded openpype tag - - Attributes: - trackItem (hiero.core.TrackItem): hiero object - - Returns: - hiero.core.Tag: hierarchy, orig clip attributes - """ - returning_tag_data = [] - # get all tags from track item - _tags = track_item.tags() - if not _tags: - return [] - - # collect all tags which are not openpype tag - returning_tag_data.extend( - tag for tag in _tags - if tag.name() != OPENPYPE_TAG_NAME - ) - - return returning_tag_data - - -def _get_tag_unique_hash(): - # sourcery skip: avoid-builtin-shadow - return secrets.token_hex(nbytes=4) - - -def set_track_openpype_tag(track, data=None): - """ - Set openpype track tag to input track object. - - Attributes: - track (hiero.core.VideoTrack): hiero object - - Returns: - hiero.core.Tag - """ - data = data or {} - - # basic Tag's attribute - tag_data = { - "editable": "0", - "note": "OpenPype data container", - "icon": "openpype_icon.png", - "metadata": dict(data.items()) - } - # get available pype tag if any - _tag = get_track_openpype_tag(track) - - if _tag: - # it not tag then create one - tag = tags.update_tag(_tag, tag_data) - else: - # if pype tag available then update with input data - tag = tags.create_tag( - "{}_{}".format( - OPENPYPE_TAG_NAME, - _get_tag_unique_hash() - ), - tag_data - ) - # add it to the input track item - track.addTag(tag) - - return tag - - -def get_track_openpype_tag(track): - """ - Get pype track item tag created by creator or loader plugin. - - Attributes: - trackItem (hiero.core.TrackItem): hiero object - - Returns: - hiero.core.Tag: hierarchy, orig clip attributes - """ - # get all tags from track item - _tags = track.tags() - if not _tags: - return None - for tag in _tags: - # return only correct tag defined by global name - if OPENPYPE_TAG_NAME in tag.name(): - return tag - - -def get_track_openpype_data(track, container_name=None): - """ - Get track's openpype tag data. - - Attributes: - trackItem (hiero.core.VideoTrack): hiero object - - Returns: - dict: data found on pype tag - """ - return_data = {} - # get pype data tag from track item - tag = get_track_openpype_tag(track) - - if not tag: - return None - - # get tag metadata attribute - tag_data = deepcopy(dict(tag.metadata())) - - for obj_name, obj_data in tag_data.items(): - obj_name = obj_name.replace("tag.", "") - - if obj_name in ["applieswhole", "note", "label"]: - continue - return_data[obj_name] = json.loads(obj_data) - - return ( - return_data[container_name] - if container_name - else return_data - ) - - -@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_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_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) - - -def get_trackitem_openpype_tag(track_item): - """ - Get pype track item tag created by creator or loader plugin. - - Attributes: - trackItem (hiero.core.TrackItem): hiero object - - Returns: - hiero.core.Tag: hierarchy, orig clip attributes - """ - # get all tags from track item - _tags = track_item.tags() - if not _tags: - return None - for tag in _tags: - # return only correct tag defined by global name - if OPENPYPE_TAG_NAME in tag.name(): - return tag - - -def set_trackitem_openpype_tag(track_item, data=None): - """ - Set openpype track tag to input track object. - - Attributes: - track (hiero.core.VideoTrack): hiero object - - Returns: - hiero.core.Tag - """ - data = data or {} - - # basic Tag's attribute - tag_data = { - "editable": "0", - "note": "OpenPype data container", - "icon": "openpype_icon.png", - "metadata": dict(data.items()) - } - # get available pype tag if any - _tag = get_trackitem_openpype_tag(track_item) - if _tag: - # it not tag then create one - tag = tags.update_tag(_tag, tag_data) - else: - # if pype tag available then update with input data - tag = tags.create_tag( - "{}_{}".format( - OPENPYPE_TAG_NAME, - _get_tag_unique_hash() - ), - tag_data - ) - # add it to the input track item - track_item.addTag(tag) - - return tag - - -def get_trackitem_openpype_data(track_item): - """ - Get track item's pype tag data. - - Attributes: - trackItem (hiero.core.TrackItem): hiero object - - Returns: - dict: data found on pype tag - """ - data = {} - # get pype data tag from track item - tag = get_trackitem_openpype_tag(track_item) - - if not tag: - return None - - # get tag metadata attribute - tag_data = deepcopy(dict(tag.metadata())) - # convert tag metadata to normal keys names and values to correct types - for k, v in tag_data.items(): - key = k.replace("tag.", "") - - try: - # capture exceptions which are related to strings only - if re.match(r"^[\d]+$", v): - value = int(v) - elif re.match(r"^True$", v): - value = True - elif re.match(r"^False$", v): - value = False - elif re.match(r"^None$", v): - value = None - elif re.match(r"^[\w\d_]+$", v): - value = v - else: - value = ast.literal_eval(v) - except (ValueError, SyntaxError) as msg: - log.warning(msg) - value = v - - data[key] = value - - return data - - -def imprint(track_item, data=None): - """ - Adding `Avalon data` into a hiero track item tag. - - Also including publish attribute into tag. - - Arguments: - track_item (hiero.core.TrackItem): hiero track item object - data (dict): Any data which needst to be imprinted - - Examples: - data = { - 'folderPath': '/shots/sq020sh0280', - 'productType': 'render', - 'productName': 'productMain' - } - """ - data = data or {} - - tag = set_trackitem_openpype_tag(track_item, data) - - # add publish attribute - set_publish_attribute(tag, True) - - -def set_publish_attribute(tag, value): - """ Set Publish attribute in input Tag object - - Attribute: - tag (hiero.core.Tag): a tag object - value (bool): True or False - """ - tag_data = tag.metadata() - # set data to the publish attribute - tag_data.setValue("tag.publish", str(value)) - - -def get_publish_attribute(tag): - """ Get Publish attribute from input Tag object - - Attribute: - tag (hiero.core.Tag): a tag object - value (bool): True or False - """ - tag_data = tag.metadata() - # get data to the publish attribute - value = tag_data.value("tag.publish") - # return value converted to bool value. Atring is stored in tag. - return ast.literal_eval(value) - - -def sync_avalon_data_to_workfile(): - # import session to get project dir - project_name = get_current_project_name() - - anatomy = Anatomy(project_name) - work_template = anatomy.get_template_item( - "work", "default", "path" - ) - work_root = anatomy.root_value_for_template(work_template) - active_project_root = ( - os.path.join(work_root, project_name) - ).replace("\\", "/") - # getting project - project = get_current_project() - - if "Tag Presets" in project.name(): - return - - log.debug("Synchronizing Pype metadata to project: {}".format( - project.name())) - - # set project root with backward compatibility - try: - project.setProjectDirectory(active_project_root) - except Exception: - # old way of setting it - project.setProjectRoot(active_project_root) - - # get project data from avalon db - project_entity = ayon_api.get_project(project_name) - project_attribs = project_entity["attrib"] - - log.debug("project attributes: {}".format(project_attribs)) - - # get format and fps property from avalon db on project - width = project_attribs["resolutionWidth"] - height = project_attribs["resolutionHeight"] - pixel_aspect = project_attribs["pixelAspect"] - fps = project_attribs["fps"] - format_name = project_entity["code"] - - # create new format in hiero project - format = hiero.core.Format(width, height, pixel_aspect, format_name) - project.setOutputFormat(format) - - # set fps to hiero project - project.setFramerate(fps) - - # TODO: add auto colorspace set from project drop - log.info("Project property has been synchronised with Avalon db") - - -def launch_workfiles_app(event): - """ - Event for launching workfiles after hiero start - - Args: - event (obj): required but unused - """ - from . import launch_workfiles_app - launch_workfiles_app() - - -def setup(console=False, port=None, menu=True): - """Setup integration - - Registers Pyblish for Hiero plug-ins and appends an item to the File-menu - - Arguments: - console (bool): Display console with GUI - port (int, optional): Port from which to start looking for an - available port to connect with Pyblish QML, default - provided by Pyblish Integration. - menu (bool, optional): Display file menu in Hiero. - """ - - if _CTX.has_been_setup: - teardown() - - add_submission() - - if menu: - add_to_filemenu() - _CTX.has_menu = True - - _CTX.has_been_setup = True - log.debug("pyblish: Loaded successfully.") - - -def teardown(): - """Remove integration""" - if not _CTX.has_been_setup: - return - - if _CTX.has_menu: - remove_from_filemenu() - _CTX.has_menu = False - - _CTX.has_been_setup = False - log.debug("pyblish: Integration torn down successfully") - - -def remove_from_filemenu(): - raise NotImplementedError("Implement me please.") - - -def add_to_filemenu(): - PublishAction() - - -class PyblishSubmission(hiero.exporters.FnSubmission.Submission): - - def __init__(self): - hiero.exporters.FnSubmission.Submission.__init__(self) - - def addToQueue(self): - from . import publish - # Add submission to Hiero module for retrieval in plugins. - hiero.submission = self - publish(hiero.ui.mainWindow()) - - -def add_submission(): - registry = hiero.core.taskRegistry - registry.addSubmission("Pyblish", PyblishSubmission) - - -class PublishAction(QtWidgets.QAction): - """ - Action with is showing as menu item - """ - - def __init__(self): - QtWidgets.QAction.__init__(self, "Publish", None) - self.triggered.connect(self.publish) - - for interest in ["kShowContextMenu/kTimeline", - "kShowContextMenukBin", - "kShowContextMenu/kSpreadsheet"]: - hiero.core.events.registerInterest(interest, self.eventHandler) - - self.setShortcut("Ctrl+Alt+P") - - def publish(self): - from . import publish - # Removing "submission" attribute from hiero module, to prevent tasks - # from getting picked up when not using the "Export" dialog. - if hasattr(hiero, "submission"): - del hiero.submission - publish(hiero.ui.mainWindow()) - - def eventHandler(self, event): - # Add the Menu to the right-click menu - event.menu.addAction(self) - - -# def CreateNukeWorkfile(nodes=None, -# nodes_effects=None, -# to_timeline=False, -# **kwargs): -# ''' Creating nuke workfile with particular version with given nodes -# Also it is creating timeline track items as precomps. -# -# Arguments: -# nodes(list of dict): each key in dict is knob order is important -# to_timeline(type): will build trackItem with metadata -# -# Returns: -# bool: True if done -# -# Raises: -# Exception: with traceback -# -# ''' -# import hiero.core -# from ayon_nuke.api.lib import ( -# BuildWorkfile, -# imprint -# ) -# -# # check if the file exists if does then Raise "File exists!" -# if os.path.exists(filepath): -# raise FileExistsError("File already exists: `{}`".format(filepath)) -# -# # if no representations matching then -# # Raise "no representations to be build" -# if len(representations) == 0: -# raise AttributeError("Missing list of `representations`") -# -# # check nodes input -# if len(nodes) == 0: -# log.warning("Missing list of `nodes`") -# -# # create temp nk file -# nuke_script = hiero.core.nuke.ScriptWriter() -# -# # create root node and save all metadata -# root_node = hiero.core.nuke.RootNode() -# -# anatomy = Anatomy(get_current_project_name()) -# work_template = anatomy.get_template_item("work", "default", "path") -# root_path = anatomy.root_value_for_template(work_template) -# -# nuke_script.addNode(root_node) -# -# script_builder = BuildWorkfile( -# root_node=root_node, -# root_path=root_path, -# nodes=nuke_script.getNodes(), -# **kwargs -# ) - - -def create_nuke_workfile_clips(nuke_workfiles, seq=None): - ''' - nuke_workfiles is list of dictionaries like: - [{ - 'path': 'P:/Jakub_testy_pipeline/test_v01.nk', - 'name': 'test', - 'handleStart': 15, # added asymmetrically to handles - 'handleEnd': 10, # added asymmetrically to handles - "clipIn": 16, - "frameStart": 991, - "frameEnd": 1023, - 'task': 'Comp-tracking', - 'work_dir': 'VFX_PR', - 'shot': '00010' - }] - ''' - - proj = hiero.core.projects()[-1] - root = proj.clipsBin() - - if not seq: - seq = hiero.core.Sequence('NewSequences') - root.addItem(hiero.core.BinItem(seq)) - # todo will need to define this better - # track = seq[1] # lazy example to get a destination# track - clips_lst = [] - for nk in nuke_workfiles: - task_path = '/'.join([nk['work_dir'], nk['shot'], nk['task']]) - bin = create_bin(task_path, proj) - - if nk['task'] not in seq.videoTracks(): - track = hiero.core.VideoTrack(nk['task']) - seq.addTrack(track) - else: - track = seq.tracks(nk['task']) - - # create clip media - media = hiero.core.MediaSource(nk['path']) - media_in = int(media.startTime() or 0) - media_duration = int(media.duration() or 0) - - handle_start = nk.get("handleStart") - handle_end = nk.get("handleEnd") - - if media_in: - source_in = media_in + handle_start - else: - source_in = nk["frameStart"] + handle_start - - if media_duration: - source_out = (media_in + media_duration - 1) - handle_end - else: - source_out = nk["frameEnd"] - handle_end - - source = hiero.core.Clip(media) - - name = os.path.basename(os.path.splitext(nk['path'])[0]) - split_name = split_by_client_version(name)[0] or name - - # add to bin as clip item - items_in_bin = [b.name() for b in bin.items()] - if split_name not in items_in_bin: - binItem = hiero.core.BinItem(source) - bin.addItem(binItem) - - new_source = [ - item for item in bin.items() if split_name in item.name() - ][0].items()[0].item() - - # add to track as clip item - trackItem = hiero.core.TrackItem( - split_name, hiero.core.TrackItem.kVideo) - trackItem.setSource(new_source) - trackItem.setSourceIn(source_in) - trackItem.setSourceOut(source_out) - trackItem.setTimelineIn(nk["clipIn"]) - trackItem.setTimelineOut(nk["clipIn"] + (source_out - source_in)) - track.addTrackItem(trackItem) - clips_lst.append(trackItem) - - return clips_lst - - -def create_bin(path=None, project=None): - ''' - Create bin in project. - If the path is "bin1/bin2/bin3" it will create whole depth - and return `bin3` - - ''' - # get the first loaded project - project = project or get_current_project() - - path = path or DEFAULT_BIN_NAME - - path = path.replace("\\", "/").split("/") - - root_bin = project.clipsBin() - - done_bin_lst = [] - for i, b in enumerate(path): - if i == 0 and len(path) > 1: - if b in [bin.name() for bin in root_bin.bins()]: - bin = [bin for bin in root_bin.bins() if b in bin.name()][0] - done_bin_lst.append(bin) - else: - create_bin = hiero.core.Bin(b) - root_bin.addItem(create_bin) - done_bin_lst.append(create_bin) - - elif i >= 1 and i < len(path) - 1: - if b in [bin.name() for bin in done_bin_lst[i - 1].bins()]: - bin = [ - bin for bin in done_bin_lst[i - 1].bins() - if b in bin.name() - ][0] - done_bin_lst.append(bin) - else: - create_bin = hiero.core.Bin(b) - done_bin_lst[i - 1].addItem(create_bin) - done_bin_lst.append(create_bin) - - elif i == len(path) - 1: - if b in [bin.name() for bin in done_bin_lst[i - 1].bins()]: - bin = [ - bin for bin in done_bin_lst[i - 1].bins() - if b in bin.name() - ][0] - done_bin_lst.append(bin) - else: - create_bin = hiero.core.Bin(b) - done_bin_lst[i - 1].addItem(create_bin) - done_bin_lst.append(create_bin) - - return done_bin_lst[-1] - - -def split_by_client_version(string): - regex = r"[/_.]v\d+" - try: - matches = re.findall(regex, string, re.IGNORECASE) - return string.split(matches[0]) - except Exception as error: - log.error(error) - return None - - -def get_selected_track_items(sequence=None): - _sequence = sequence or get_current_sequence() - - # Getting selection - timeline_editor = hiero.ui.getTimelineEditor(_sequence) - return timeline_editor.selection() - - -def set_selected_track_items(track_items_list, sequence=None): - _sequence = sequence or get_current_sequence() - - # make sure only trackItems are in list selection - only_track_items = [ - i for i in track_items_list - if isinstance(i, hiero.core.TrackItem)] - - # Getting selection - timeline_editor = hiero.ui.getTimelineEditor(_sequence) - return timeline_editor.setSelection(only_track_items) - - -def _read_doc_from_path(path): - # reading QtXml.QDomDocument from HROX path - hrox_file = QtCore.QFile(path) - if not hrox_file.open(QtCore.QFile.ReadOnly): - raise RuntimeError("Failed to open file for reading") - doc = QtXml.QDomDocument() - doc.setContent(hrox_file) - hrox_file.close() - return doc - - -def _write_doc_to_path(doc, path): - # write QtXml.QDomDocument to path as HROX - hrox_file = QtCore.QFile(path) - if not hrox_file.open(QtCore.QFile.WriteOnly): - raise RuntimeError("Failed to open file for writing") - stream = QtCore.QTextStream(hrox_file) - doc.save(stream, 1) - hrox_file.close() - - -def _set_hrox_project_knobs(doc, **knobs): - # set attributes to Project Tag - proj_elem = doc.documentElement().firstChildElement("Project") - for k, v in knobs.items(): - if "ocioconfigpath" in k: - paths_to_format = v[platform.system().lower()] - for _path in paths_to_format: - v = _path.format(**os.environ) - if not os.path.exists(v): - continue - log.debug("Project colorspace knob `{}` was set to `{}`".format(k, v)) - if isinstance(v, dict): - continue - proj_elem.setAttribute(str(k), v) - - -def apply_colorspace_project(): - """Apply colorspaces from settings. - - Due to not being able to set the project settings through the Python API, - we need to do use some dubious code to find the widgets and set them. It is - possible to set the project settings without traversing through the widgets - but it involves reading the hrox files from disk with XML, so no in-memory - support. See https://community.foundry.com/discuss/topic/137771/change-a-project-s-default-color-transform-with-python # noqa - for more details. - """ - # get presets for hiero - project_name = get_current_project_name() - imageio = get_project_settings(project_name)["hiero"]["imageio"] - presets = imageio.get("workfile") - - # Open Project Settings UI. - for act in hiero.ui.registeredActions(): - if act.objectName() == "foundry.project.settings": - act.trigger() - - # Find widgets from their sibling label. - labels = { - "Working Space:": "workingSpace", - "Viewer:": "viewerLut", - "Thumbnails:": "thumbnailLut", - "Monitor Out:": "monitorOutLut", - "8 Bit Files:": "eightBitLut", - "16 Bit Files:": "sixteenBitLut", - "Log Files:": "logLut", - "Floating Point Files:": "floatLut" - } - widgets = {x: None for x in labels.values()} - - def _recursive_children(widget, labels, widgets): - children = widget.children() - for count, child in enumerate(children): - if isinstance(child, QtWidgets.QLabel): - if child.text() in labels.keys(): - widgets[labels[child.text()]] = children[count + 1] - _recursive_children(child, labels, widgets) - - app = QtWidgets.QApplication.instance() - title = "Project Settings" - for widget in app.topLevelWidgets(): - if isinstance(widget, QtWidgets.QMainWindow): - if widget.windowTitle() != title: - continue - _recursive_children(widget, labels, widgets) - widget.close() - - msg = "Setting value \"{}\" is not a valid option for \"{}\"" - for key, widget in widgets.items(): - options = [widget.itemText(i) for i in range(widget.count())] - setting_value = presets[key] - assert setting_value in options, msg.format(setting_value, key) - widget.setCurrentText(presets[key]) - - # This code block is for setting up project colorspaces for files on disk. - # Due to not having Python API access to set the project settings, the - # Foundry recommended way is to modify the hrox files on disk with XML. See - # this forum thread for more details; - # https://community.foundry.com/discuss/topic/137771/change-a-project-s-default-color-transform-with-python # noqa - ''' - # backward compatibility layer - # TODO: remove this after some time - config_data = get_current_context_imageio_config_preset() - - if config_data: - presets.update({ - "ocioConfigName": "custom" - }) - - # get path the the active projects - project = get_current_project() - current_file = project.path() - - msg = "The project needs to be saved to disk to apply colorspace settings." - assert current_file, msg - - # save the workfile as subversion "comment:_colorspaceChange" - split_current_file = os.path.splitext(current_file) - copy_current_file = current_file - - if "_colorspaceChange" not in current_file: - copy_current_file = ( - split_current_file[0] - + "_colorspaceChange" - + split_current_file[1] - ) - - try: - # duplicate the file so the changes are applied only to the copy - shutil.copyfile(current_file, copy_current_file) - except shutil.Error: - # in case the file already exists and it want to copy to the - # same filewe need to do this trick - # TEMP file name change - copy_current_file_tmp = copy_current_file + "_tmp" - # create TEMP file - shutil.copyfile(current_file, copy_current_file_tmp) - # remove original file - os.remove(current_file) - # copy TEMP back to original name - shutil.copyfile(copy_current_file_tmp, copy_current_file) - # remove the TEMP file as we dont need it - os.remove(copy_current_file_tmp) - - # use the code from below for changing xml hrox Attributes - presets.update({"name": os.path.basename(copy_current_file)}) - - # read HROX in as QDomSocument - doc = _read_doc_from_path(copy_current_file) - - # apply project colorspace properties - _set_hrox_project_knobs(doc, **presets) - - # write QDomSocument back as HROX - _write_doc_to_path(doc, copy_current_file) - - # open the file as current project - hiero.core.openProject(copy_current_file) - ''' - - -def apply_colorspace_clips(): - project_name = get_current_project_name() - project = get_current_project(remove_untitled=True) - clips = project.clips() - - # get presets for hiero - imageio = get_project_settings(project_name)["hiero"]["imageio"] - - presets = imageio.get("regexInputs", {}).get("inputs", {}) - for clip in clips: - clip_media_source_path = clip.mediaSource().firstpath() - clip_name = clip.name() - clip_colorspace = clip.sourceMediaColourTransform() - - if "default" in clip_colorspace: - continue - - # check if any colorspace presets for read is matching - preset_clrsp = None - for k in presets: - if not bool(re.search(k["regex"], clip_media_source_path)): - continue - preset_clrsp = k["colorspace"] - - if preset_clrsp: - log.debug("Changing clip.path: {}".format(clip_media_source_path)) - log.info("Changing clip `{}` colorspace {} to {}".format( - clip_name, clip_colorspace, preset_clrsp)) - # set the found preset to the clip - clip.setSourceMediaColourTransform(preset_clrsp) - - # save project after all is changed - project.save() - - -def is_overlapping(ti_test, ti_original, strict=False): - covering_exp = ( - (ti_test.timelineIn() <= ti_original.timelineIn()) - and (ti_test.timelineOut() >= ti_original.timelineOut()) - ) - - if strict: - return covering_exp - - inside_exp = ( - (ti_test.timelineIn() >= ti_original.timelineIn()) - and (ti_test.timelineOut() <= ti_original.timelineOut()) - ) - overlaying_right_exp = ( - (ti_test.timelineIn() < ti_original.timelineOut()) - and (ti_test.timelineOut() >= ti_original.timelineOut()) - ) - overlaying_left_exp = ( - (ti_test.timelineOut() > ti_original.timelineIn()) - and (ti_test.timelineIn() <= ti_original.timelineIn()) - ) - - return any(( - covering_exp, - inside_exp, - overlaying_right_exp, - overlaying_left_exp - )) - - -def get_sequence_pattern_and_padding(file): - """ Return sequence pattern and padding from file - - Attributes: - file (string): basename form path - - Example: - Can find file.0001.ext, file.%02d.ext, file.####.ext - - Return: - string: any matching sequence pattern - int: padding of sequence numbering - """ - foundall = re.findall( - r"(#+)|(%\d+d)|(?<=[^a-zA-Z0-9])(\d+)(?=\.\w+$)", file) - if not foundall: - return None, None - found = sorted(list(set(foundall[0])))[-1] - - padding = int( - re.findall(r"\d+", found)[-1]) if "%" in found else len(found) - return found, padding - - -def sync_clip_name_to_data_asset(track_items_list): - # loop through all selected clips - for track_item in track_items_list: - # ignore if parent track is locked or disabled - if track_item.parent().isLocked(): - continue - if not track_item.parent().isEnabled(): - continue - # ignore if the track item is disabled - if not track_item.isEnabled(): - continue - - # get name and data - ti_name = track_item.name() - data = get_trackitem_openpype_data(track_item) - - # ignore if no data on the clip or not publish instance - if not data: - continue - if data.get("id") not in { - AYON_INSTANCE_ID, AVALON_INSTANCE_ID - }: - continue - - # fix data if wrong name - if data["asset"] != ti_name: - data["asset"] = ti_name - # remove the original tag - tag = get_trackitem_openpype_tag(track_item) - track_item.removeTag(tag) - # create new tag with updated data - set_trackitem_openpype_tag(track_item, data) - print("asset was changed in clip: {}".format(ti_name)) - - -def set_track_color(track_item, color): - track_item.source().binItem().setColor(color) - - -def check_inventory_versions(track_items=None): - """ - Actual version color identifier of Loaded containers - - Check all track items and filter only - Loader nodes for its version. It will get all versions from database - and check if the node is having actual version. If not then it will color - it to red. - """ - from . import parse_container - - track_items = track_items or get_track_items() - # presets - clip_color_last = "green" - clip_color = "red" - - containers = [] - # Find all containers and collect it's node and representation ids - for track_item in track_items: - container = parse_container(track_item) - if container: - containers.append(container) - - # Skip if nothing was found - if not containers: - return - - project_name = get_current_project_name() - filter_result = filter_containers(containers, project_name) - for container in filter_result.latest: - set_track_color(container["_item"], clip_color_last) - - for container in filter_result.outdated: - set_track_color(container["_item"], clip_color) - - -def selection_changed_timeline(event): - """Callback on timeline to check if asset in data is the same as clip name. - - Args: - event (hiero.core.Event): timeline event - """ - timeline_editor = event.sender - selection = timeline_editor.selection() - - track_items = get_track_items( - selection=selection, - track_type="video", - check_enabled=True, - check_locked=True, - check_tagged=True - ) - - # run checking function - sync_clip_name_to_data_asset(track_items) - - -def before_project_save(event): - track_items = get_track_items( - track_type="video", - check_enabled=True, - check_locked=True, - check_tagged=True - ) - - # run checking function - sync_clip_name_to_data_asset(track_items) - - # also mark old versions of loaded containers - check_inventory_versions(track_items) - - -def get_main_window(): - """Acquire Nuke's main window""" - if _CTX.parent_gui is None: - top_widgets = QtWidgets.QApplication.topLevelWidgets() - name = "Foundry::UI::DockMainWindow" - main_window = next(widget for widget in top_widgets if - widget.inherits("QMainWindow") and - widget.metaObject().className() == name) - _CTX.parent_gui = main_window - return _CTX.parent_gui diff --git a/server_addon/hiero/client/ayon_hiero/api/menu.py b/server_addon/hiero/client/ayon_hiero/api/menu.py deleted file mode 100644 index 632b11c7d3..0000000000 --- a/server_addon/hiero/client/ayon_hiero/api/menu.py +++ /dev/null @@ -1,175 +0,0 @@ -import os -import sys - -import hiero.core -from hiero.ui import findMenuAction - -from qtpy import QtGui - -from ayon_core.lib import Logger, is_dev_mode_enabled -from ayon_core.tools.utils import host_tools -from ayon_core.settings import get_project_settings -from ayon_core.pipeline import ( - get_current_project_name, - get_current_folder_path, - get_current_task_name -) - -from . import tags - -log = Logger.get_logger(__name__) - -self = sys.modules[__name__] -self._change_context_menu = None - - -def get_context_label(): - return "{}, {}".format( - get_current_folder_path(), - get_current_task_name() - ) - - -def update_menu_task_label(): - """Update the task label in Avalon menu to current session""" - - object_name = self._change_context_menu - found_menu = findMenuAction(object_name) - - if not found_menu: - log.warning("Can't find menuItem: {}".format(object_name)) - return - - label = get_context_label() - - menu = found_menu.menu() - self._change_context_menu = label - menu.setTitle(label) - - -def menu_install(): - """ - Installing menu into Hiero - - """ - - from . import ( - publish, launch_workfiles_app, reload_config, - apply_colorspace_project, apply_colorspace_clips - ) - from .lib import get_main_window - - main_window = get_main_window() - - # here is the best place to add menu - - menu_name = os.environ['AYON_MENU_LABEL'] - - context_label = get_context_label() - - self._change_context_menu = context_label - - try: - check_made_menu = findMenuAction(menu_name) - except Exception: - check_made_menu = None - - if not check_made_menu: - # Grab Hiero's MenuBar - menu = hiero.ui.menuBar().addMenu(menu_name) - else: - menu = check_made_menu.menu() - - context_label_action = menu.addAction(context_label) - context_label_action.setEnabled(False) - - menu.addSeparator() - - workfiles_action = menu.addAction("Work Files...") - workfiles_action.setIcon(QtGui.QIcon("icons:Position.png")) - workfiles_action.triggered.connect(launch_workfiles_app) - - default_tags_action = menu.addAction("Create Default Tags") - default_tags_action.setIcon(QtGui.QIcon("icons:Position.png")) - default_tags_action.triggered.connect(tags.add_tags_to_workfile) - - menu.addSeparator() - - creator_action = menu.addAction("Create...") - creator_action.setIcon(QtGui.QIcon("icons:CopyRectangle.png")) - creator_action.triggered.connect( - lambda: host_tools.show_creator(parent=main_window) - ) - - publish_action = menu.addAction("Publish...") - publish_action.setIcon(QtGui.QIcon("icons:Output.png")) - publish_action.triggered.connect( - lambda *args: publish(hiero.ui.mainWindow()) - ) - - loader_action = menu.addAction("Load...") - loader_action.setIcon(QtGui.QIcon("icons:CopyRectangle.png")) - loader_action.triggered.connect( - lambda: host_tools.show_loader(parent=main_window) - ) - - sceneinventory_action = menu.addAction("Manage...") - sceneinventory_action.setIcon(QtGui.QIcon("icons:CopyRectangle.png")) - sceneinventory_action.triggered.connect( - lambda: host_tools.show_scene_inventory(parent=main_window) - ) - - library_action = menu.addAction("Library...") - library_action.setIcon(QtGui.QIcon("icons:CopyRectangle.png")) - library_action.triggered.connect( - lambda: host_tools.show_library_loader(parent=main_window) - ) - - if is_dev_mode_enabled(): - menu.addSeparator() - reload_action = menu.addAction("Reload pipeline") - reload_action.setIcon(QtGui.QIcon("icons:ColorAdd.png")) - reload_action.triggered.connect(reload_config) - - menu.addSeparator() - apply_colorspace_p_action = menu.addAction("Apply Colorspace Project") - apply_colorspace_p_action.setIcon(QtGui.QIcon("icons:ColorAdd.png")) - apply_colorspace_p_action.triggered.connect(apply_colorspace_project) - - apply_colorspace_c_action = menu.addAction("Apply Colorspace Clips") - apply_colorspace_c_action.setIcon(QtGui.QIcon("icons:ColorAdd.png")) - apply_colorspace_c_action.triggered.connect(apply_colorspace_clips) - - menu.addSeparator() - - exeprimental_action = menu.addAction("Experimental tools...") - exeprimental_action.triggered.connect( - lambda: host_tools.show_experimental_tools_dialog(parent=main_window) - ) - - -def add_scripts_menu(): - try: - from . import launchforhiero - except ImportError: - - log.warning( - "Skipping studio.menu install, because " - "'scriptsmenu' module seems unavailable." - ) - return - - # load configuration of custom menu - project_settings = get_project_settings(get_current_project_name()) - config = project_settings["hiero"]["scriptsmenu"]["definition"] - _menu = project_settings["hiero"]["scriptsmenu"]["name"] - - if not config: - log.warning("Skipping studio menu, no definition found.") - return - - # run the launcher for Hiero menu - studio_menu = launchforhiero.main(title=_menu.title()) - - # apply configuration - studio_menu.build_from_configuration(studio_menu, config) diff --git a/server_addon/hiero/client/ayon_hiero/api/otio/__init__.py b/server_addon/hiero/client/ayon_hiero/api/otio/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/server_addon/hiero/client/ayon_hiero/api/otio/hiero_export.py b/server_addon/hiero/client/ayon_hiero/api/otio/hiero_export.py deleted file mode 100644 index de547f3046..0000000000 --- a/server_addon/hiero/client/ayon_hiero/api/otio/hiero_export.py +++ /dev/null @@ -1,443 +0,0 @@ -""" compatibility OpenTimelineIO 0.12.0 and newer -""" - -import os -import re -import ast -import opentimelineio as otio -from . import utils -import hiero.core -import hiero.ui - - -TRACK_TYPE_MAP = { - hiero.core.VideoTrack: otio.schema.TrackKind.Video, - hiero.core.AudioTrack: otio.schema.TrackKind.Audio -} -MARKER_COLOR_MAP = { - "magenta": otio.schema.MarkerColor.MAGENTA, - "red": otio.schema.MarkerColor.RED, - "yellow": otio.schema.MarkerColor.YELLOW, - "green": otio.schema.MarkerColor.GREEN, - "cyan": otio.schema.MarkerColor.CYAN, - "blue": otio.schema.MarkerColor.BLUE, -} - - -class CTX: - project_fps = None - timeline = None - include_tags = True - - -def flatten(list_): - for item_ in list_: - if isinstance(item_, (list, tuple)): - for sub_item in flatten(item_): - yield sub_item - else: - yield item_ - - -def create_otio_rational_time(frame, fps): - return otio.opentime.RationalTime( - float(frame), - float(fps) - ) - - -def create_otio_time_range(start_frame, frame_duration, fps): - return otio.opentime.TimeRange( - start_time=create_otio_rational_time(start_frame, fps), - duration=create_otio_rational_time(frame_duration, fps) - ) - - -def _get_metadata(item): - if hasattr(item, 'metadata'): - return {key: value for key, value in dict(item.metadata()).items()} - return {} - - -def create_time_effects(otio_clip, track_item): - # get all subtrack items - subTrackItems = flatten(track_item.parent().subTrackItems()) - speed = track_item.playbackSpeed() - - otio_effect = None - # retime on track item - if speed != 1.: - # make effect - otio_effect = otio.schema.LinearTimeWarp() - otio_effect.name = "Speed" - otio_effect.time_scalar = speed - - # freeze frame effect - if speed == 0.: - otio_effect = otio.schema.FreezeFrame() - otio_effect.name = "FreezeFrame" - - if otio_effect: - # add otio effect to clip effects - otio_clip.effects.append(otio_effect) - - # loop through and get all Timewarps - for effect in subTrackItems: - if ((track_item not in effect.linkedItems()) - and (len(effect.linkedItems()) > 0)): - continue - # avoid all effect which are not TimeWarp and disabled - if "TimeWarp" not in effect.name(): - continue - - if not effect.isEnabled(): - continue - - node = effect.node() - name = node["name"].value() - - # solve effect class as effect name - _name = effect.name() - if "_" in _name: - effect_name = re.sub(r"(?:_)[_0-9]+", "", _name) # more numbers - else: - effect_name = re.sub(r"\d+", "", _name) # one number - - metadata = {} - # add knob to metadata - for knob in ["lookup", "length"]: - value = node[knob].value() - animated = node[knob].isAnimated() - if animated: - value = [ - ((node[knob].getValueAt(i)) - i) - for i in range( - track_item.timelineIn(), track_item.timelineOut() + 1) - ] - - metadata[knob] = value - - # make effect - otio_effect = otio.schema.TimeEffect() - otio_effect.name = name - otio_effect.effect_name = effect_name - otio_effect.metadata.update(metadata) - - # add otio effect to clip effects - otio_clip.effects.append(otio_effect) - - -def create_otio_reference(clip): - metadata = _get_metadata(clip) - media_source = clip.mediaSource() - - # get file info for path and start frame - file_info = media_source.fileinfos().pop() - frame_start = file_info.startFrame() - path = file_info.filename() - - # get padding and other file infos - padding = media_source.filenamePadding() - file_head = media_source.filenameHead() - is_sequence = not media_source.singleFile() - frame_duration = media_source.duration() - fps = utils.get_rate(clip) or CTX.project_fps - extension = os.path.splitext(path)[-1] - - if is_sequence: - metadata.update({ - "isSequence": True, - "padding": padding - }) - - # add resolution metadata - metadata.update({ - "openpype.source.colourtransform": clip.sourceMediaColourTransform(), - "openpype.source.width": int(media_source.width()), - "openpype.source.height": int(media_source.height()), - "openpype.source.pixelAspect": float(media_source.pixelAspect()) - }) - - otio_ex_ref_item = None - - if is_sequence: - # if it is file sequence try to create `ImageSequenceReference` - # the OTIO might not be compatible so return nothing and do it old way - try: - dirname = os.path.dirname(path) - otio_ex_ref_item = otio.schema.ImageSequenceReference( - target_url_base=dirname + os.sep, - name_prefix=file_head, - name_suffix=extension, - start_frame=frame_start, - frame_zero_padding=padding, - rate=fps, - available_range=create_otio_time_range( - frame_start, - frame_duration, - fps - ) - ) - except AttributeError: - pass - - if not otio_ex_ref_item: - reformat_path = utils.get_reformated_path(path, padded=False) - # in case old OTIO or video file create `ExternalReference` - otio_ex_ref_item = otio.schema.ExternalReference( - target_url=reformat_path, - available_range=create_otio_time_range( - frame_start, - frame_duration, - fps - ) - ) - - # add metadata to otio item - add_otio_metadata(otio_ex_ref_item, media_source, **metadata) - - return otio_ex_ref_item - - -def get_marker_color(tag): - icon = tag.icon() - pat = r'icons:Tag(?P\w+)\.\w+' - - res = re.search(pat, icon) - if res: - color = res.groupdict().get('color') - if color.lower() in MARKER_COLOR_MAP: - return MARKER_COLOR_MAP[color.lower()] - - return otio.schema.MarkerColor.RED - - -def create_otio_markers(otio_item, item): - for tag in item.tags(): - if not tag.visible(): - continue - - if tag.name() == 'Copy': - # Hiero adds this tag to a lot of clips - continue - - frame_rate = utils.get_rate(item) or CTX.project_fps - - marked_range = otio.opentime.TimeRange( - start_time=otio.opentime.RationalTime( - tag.inTime(), - frame_rate - ), - duration=otio.opentime.RationalTime( - int(tag.metadata().dict().get('tag.length', '0')), - frame_rate - ) - ) - # add tag metadata but remove "tag." string - metadata = {} - - for key, value in tag.metadata().dict().items(): - _key = key.replace("tag.", "") - - try: - # capture exceptions which are related to strings only - _value = ast.literal_eval(value) - except (ValueError, SyntaxError): - _value = value - - metadata.update({_key: _value}) - - # Store the source item for future import assignment - metadata['hiero_source_type'] = item.__class__.__name__ - - marker = otio.schema.Marker( - name=tag.name(), - color=get_marker_color(tag), - marked_range=marked_range, - metadata=metadata - ) - - otio_item.markers.append(marker) - - -def create_otio_clip(track_item): - clip = track_item.source() - speed = track_item.playbackSpeed() - # flip if speed is in minus - source_in = track_item.sourceIn() if speed > 0 else track_item.sourceOut() - - duration = int(track_item.duration()) - - fps = utils.get_rate(track_item) or CTX.project_fps - name = track_item.name() - - media_reference = create_otio_reference(clip) - source_range = create_otio_time_range( - int(source_in), - int(duration), - fps - ) - - otio_clip = otio.schema.Clip( - name=name, - source_range=source_range, - media_reference=media_reference - ) - - # Add tags as markers - if CTX.include_tags: - create_otio_markers(otio_clip, track_item) - create_otio_markers(otio_clip, track_item.source()) - - # only if video - if not clip.mediaSource().hasAudio(): - # Add effects to clips - create_time_effects(otio_clip, track_item) - - return otio_clip - - -def create_otio_gap(gap_start, clip_start, tl_start_frame, fps): - return otio.schema.Gap( - source_range=create_otio_time_range( - gap_start, - (clip_start - tl_start_frame) - gap_start, - fps - ) - ) - - -def _create_otio_timeline(): - project = CTX.timeline.project() - metadata = _get_metadata(CTX.timeline) - - metadata.update({ - "openpype.timeline.width": int(CTX.timeline.format().width()), - "openpype.timeline.height": int(CTX.timeline.format().height()), - "openpype.timeline.pixelAspect": int(CTX.timeline.format().pixelAspect()), # noqa - "openpype.project.useOCIOEnvironmentOverride": project.useOCIOEnvironmentOverride(), # noqa - "openpype.project.lutSetting16Bit": project.lutSetting16Bit(), - "openpype.project.lutSetting8Bit": project.lutSetting8Bit(), - "openpype.project.lutSettingFloat": project.lutSettingFloat(), - "openpype.project.lutSettingLog": project.lutSettingLog(), - "openpype.project.lutSettingViewer": project.lutSettingViewer(), - "openpype.project.lutSettingWorkingSpace": project.lutSettingWorkingSpace(), # noqa - "openpype.project.lutUseOCIOForExport": project.lutUseOCIOForExport(), - "openpype.project.ocioConfigName": project.ocioConfigName(), - "openpype.project.ocioConfigPath": project.ocioConfigPath() - }) - - start_time = create_otio_rational_time( - CTX.timeline.timecodeStart(), CTX.project_fps) - - return otio.schema.Timeline( - name=CTX.timeline.name(), - global_start_time=start_time, - metadata=metadata - ) - - -def create_otio_track(track_type, track_name): - return otio.schema.Track( - name=track_name, - kind=TRACK_TYPE_MAP[track_type] - ) - - -def add_otio_gap(track_item, otio_track, prev_out): - gap_length = track_item.timelineIn() - prev_out - if prev_out != 0: - gap_length -= 1 - - gap = otio.opentime.TimeRange( - duration=otio.opentime.RationalTime( - gap_length, - CTX.project_fps - ) - ) - otio_gap = otio.schema.Gap(source_range=gap) - otio_track.append(otio_gap) - - -def add_otio_metadata(otio_item, media_source, **kwargs): - metadata = _get_metadata(media_source) - - # add additional metadata from kwargs - if kwargs: - metadata.update(kwargs) - - # add metadata to otio item metadata - for key, value in metadata.items(): - otio_item.metadata.update({key: value}) - - -def create_otio_timeline(): - - def set_prev_item(itemindex, track_item): - # Add Gap if needed - if itemindex == 0: - # if it is first track item at track then add - # it to previous item - return track_item - - else: - # get previous item - return track_item.parent().items()[itemindex - 1] - - # get current timeline - CTX.timeline = hiero.ui.activeSequence() - CTX.project_fps = CTX.timeline.framerate().toFloat() - - # convert timeline to otio - otio_timeline = _create_otio_timeline() - - # loop all defined track types - for track in CTX.timeline.items(): - # skip if track is disabled - if not track.isEnabled(): - continue - - # convert track to otio - otio_track = create_otio_track( - type(track), track.name()) - - for itemindex, track_item in enumerate(track): - # Add Gap if needed - if itemindex == 0: - # if it is first track item at track then add - # it to previous item - prev_item = track_item - - else: - # get previous item - prev_item = track_item.parent().items()[itemindex - 1] - - # calculate clip frame range difference from each other - clip_diff = track_item.timelineIn() - prev_item.timelineOut() - - # add gap if first track item is not starting - # at first timeline frame - if itemindex == 0 and track_item.timelineIn() > 0: - add_otio_gap(track_item, otio_track, 0) - - # or add gap if following track items are having - # frame range differences from each other - elif itemindex and clip_diff != 1: - add_otio_gap(track_item, otio_track, prev_item.timelineOut()) - - # create otio clip and add it to track - otio_clip = create_otio_clip(track_item) - otio_track.append(otio_clip) - - # Add tags as markers - if CTX.include_tags: - create_otio_markers(otio_track, track) - - # add track to otio timeline - otio_timeline.tracks.append(otio_track) - - return otio_timeline - - -def write_to_file(otio_timeline, path): - otio.adapters.write_to_file(otio_timeline, path) diff --git a/server_addon/hiero/client/ayon_hiero/api/otio/hiero_import.py b/server_addon/hiero/client/ayon_hiero/api/otio/hiero_import.py deleted file mode 100644 index 29ff7f7325..0000000000 --- a/server_addon/hiero/client/ayon_hiero/api/otio/hiero_import.py +++ /dev/null @@ -1,535 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -__author__ = "Daniel Flehner Heen" -__credits__ = ["Jakub Jezek", "Daniel Flehner Heen"] - - -import os -import hiero.core -import hiero.ui - -import PySide2.QtWidgets as qw - -try: - from urllib import unquote - -except ImportError: - from urllib.parse import unquote # lint:ok - -import opentimelineio as otio - -_otio_old = False - - -def inform(messages): - if isinstance(messages, type('')): - messages = [messages] - - qw.QMessageBox.information( - hiero.ui.mainWindow(), - 'OTIO Import', - '\n'.join(messages), - qw.QMessageBox.StandardButton.Ok - ) - - -def get_transition_type(otio_item, otio_track): - _in, _out = otio_track.neighbors_of(otio_item) - - if isinstance(_in, otio.schema.Gap): - _in = None - - if isinstance(_out, otio.schema.Gap): - _out = None - - if _in and _out: - return 'dissolve' - - elif _in and not _out: - return 'fade_out' - - elif not _in and _out: - return 'fade_in' - - else: - return 'unknown' - - -def find_trackitem(otio_clip, hiero_track): - for item in hiero_track.items(): - if item.timelineIn() == otio_clip.range_in_parent().start_time.value: - if item.name() == otio_clip.name: - return item - - return None - - -def get_neighboring_trackitems(otio_item, otio_track, hiero_track): - _in, _out = otio_track.neighbors_of(otio_item) - trackitem_in = None - trackitem_out = None - - if _in: - trackitem_in = find_trackitem(_in, hiero_track) - - if _out: - trackitem_out = find_trackitem(_out, hiero_track) - - return trackitem_in, trackitem_out - - -def apply_transition(otio_track, otio_item, track): - warning = None - - # Figure out type of transition - transition_type = get_transition_type(otio_item, otio_track) - - # Figure out track kind for getattr below - kind = '' - if isinstance(track, hiero.core.AudioTrack): - kind = 'Audio' - - # Gather TrackItems involved in transition - item_in, item_out = get_neighboring_trackitems( - otio_item, - otio_track, - track - ) - - # Create transition object - if transition_type == 'dissolve': - transition_func = getattr( - hiero.core.Transition, - "create{kind}DissolveTransition".format(kind=kind) - ) - - try: - transition = transition_func( - item_in, - item_out, - otio_item.in_offset.value, - otio_item.out_offset.value, - ) - - # Catch error raised if transition is bigger than TrackItem source - except RuntimeError as e: - transition = None - warning = ( - "Unable to apply transition \"{t.name}\": {e} " - "Ignoring the transition.").format(t=otio_item, e=str(e)) - - elif transition_type == 'fade_in': - transition_func = getattr( - hiero.core.Transition, - 'create{kind}FadeInTransition'.format(kind=kind) - ) - - # Warn user if part of fade is outside of clip - if otio_item.in_offset.value: - warning = \ - 'Fist half of transition "{t.name}" is outside of clip and ' \ - 'not valid in Hiero. Only applied second half.' \ - .format(t=otio_item) - - transition = transition_func( - item_out, - otio_item.out_offset.value, - ) - - elif transition_type == 'fade_out': - transition_func = getattr( - hiero.core.Transition, - 'create{kind}FadeOutTransition'.format(kind=kind) - ) - transition = transition_func( - item_in, - otio_item.in_offset.value - ) - - # Warn user if part of fade is outside of clip - if otio_item.out_offset.value: - warning = \ - 'Second half of transition "{t.name}" is outside of clip ' \ - 'and not valid in Hiero. Only applied first half.' \ - .format(t=otio_item) - - else: - # Unknown transition - return - - # Apply transition to track - if transition: - track.addTransition(transition) - - # Inform user about missing or adjusted transitions - return warning - - -def prep_url(url_in): - url = unquote(url_in) - - if url.startswith('file://localhost/'): - return url - - url = 'file://localhost{sep}{url}'.format( - sep=url.startswith(os.sep) and '' or os.sep, - url=url.startswith(os.sep) and url[1:] or url - ) - - return url - - -def create_offline_mediasource(otio_clip, path=None): - global _otio_old - - hiero_rate = hiero.core.TimeBase(otio_clip.source_range.start_time.rate) - - try: - legal_media_refs = ( - otio.schema.ExternalReference, - otio.schema.ImageSequenceReference - ) - except AttributeError: - _otio_old = True - legal_media_refs = ( - otio.schema.ExternalReference - ) - - if isinstance(otio_clip.media_reference, legal_media_refs): - source_range = otio_clip.available_range() - - else: - source_range = otio_clip.source_range - - if path is None: - path = otio_clip.name - - media = hiero.core.MediaSource.createOfflineVideoMediaSource( - prep_url(path), - source_range.start_time.value, - source_range.duration.value, - hiero_rate, - source_range.start_time.value, - ) - - return media - - -def load_otio(otio_file, project=None, sequence=None): - otio_timeline = otio.adapters.read_from_file(otio_file) - build_sequence(otio_timeline, project=project, sequence=sequence) - - -marker_color_map = { - "PINK": "Magenta", - "RED": "Red", - "ORANGE": "Yellow", - "YELLOW": "Yellow", - "GREEN": "Green", - "CYAN": "Cyan", - "BLUE": "Blue", - "PURPLE": "Magenta", - "MAGENTA": "Magenta", - "BLACK": "Blue", - "WHITE": "Green" -} - - -def get_tag(tagname, tagsbin): - for tag in tagsbin.items(): - if tag.name() == tagname: - return tag - - if isinstance(tag, hiero.core.Bin): - tag = get_tag(tagname, tag) - - if tag is not None: - return tag - - return None - - -def add_metadata(metadata, hiero_item): - for key, value in metadata.get('Hiero', dict()).items(): - if key == 'source_type': - # Only used internally to reassign tag to correct Hiero item - continue - - if isinstance(value, dict): - add_metadata(value, hiero_item) - continue - - if value is not None: - if not key.startswith('tag.'): - key = 'tag.' + key - - hiero_item.metadata().setValue(key, str(value)) - - -def add_markers(otio_item, hiero_item, tagsbin): - if isinstance(otio_item, (otio.schema.Stack, otio.schema.Clip)): - markers = otio_item.markers - - elif isinstance(otio_item, otio.schema.Timeline): - markers = otio_item.tracks.markers - - else: - markers = [] - - for marker in markers: - meta = marker.metadata.get('Hiero', dict()) - if 'source_type' in meta: - if hiero_item.__class__.__name__ != meta.get('source_type'): - continue - - marker_color = marker.color - - _tag = get_tag(marker.name, tagsbin) - if _tag is None: - _tag = get_tag(marker_color_map[marker_color], tagsbin) - - if _tag is None: - _tag = hiero.core.Tag(marker_color_map[marker.color]) - - start = marker.marked_range.start_time.value - end = ( - marker.marked_range.start_time.value + - marker.marked_range.duration.value - ) - - if hasattr(hiero_item, 'addTagToRange'): - tag = hiero_item.addTagToRange(_tag, start, end) - - else: - tag = hiero_item.addTag(_tag) - - tag.setName(marker.name or marker_color_map[marker_color]) - # tag.setNote(meta.get('tag.note', '')) - - # Add metadata - add_metadata(marker.metadata, tag) - - -def create_track(otio_track, tracknum, track_kind): - if track_kind is None and hasattr(otio_track, 'kind'): - track_kind = otio_track.kind - - # Create a Track - if track_kind == otio.schema.TrackKind.Video: - track = hiero.core.VideoTrack( - otio_track.name or 'Video{n}'.format(n=tracknum) - ) - - else: - track = hiero.core.AudioTrack( - otio_track.name or 'Audio{n}'.format(n=tracknum) - ) - - return track - - -def create_clip(otio_clip, tagsbin, sequencebin): - # Create MediaSource - url = None - media = None - otio_media = otio_clip.media_reference - - if isinstance(otio_media, otio.schema.ExternalReference): - url = prep_url(otio_media.target_url) - media = hiero.core.MediaSource(url) - - elif not _otio_old: - if isinstance(otio_media, otio.schema.ImageSequenceReference): - url = prep_url(otio_media.abstract_target_url('#')) - media = hiero.core.MediaSource(url) - - if media is None or media.isOffline(): - media = create_offline_mediasource(otio_clip, url) - - # Reuse previous clip if possible - clip = None - for item in sequencebin.clips(): - if item.activeItem().mediaSource() == media: - clip = item.activeItem() - break - - if not clip: - # Create new Clip - clip = hiero.core.Clip(media) - - # Add Clip to a Bin - sequencebin.addItem(hiero.core.BinItem(clip)) - - # Add markers - add_markers(otio_clip, clip, tagsbin) - - return clip - - -def create_trackitem(playhead, track, otio_clip, clip): - source_range = otio_clip.source_range - - trackitem = track.createTrackItem(otio_clip.name) - trackitem.setPlaybackSpeed(source_range.start_time.rate) - trackitem.setSource(clip) - - time_scalar = 1. - - # Check for speed effects and adjust playback speed accordingly - for effect in otio_clip.effects: - if isinstance(effect, otio.schema.LinearTimeWarp): - time_scalar = effect.time_scalar - # Only reverse effect can be applied here - if abs(time_scalar) == 1.: - trackitem.setPlaybackSpeed( - trackitem.playbackSpeed() * time_scalar - ) - - elif isinstance(effect, otio.schema.FreezeFrame): - # For freeze frame, playback speed must be set after range - time_scalar = 0. - - # If reverse playback speed swap source in and out - if trackitem.playbackSpeed() < 0: - source_out = source_range.start_time.value - source_in = source_range.end_time_inclusive().value - - timeline_in = playhead + source_out - timeline_out = (timeline_in + source_range.duration.value) - 1 - else: - # Normal playback speed - source_in = source_range.start_time.value - source_out = source_range.end_time_inclusive().value - - timeline_in = playhead - timeline_out = (timeline_in + source_range.duration.value) - 1 - - # Set source and timeline in/out points - trackitem.setTimes( - timeline_in, - timeline_out, - source_in, - source_out, - ) - - # Apply playback speed for freeze frames - if abs(time_scalar) != 1.: - trackitem.setPlaybackSpeed(trackitem.playbackSpeed() * time_scalar) - - # Link audio to video when possible - if isinstance(track, hiero.core.AudioTrack): - for other in track.parent().trackItemsAt(playhead): - if other.source() == clip: - trackitem.link(other) - - return trackitem - - -def build_sequence( - otio_timeline, project=None, sequence=None, track_kind=None -): - if project is None: - if sequence: - project = sequence.project() - - else: - # Per version 12.1v2 there is no way of getting active project - project = hiero.core.projects(hiero.core.Project.kUserProjects)[-1] - - projectbin = project.clipsBin() - - if not sequence: - # Create a Sequence - sequence = hiero.core.Sequence(otio_timeline.name or 'OTIOSequence') - - # Set sequence settings from otio timeline if available - if ( - hasattr(otio_timeline, 'global_start_time') - and otio_timeline.global_start_time - ): - start_time = otio_timeline.global_start_time - sequence.setFramerate(start_time.rate) - sequence.setTimecodeStart(start_time.value) - - # Create a Bin to hold clips - projectbin.addItem(hiero.core.BinItem(sequence)) - - sequencebin = hiero.core.Bin(sequence.name()) - projectbin.addItem(sequencebin) - - else: - sequencebin = projectbin - - # Get tagsBin - tagsbin = hiero.core.project("Tag Presets").tagsBin() - - # Add timeline markers - add_markers(otio_timeline, sequence, tagsbin) - - if isinstance(otio_timeline, otio.schema.Timeline): - tracks = otio_timeline.tracks - - else: - tracks = [otio_timeline] - - for tracknum, otio_track in enumerate(tracks): - playhead = 0 - _transitions = [] - - # Add track to sequence - track = create_track(otio_track, tracknum, track_kind) - sequence.addTrack(track) - - # iterate over items in track - for _itemnum, otio_clip in enumerate(otio_track): - if isinstance(otio_clip, (otio.schema.Track, otio.schema.Stack)): - inform('Nested sequences/tracks are created separately.') - - # Add gap where the nested sequence would have been - playhead += otio_clip.source_range.duration.value - - # Process nested sequence - build_sequence( - otio_clip, - project=project, - track_kind=otio_track.kind - ) - - elif isinstance(otio_clip, otio.schema.Clip): - # Create a Clip - clip = create_clip(otio_clip, tagsbin, sequencebin) - - # Create TrackItem - trackitem = create_trackitem( - playhead, track, otio_clip, clip - ) - - # Add markers - add_markers(otio_clip, trackitem, tagsbin) - - # Add trackitem to track - track.addTrackItem(trackitem) - - # Update playhead - playhead = trackitem.timelineOut() + 1 - - elif isinstance(otio_clip, otio.schema.Transition): - # Store transitions for when all clips in the track are created - _transitions.append((otio_track, otio_clip)) - - elif isinstance(otio_clip, otio.schema.Gap): - # Hiero has no fillers, slugs or blanks at the moment - playhead += otio_clip.source_range.duration.value - - # Apply transitions we stored earlier now that all clips are present - warnings = [] - for otio_track, otio_item in _transitions: - # Catch warnings form transitions in case - # of unsupported transitions - warning = apply_transition(otio_track, otio_item, track) - if warning: - warnings.append(warning) - - if warnings: - inform(warnings) diff --git a/server_addon/hiero/client/ayon_hiero/api/otio/utils.py b/server_addon/hiero/client/ayon_hiero/api/otio/utils.py deleted file mode 100644 index f7cb58f1e8..0000000000 --- a/server_addon/hiero/client/ayon_hiero/api/otio/utils.py +++ /dev/null @@ -1,80 +0,0 @@ -import re -import opentimelineio as otio - - -def timecode_to_frames(timecode, framerate): - rt = otio.opentime.from_timecode(timecode, 24) - return int(otio.opentime.to_frames(rt)) - - -def frames_to_timecode(frames, framerate): - rt = otio.opentime.from_frames(frames, framerate) - return otio.opentime.to_timecode(rt) - - -def frames_to_secons(frames, framerate): - rt = otio.opentime.from_frames(frames, framerate) - return otio.opentime.to_seconds(rt) - - -def get_reformated_path(path, padded=True): - """ - Return fixed python expression path - - Args: - path (str): path url or simple file name - - Returns: - type: string with reformatted path - - Example: - get_reformated_path("plate.[0001-1008].exr") > plate.%04d.exr - - """ - if "%" in path: - padding_pattern = r"(\d+)" - padding = int(re.findall(padding_pattern, path).pop()) - num_pattern = r"(%\d+d)" - if padded: - path = re.sub(num_pattern, "%0{}d".format(padding), path) - else: - path = re.sub(num_pattern, "%d", path) - return path - - -def get_padding_from_path(path): - """ - Return padding number from DaVinci Resolve sequence path style - - Args: - path (str): path url or simple file name - - Returns: - int: padding number - - Example: - get_padding_from_path("plate.[0001-1008].exr") > 4 - - """ - padding_pattern = "(\\d+)(?=-)" - if "[" in path: - return len(re.findall(padding_pattern, path).pop()) - - return None - - -def get_rate(item): - if not hasattr(item, 'framerate'): - return None - - num, den = item.framerate().toRational() - - try: - rate = float(num) / float(den) - except ZeroDivisionError: - return None - - if rate.is_integer(): - return rate - - return round(rate, 4) diff --git a/server_addon/hiero/client/ayon_hiero/api/pipeline.py b/server_addon/hiero/client/ayon_hiero/api/pipeline.py deleted file mode 100644 index d14d255a87..0000000000 --- a/server_addon/hiero/client/ayon_hiero/api/pipeline.py +++ /dev/null @@ -1,340 +0,0 @@ -""" -Basic avalon integration -""" -from copy import deepcopy -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, - register_creator_plugin_path, - register_loader_plugin_path, - deregister_creator_plugin_path, - deregister_loader_plugin_path, - AVALON_CONTAINER_ID, - AYON_CONTAINER_ID, -) -from ayon_core.tools.utils import host_tools -from ayon_hiero import HIERO_ADDON_ROOT - -from . import lib, menu, events - -log = Logger.get_logger(__name__) - -# plugin paths -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("\\", "/") - -AVALON_CONTAINERS = ":AVALON_CONTAINERS" - - -def install(): - """Installing Hiero integration.""" - - # adding all events - events.register_events() - - log.info("Registering Hiero plug-ins..") - pyblish.register_host("hiero") - pyblish.register_plugin_path(PUBLISH_PATH) - register_loader_plugin_path(LOAD_PATH) - register_creator_plugin_path(CREATE_PATH) - - # register callback for switching publishable - pyblish.register_callback("instanceToggled", on_pyblish_instance_toggled) - - # install menu - menu.menu_install() - menu.add_scripts_menu() - - # register hiero events - events.register_hiero_events() - - -def uninstall(): - """ - Uninstalling Hiero integration for avalon - - """ - log.info("Deregistering Hiero plug-ins..") - pyblish.deregister_host("hiero") - pyblish.deregister_plugin_path(PUBLISH_PATH) - deregister_loader_plugin_path(LOAD_PATH) - deregister_creator_plugin_path(CREATE_PATH) - - # register callback for switching publishable - pyblish.deregister_callback("instanceToggled", on_pyblish_instance_toggled) - - -def containerise(track_item, - name, - namespace, - context, - loader=None, - data=None): - """Bundle Hiero's object into an assembly and imprint it with metadata - - Containerisation enables a tracking of version, author and origin - for loaded assets. - - Arguments: - track_item (hiero.core.TrackItem): object to imprint as container - name (str): Name of resulting assembly - namespace (str): Namespace under which to host container - context (dict): Asset information - loader (str, optional): Name of node used to produce this container. - - Returns: - track_item (hiero.core.TrackItem): containerised object - - """ - - data_imprint = OrderedDict({ - "schema": "openpype:container-2.0", - "id": AVALON_CONTAINER_ID, - "name": str(name), - "namespace": str(namespace), - "loader": str(loader), - "representation": context["representation"]["id"], - }) - - if data: - for k, v in data.items(): - data_imprint.update({k: v}) - - log.debug("_ data_imprint: {}".format(data_imprint)) - lib.set_trackitem_openpype_tag(track_item, data_imprint) - - return track_item - - -def ls(): - """List available containers. - - This function is used by the Container Manager in Nuke. You'll - need to implement a for-loop that then *yields* one Container at - a time. - - See the `container.json` schema for details on how it should look, - and the Maya equivalent, which is in `avalon.maya.pipeline` - """ - - # get all track items from current timeline - all_items = lib.get_track_items() - - # append all video tracks - for track in (lib.get_current_sequence() or []): - if type(track) != hiero.core.VideoTrack: - continue - all_items.append(track) - - for item in all_items: - container_data = parse_container(item) - - if isinstance(container_data, list): - for _c in container_data: - yield _c - elif container_data: - yield container_data - - -def parse_container(item, validate=True): - """Return container data from track_item's pype tag. - - Args: - item (hiero.core.TrackItem or hiero.core.VideoTrack): - A containerised track item. - validate (bool)[optional]: validating with avalon scheme - - Returns: - dict: The container schema data for input containerized track item. - - """ - def data_to_container(item, data): - if ( - not data - or data.get("id") not in { - AYON_CONTAINER_ID, AVALON_CONTAINER_ID - } - ): - return - - if validate and data and data.get("schema"): - schema.validate(data) - - if not isinstance(data, dict): - return - - # If not all required data return the empty container - required = ['schema', 'id', 'name', - 'namespace', 'loader', 'representation'] - - if any(key not in data for key in required): - return - - container = {key: data[key] for key in required} - - container["objectName"] = item.name() - - # Store reference to the node object - container["_item"] = item - - return container - - # convert tag metadata to normal keys names - if type(item) == hiero.core.VideoTrack: - return_list = [] - _data = lib.get_track_openpype_data(item) - - if not _data: - return - # convert the data to list and validate them - for _, obj_data in _data.items(): - container = data_to_container(item, obj_data) - return_list.append(container) - return return_list - else: - _data = lib.get_trackitem_openpype_data(item) - return data_to_container(item, _data) - - -def _update_container_data(container, data): - for key in container: - try: - container[key] = data[key] - except KeyError: - pass - return container - - -def update_container(item, data=None): - """Update container data to input track_item or track's - openpype tag. - - Args: - item (hiero.core.TrackItem or hiero.core.VideoTrack): - A containerised track item. - data (dict)[optional]: dictionery with data to be updated - - Returns: - bool: True if container was updated correctly - - """ - - data = data or {} - data = deepcopy(data) - - if type(item) == hiero.core.VideoTrack: - # form object data for test - object_name = data["objectName"] - - # get all available containers - containers = lib.get_track_openpype_data(item) - container = lib.get_track_openpype_data(item, object_name) - - containers = deepcopy(containers) - container = deepcopy(container) - - # update data in container - updated_container = _update_container_data(container, data) - # merge updated container back to containers - containers.update({object_name: updated_container}) - - return bool(lib.set_track_openpype_tag(item, containers)) - else: - container = lib.get_trackitem_openpype_data(item) - updated_container = _update_container_data(container, data) - - log.info("Updating container: `{}`".format(item.name())) - return bool(lib.set_trackitem_openpype_tag(item, updated_container)) - - -def launch_workfiles_app(*args): - ''' Wrapping function for workfiles launcher ''' - from .lib import get_main_window - - main_window = get_main_window() - # show workfile gui - host_tools.show_workfiles(parent=main_window) - - -def publish(parent): - """Shorthand to publish from within host""" - return host_tools.show_publish(parent) - - -@contextlib.contextmanager -def maintained_selection(): - """Maintain selection during context - - Example: - >>> with maintained_selection(): - ... for track_item in track_items: - ... < do some stuff > - """ - from .lib import ( - set_selected_track_items, - get_selected_track_items - ) - previous_selection = get_selected_track_items() - reset_selection() - try: - # do the operation - yield - finally: - reset_selection() - set_selected_track_items(previous_selection) - - -def reset_selection(): - """Deselect all selected nodes - """ - from .lib import set_selected_track_items - set_selected_track_items([]) - - -def reload_config(): - """Attempt to reload pipeline at run-time. - - CAUTION: This is primarily for development and debugging purposes. - - """ - import importlib - - for module in ( - "ayon_hiero.lib", - "ayon_hiero.menu", - "ayon_hiero.tags" - ): - log.info("Reloading module: {}...".format(module)) - try: - module = importlib.import_module(module) - import imp - imp.reload(module) - except Exception as e: - log.warning("Cannot reload module: {}".format(e)) - importlib.reload(module) - - -def on_pyblish_instance_toggled(instance, old_value, new_value): - """Toggle node passthrough states on instance toggles.""" - - log.info("instance toggle: {}, old_value: {}, new_value:{} ".format( - instance, old_value, new_value)) - - from ayon_hiero.api import ( - get_trackitem_openpype_tag, - set_publish_attribute - ) - - # Whether instances should be passthrough based on new value - track_item = instance.data["item"] - tag = get_trackitem_openpype_tag(track_item) - set_publish_attribute(tag, new_value) diff --git a/server_addon/hiero/client/ayon_hiero/api/plugin.py b/server_addon/hiero/client/ayon_hiero/api/plugin.py deleted file mode 100644 index 16eb1d55f3..0000000000 --- a/server_addon/hiero/client/ayon_hiero/api/plugin.py +++ /dev/null @@ -1,946 +0,0 @@ -import os -from pprint import pformat -import re -from copy import deepcopy - -import hiero - -from qtpy import QtWidgets, QtCore -import qargparse - -from ayon_core.settings import get_current_project_settings -from ayon_core.lib import Logger -from ayon_core.pipeline import LoaderPlugin, LegacyCreator -from ayon_core.pipeline.load import get_representation_path_from_context -from . import lib - -log = Logger.get_logger(__name__) - - -def load_stylesheet(): - path = os.path.join(os.path.dirname(__file__), "style.css") - if not os.path.exists(path): - log.warning("Unable to load stylesheet, file not found in resources") - return "" - - with open(path, "r") as file_stream: - stylesheet = file_stream.read() - return stylesheet - - -class CreatorWidget(QtWidgets.QDialog): - - # output items - items = {} - - def __init__(self, name, info, ui_inputs, parent=None): - super(CreatorWidget, self).__init__(parent) - - self.setObjectName(name) - - self.setWindowFlags( - QtCore.Qt.Window - | QtCore.Qt.CustomizeWindowHint - | QtCore.Qt.WindowTitleHint - | QtCore.Qt.WindowCloseButtonHint - | QtCore.Qt.WindowStaysOnTopHint - ) - self.setWindowTitle(name or "AYON Creator Input") - self.resize(500, 700) - - # Where inputs and labels are set - self.content_widget = [QtWidgets.QWidget(self)] - top_layout = QtWidgets.QFormLayout(self.content_widget[0]) - top_layout.setObjectName("ContentLayout") - top_layout.addWidget(Spacer(5, self)) - - # first add widget tag line - top_layout.addWidget(QtWidgets.QLabel(info)) - - # main dynamic layout - self.scroll_area = QtWidgets.QScrollArea(self, widgetResizable=True) - self.scroll_area.setVerticalScrollBarPolicy( - QtCore.Qt.ScrollBarAsNeeded) - self.scroll_area.setVerticalScrollBarPolicy( - QtCore.Qt.ScrollBarAlwaysOn) - self.scroll_area.setHorizontalScrollBarPolicy( - QtCore.Qt.ScrollBarAlwaysOff) - self.scroll_area.setWidgetResizable(True) - - self.content_widget.append(self.scroll_area) - - scroll_widget = QtWidgets.QWidget(self) - in_scroll_area = QtWidgets.QVBoxLayout(scroll_widget) - self.content_layout = [in_scroll_area] - - # add preset data into input widget layout - self.items = self.populate_widgets(ui_inputs) - self.scroll_area.setWidget(scroll_widget) - - # Confirmation buttons - btns_widget = QtWidgets.QWidget(self) - btns_layout = QtWidgets.QHBoxLayout(btns_widget) - - cancel_btn = QtWidgets.QPushButton("Cancel") - btns_layout.addWidget(cancel_btn) - - ok_btn = QtWidgets.QPushButton("Ok") - btns_layout.addWidget(ok_btn) - - # Main layout of the dialog - main_layout = QtWidgets.QVBoxLayout(self) - main_layout.setContentsMargins(10, 10, 10, 10) - main_layout.setSpacing(0) - - # adding content widget - for w in self.content_widget: - main_layout.addWidget(w) - - main_layout.addWidget(btns_widget) - - ok_btn.clicked.connect(self._on_ok_clicked) - cancel_btn.clicked.connect(self._on_cancel_clicked) - - stylesheet = load_stylesheet() - self.setStyleSheet(stylesheet) - - def _on_ok_clicked(self): - self.result = self.value(self.items) - self.close() - - def _on_cancel_clicked(self): - self.result = None - self.close() - - def value(self, data, new_data=None): - new_data = new_data or dict() - for k, v in data.items(): - new_data[k] = { - "target": None, - "value": None - } - if v["type"] == "dict": - new_data[k]["target"] = v["target"] - new_data[k]["value"] = self.value(v["value"]) - if v["type"] == "section": - new_data.pop(k) - new_data = self.value(v["value"], new_data) - elif getattr(v["value"], "currentText", None): - new_data[k]["target"] = v["target"] - new_data[k]["value"] = v["value"].currentText() - elif getattr(v["value"], "isChecked", None): - new_data[k]["target"] = v["target"] - new_data[k]["value"] = v["value"].isChecked() - elif getattr(v["value"], "value", None): - new_data[k]["target"] = v["target"] - new_data[k]["value"] = v["value"].value() - elif getattr(v["value"], "text", None): - new_data[k]["target"] = v["target"] - new_data[k]["value"] = v["value"].text() - - return new_data - - def camel_case_split(self, text): - matches = re.finditer( - '.+?(?:(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])|$)', text) - return " ".join([str(m.group(0)).capitalize() for m in matches]) - - def create_row(self, layout, type, text, **kwargs): - value_keys = ["setText", "setCheckState", "setValue", "setChecked"] - - # get type attribute from qwidgets - attr = getattr(QtWidgets, type) - - # convert label text to normal capitalized text with spaces - label_text = self.camel_case_split(text) - - # assign the new text to label widget - label = QtWidgets.QLabel(label_text) - label.setObjectName("LineLabel") - - # create attribute name text strip of spaces - attr_name = text.replace(" ", "") - - # create attribute and assign default values - setattr( - self, - attr_name, - attr(parent=self)) - - # assign the created attribute to variable - item = getattr(self, attr_name) - - # set attributes to item which are not values - for func, val in kwargs.items(): - if func in value_keys: - continue - - if getattr(item, func): - log.debug("Setting {} to {}".format(func, val)) - func_attr = getattr(item, func) - if isinstance(val, tuple): - func_attr(*val) - else: - func_attr(val) - - # set values to item - for value_item in value_keys: - if value_item not in kwargs: - continue - if getattr(item, value_item): - getattr(item, value_item)(kwargs[value_item]) - - # add to layout - layout.addRow(label, item) - - return item - - def populate_widgets(self, data, content_layout=None): - """ - Populate widget from input dict. - - Each plugin has its own set of widget rows defined in dictionary - each row values should have following keys: `type`, `target`, - `label`, `order`, `value` and optionally also `toolTip`. - - Args: - data (dict): widget rows or organized groups defined - by types `dict` or `section` - content_layout (QtWidgets.QFormLayout)[optional]: used when nesting - - Returns: - dict: redefined data dict updated with created widgets - - """ - - content_layout = content_layout or self.content_layout[-1] - # fix order of process by defined order value - ordered_keys = list(data.keys()) - for k, v in data.items(): - try: - # try removing a key from index which should - # be filled with new - ordered_keys.pop(v["order"]) - except IndexError: - pass - # add key into correct order - ordered_keys.insert(v["order"], k) - - # process ordered - for k in ordered_keys: - v = data[k] - tool_tip = v.get("toolTip", "") - if v["type"] == "dict": - # adding spacer between sections - self.content_layout.append(QtWidgets.QWidget(self)) - content_layout.addWidget(self.content_layout[-1]) - self.content_layout[-1].setObjectName("sectionHeadline") - - headline = QtWidgets.QVBoxLayout(self.content_layout[-1]) - headline.addWidget(Spacer(20, self)) - headline.addWidget(QtWidgets.QLabel(v["label"])) - - # adding nested layout with label - self.content_layout.append(QtWidgets.QWidget(self)) - self.content_layout[-1].setObjectName("sectionContent") - - nested_content_layout = QtWidgets.QFormLayout( - self.content_layout[-1]) - nested_content_layout.setObjectName("NestedContentLayout") - content_layout.addWidget(self.content_layout[-1]) - - # add nested key as label - data[k]["value"] = self.populate_widgets( - v["value"], nested_content_layout) - - if v["type"] == "section": - # adding spacer between sections - self.content_layout.append(QtWidgets.QWidget(self)) - content_layout.addWidget(self.content_layout[-1]) - self.content_layout[-1].setObjectName("sectionHeadline") - - headline = QtWidgets.QVBoxLayout(self.content_layout[-1]) - headline.addWidget(Spacer(20, self)) - headline.addWidget(QtWidgets.QLabel(v["label"])) - - # adding nested layout with label - self.content_layout.append(QtWidgets.QWidget(self)) - self.content_layout[-1].setObjectName("sectionContent") - - nested_content_layout = QtWidgets.QFormLayout( - self.content_layout[-1]) - nested_content_layout.setObjectName("NestedContentLayout") - content_layout.addWidget(self.content_layout[-1]) - - # add nested key as label - data[k]["value"] = self.populate_widgets( - v["value"], nested_content_layout) - - elif v["type"] == "QLineEdit": - data[k]["value"] = self.create_row( - content_layout, "QLineEdit", v["label"], - setText=v["value"], setToolTip=tool_tip) - elif v["type"] == "QComboBox": - data[k]["value"] = self.create_row( - content_layout, "QComboBox", v["label"], - addItems=v["value"], setToolTip=tool_tip) - elif v["type"] == "QCheckBox": - data[k]["value"] = self.create_row( - content_layout, "QCheckBox", v["label"], - setChecked=v["value"], setToolTip=tool_tip) - elif v["type"] == "QSpinBox": - data[k]["value"] = self.create_row( - content_layout, "QSpinBox", v["label"], - setValue=v["value"], - setDisplayIntegerBase=10000, - setRange=(0, 99999), setMinimum=0, - setMaximum=100000, setToolTip=tool_tip) - - return data - - -class Spacer(QtWidgets.QWidget): - def __init__(self, height, *args, **kwargs): - super(self.__class__, self).__init__(*args, **kwargs) - - self.setFixedHeight(height) - - real_spacer = QtWidgets.QWidget(self) - real_spacer.setObjectName("Spacer") - real_spacer.setFixedHeight(height) - - layout = QtWidgets.QVBoxLayout(self) - layout.setContentsMargins(0, 0, 0, 0) - layout.addWidget(real_spacer) - - self.setLayout(layout) - - -class SequenceLoader(LoaderPlugin): - """A basic SequenceLoader for Resolve - - This will implement the basic behavior for a loader to inherit from that - will containerize the reference and will implement the `remove` and - `update` logic. - - """ - - options = [ - qargparse.Boolean( - "handles", - label="Include handles", - default=0, - help="Load with handles or without?" - ), - qargparse.Choice( - "load_to", - label="Where to load clips", - items=[ - "Current timeline", - "New timeline" - ], - default="Current timeline", - help="Where do you want clips to be loaded?" - ), - qargparse.Choice( - "load_how", - label="How to load clips", - items=[ - "Original timing", - "Sequentially in order" - ], - default="Original timing", - help="Would you like to place it at original timing?" - ) - ] - - def load( - self, - context, - name=None, - namespace=None, - options=None - ): - pass - - def update(self, container, context): - """Update an existing `container` - """ - pass - - def remove(self, container): - """Remove an existing `container` - """ - pass - - -class ClipLoader: - - active_bin = None - data = dict() - - def __init__(self, cls, context, path, **options): - """ Initialize object - - Arguments: - cls (avalon.api.Loader): plugin object - context (dict): loader plugin context - options (dict)[optional]: possible keys: - projectBinPath: "path/to/binItem" - - """ - self.__dict__.update(cls.__dict__) - self.context = context - self.active_project = lib.get_current_project() - self.fname = path - - # try to get value from options or evaluate key value for `handles` - self.with_handles = options.get("handles") or bool( - options.get("handles") is True) - # try to get value from options or evaluate key value for `load_how` - self.sequencial_load = options.get("sequentially") or bool( - "Sequentially in order" in options.get("load_how", "")) - # try to get value from options or evaluate key value for `load_to` - self.new_sequence = options.get("newSequence") or bool( - "New timeline" in options.get("load_to", "")) - self.clip_name_template = options.get( - "clipNameTemplate") or "{asset}_{subset}_{representation}" - assert self._populate_data(), str( - "Cannot Load selected data, look into database " - "or call your supervisor") - - # inject folder data to representation dict - folder_entity = self.context["folder"] - self.data["folderAttributes"] = folder_entity["attrib"] - log.info("__init__ self.data: `{}`".format(pformat(self.data))) - log.info("__init__ options: `{}`".format(pformat(options))) - - # add active components to class - if self.new_sequence: - if options.get("sequence"): - # if multiselection is set then use options sequence - self.active_sequence = options["sequence"] - else: - # create new sequence - self.active_sequence = lib.get_current_sequence(new=True) - self.active_sequence.setFramerate( - hiero.core.TimeBase.fromString( - str(self.data["folderAttributes"]["fps"]))) - else: - self.active_sequence = lib.get_current_sequence() - - if options.get("track"): - # if multiselection is set then use options track - self.active_track = options["track"] - else: - self.active_track = lib.get_current_track( - self.active_sequence, self.data["track_name"]) - - def _populate_data(self): - """ Gets context and convert it to self.data - data structure: - { - "name": "assetName_productName_representationName" - "path": "path/to/file/created/by/get_repr..", - "binPath": "projectBinPath", - } - """ - # create name - repr = self.context["representation"] - repr_cntx = repr["context"] - folder_path = self.context["folder"]["path"] - product_name = self.context["product"]["name"] - representation = repr["name"] - self.data["clip_name"] = self.clip_name_template.format(**repr_cntx) - self.data["track_name"] = "_".join([product_name, representation]) - self.data["versionAttributes"] = self.context["version"]["attrib"] - # gets file path - file = get_representation_path_from_context(self.context) - if not file: - repr_id = repr["id"] - log.warning( - "Representation id `{}` is failing to load".format(repr_id)) - return None - self.data["path"] = file.replace("\\", "/") - - # convert to hashed path - if repr_cntx.get("frame"): - self._fix_path_hashes() - - # solve project bin structure path - hierarchy = "Loader{}".format(folder_path) - - self.data["binPath"] = hierarchy - - return True - - def _fix_path_hashes(self): - """ Convert file path where it is needed padding with hashes - """ - file = self.data["path"] - if "#" not in file: - frame = self.context["representation"]["context"].get("frame") - padding = len(frame) - file = file.replace(frame, "#" * padding) - self.data["path"] = file - - def _make_track_item(self, source_bin_item, audio=False): - """ Create track item with """ - - clip = source_bin_item.activeItem() - - # add to track as clip item - if not audio: - track_item = hiero.core.TrackItem( - self.data["clip_name"], hiero.core.TrackItem.kVideo) - else: - track_item = hiero.core.TrackItem( - self.data["clip_name"], hiero.core.TrackItem.kAudio) - - track_item.setSource(clip) - track_item.setSourceIn(self.handle_start) - track_item.setTimelineIn(self.timeline_in) - track_item.setSourceOut((self.media_duration) - self.handle_end) - track_item.setTimelineOut(self.timeline_out) - track_item.setPlaybackSpeed(1) - self.active_track.addTrackItem(track_item) - - return track_item - - def load(self): - # create project bin for the media to be imported into - self.active_bin = lib.create_bin(self.data["binPath"]) - - # create mediaItem in active project bin - # create clip media - self.media = hiero.core.MediaSource(self.data["path"]) - self.media_duration = int(self.media.duration()) - - # get handles - version_attributes = self.data["versionAttributes"] - self.handle_start = version_attributes.get("handleStart") - self.handle_end = version_attributes.get("handleEnd") - if self.handle_start is None: - self.handle_start = self.data["folderAttributes"]["handleStart"] - if self.handle_end is None: - self.handle_end = self.data["folderAttributes"]["handleEnd"] - - self.handle_start = int(self.handle_start) - self.handle_end = int(self.handle_end) - - if self.sequencial_load: - last_track_item = lib.get_track_items( - sequence_name=self.active_sequence.name(), - track_name=self.active_track.name() - ) - if len(last_track_item) == 0: - last_timeline_out = 0 - else: - last_track_item = last_track_item[-1] - last_timeline_out = int(last_track_item.timelineOut()) + 1 - self.timeline_in = last_timeline_out - self.timeline_out = last_timeline_out + int( - self.data["folderAttributes"]["clipOut"] - - self.data["folderAttributes"]["clipIn"]) - else: - self.timeline_in = int(self.data["folderAttributes"]["clipIn"]) - self.timeline_out = int(self.data["folderAttributes"]["clipOut"]) - - log.debug("__ self.timeline_in: {}".format(self.timeline_in)) - log.debug("__ self.timeline_out: {}".format(self.timeline_out)) - - # check if slate is included - 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 - if slate_on: - self.media_duration -= 1 - self.handle_start += 1 - - # create Clip from Media - clip = hiero.core.Clip(self.media) - clip.setName(self.data["clip_name"]) - - # add Clip to bin if not there yet - if self.data["clip_name"] not in [ - b.name() for b in self.active_bin.items()]: - bin_item = hiero.core.BinItem(clip) - self.active_bin.addItem(bin_item) - - # just make sure the clip is created - # there were some cases were hiero was not creating it - source_bin_item = None - for item in self.active_bin.items(): - if self.data["clip_name"] == item.name(): - source_bin_item = item - if not source_bin_item: - log.warning("Problem with created Source clip: `{}`".format( - self.data["clip_name"])) - - # include handles - if self.with_handles: - self.timeline_in -= self.handle_start - self.timeline_out += self.handle_end - self.handle_start = 0 - self.handle_end = 0 - - # make track item from source in bin as item - track_item = self._make_track_item(source_bin_item) - - log.info("Loading clips: `{}`".format(self.data["clip_name"])) - return track_item - - -class Creator(LegacyCreator): - """Creator class wrapper - """ - clip_color = "Purple" - rename_index = None - - def __init__(self, *args, **kwargs): - super(Creator, self).__init__(*args, **kwargs) - import ayon_hiero.api as phiero - self.presets = get_current_project_settings()[ - "hiero"]["create"].get(self.__class__.__name__, {}) - - # adding basic current context resolve objects - self.project = phiero.get_current_project() - self.sequence = phiero.get_current_sequence() - - if (self.options or {}).get("useSelection"): - timeline_selection = phiero.get_timeline_selection() - self.selected = phiero.get_track_items( - selection=timeline_selection - ) - else: - self.selected = phiero.get_track_items() - - self.widget = CreatorWidget - - -class PublishClip: - """ - Convert a track item to publishable instance - - Args: - track_item (hiero.core.TrackItem): hiero track item object - kwargs (optional): additional data needed for rename=True (presets) - - Returns: - hiero.core.TrackItem: hiero track item object with pype tag - """ - vertical_clip_match = {} - tag_data = {} - types = { - "shot": "shot", - "folder": "folder", - "episode": "episode", - "sequence": "sequence", - "track": "sequence", - } - - # parents search pattern - parents_search_pattern = r"\{([a-z]*?)\}" - - # default templates for non-ui use - rename_default = False - hierarchy_default = "{_folder_}/{_sequence_}/{_track_}" - clip_name_default = "shot_{_trackIndex_:0>3}_{_clipIndex_:0>4}" - base_product_name_default = "" - review_track_default = "< none >" - product_type_default = "plate" - count_from_default = 10 - count_steps_default = 10 - vertical_sync_default = False - driving_layer_default = "" - - def __init__(self, cls, track_item, **kwargs): - # populate input cls attribute onto self.[attr] - self.__dict__.update(cls.__dict__) - - # get main parent objects - self.track_item = track_item - sequence_name = lib.get_current_sequence().name() - self.sequence_name = str(sequence_name).replace(" ", "_") - - # track item (clip) main attributes - self.ti_name = track_item.name() - self.ti_index = int(track_item.eventNumber()) - - # get track name and index - track_name = track_item.parent().name() - self.track_name = str(track_name).replace(" ", "_") - self.track_index = int(track_item.parent().trackIndex()) - - # adding tag.family into tag - if kwargs.get("avalon"): - self.tag_data.update(kwargs["avalon"]) - - # add publish attribute to tag data - self.tag_data.update({"publish": True}) - - # adding ui inputs if any - self.ui_inputs = kwargs.get("ui_inputs", {}) - - # populate default data before we get other attributes - self._populate_track_item_default_data() - - # use all populated default data to create all important attributes - self._populate_attributes() - - # create parents with correct types - self._create_parents() - - def convert(self): - # solve track item data and add them to tag data - tag_hierarchy_data = self._convert_to_tag_data() - - self.tag_data.update(tag_hierarchy_data) - - # if track name is in review track name and also if driving track name - # is not in review track name: skip tag creation - if (self.track_name in self.review_layer) and ( - self.driving_layer not in self.review_layer): - return - - # deal with clip name - new_name = self.tag_data.pop("newClipName") - - if self.rename: - # rename track item - self.track_item.setName(new_name) - self.tag_data["asset_name"] = new_name - else: - self.tag_data["asset_name"] = self.ti_name - self.tag_data["hierarchyData"]["shot"] = self.ti_name - - # AYON unique identifier - folder_path = "/{}/{}".format( - tag_hierarchy_data["hierarchy"], - self.tag_data["asset_name"] - ) - self.tag_data["folderPath"] = folder_path - if self.tag_data["heroTrack"] and self.review_layer: - self.tag_data.update({"reviewTrack": self.review_layer}) - else: - self.tag_data.update({"reviewTrack": None}) - - # TODO: remove debug print - log.debug("___ self.tag_data: {}".format( - pformat(self.tag_data) - )) - - # create pype tag on track_item and add data - lib.imprint(self.track_item, self.tag_data) - - return self.track_item - - def _populate_track_item_default_data(self): - """ Populate default formatting data from track item. """ - - self.track_item_default_data = { - "_folder_": "shots", - "_sequence_": self.sequence_name, - "_track_": self.track_name, - "_clip_": self.ti_name, - "_trackIndex_": self.track_index, - "_clipIndex_": self.ti_index - } - - def _populate_attributes(self): - """ Populate main object attributes. """ - # track item frame range and parent track name for vertical sync check - self.clip_in = int(self.track_item.timelineIn()) - self.clip_out = int(self.track_item.timelineOut()) - - # define ui inputs if non gui mode was used - self.shot_num = self.ti_index - log.debug( - "____ self.shot_num: {}".format(self.shot_num)) - - # ui_inputs data or default values if gui was not used - self.rename = self.ui_inputs.get( - "clipRename", {}).get("value") or self.rename_default - self.clip_name = self.ui_inputs.get( - "clipName", {}).get("value") or self.clip_name_default - self.hierarchy = self.ui_inputs.get( - "hierarchy", {}).get("value") or self.hierarchy_default - self.hierarchy_data = self.ui_inputs.get( - "hierarchyData", {}).get("value") or \ - self.track_item_default_data.copy() - self.count_from = self.ui_inputs.get( - "countFrom", {}).get("value") or self.count_from_default - self.count_steps = self.ui_inputs.get( - "countSteps", {}).get("value") or self.count_steps_default - self.base_product_name = self.ui_inputs.get( - "productName", {}).get("value") or self.base_product_name_default - self.product_type = self.ui_inputs.get( - "productType", {}).get("value") or self.product_type_default - self.vertical_sync = self.ui_inputs.get( - "vSyncOn", {}).get("value") or self.vertical_sync_default - self.driving_layer = self.ui_inputs.get( - "vSyncTrack", {}).get("value") or self.driving_layer_default - self.review_track = self.ui_inputs.get( - "reviewTrack", {}).get("value") or self.review_track_default - self.audio = self.ui_inputs.get( - "audio", {}).get("value") or False - - # build product name from layer name - if self.base_product_name == "": - self.base_product_name = self.track_name - - # create product for publishing - self.product_name = ( - self.product_type + self.base_product_name.capitalize() - ) - - def _replace_hash_to_expression(self, name, text): - """ Replace hash with number in correct padding. """ - _spl = text.split("#") - _len = (len(_spl) - 1) - _repl = "{{{0}:0>{1}}}".format(name, _len) - return text.replace(("#" * _len), _repl) - - - def _convert_to_tag_data(self): - """ Convert internal data to tag data. - - Populating the tag data into internal variable self.tag_data - """ - # define vertical sync attributes - hero_track = True - self.review_layer = "" - if self.vertical_sync: - # check if track name is not in driving layer - if self.track_name not in self.driving_layer: - # if it is not then define vertical sync as None - hero_track = False - - # increasing steps by index of rename iteration - self.count_steps *= self.rename_index - - hierarchy_formatting_data = {} - hierarchy_data = deepcopy(self.hierarchy_data) - _data = self.track_item_default_data.copy() - if self.ui_inputs: - # adding tag metadata from ui - for _k, _v in self.ui_inputs.items(): - if _v["target"] == "tag": - self.tag_data[_k] = _v["value"] - - # driving layer is set as positive match - if hero_track or self.vertical_sync: - # mark review layer - if self.review_track and ( - self.review_track not in self.review_track_default): - # if review layer is defined and not the same as default - self.review_layer = self.review_track - # shot num calculate - if self.rename_index == 0: - self.shot_num = self.count_from - else: - self.shot_num = self.count_from + self.count_steps - - # clip name sequence number - _data.update({"shot": self.shot_num}) - - # solve # in test to pythonic expression - for _k, _v in hierarchy_data.items(): - if "#" not in _v["value"]: - continue - hierarchy_data[ - _k]["value"] = self._replace_hash_to_expression( - _k, _v["value"]) - - # fill up pythonic expresisons in hierarchy data - for k, _v in hierarchy_data.items(): - hierarchy_formatting_data[k] = _v["value"].format(**_data) - else: - # if no gui mode then just pass default data - hierarchy_formatting_data = hierarchy_data - - tag_hierarchy_data = self._solve_tag_hierarchy_data( - hierarchy_formatting_data - ) - - tag_hierarchy_data.update({"heroTrack": True}) - if hero_track and self.vertical_sync: - self.vertical_clip_match.update({ - (self.clip_in, self.clip_out): tag_hierarchy_data - }) - - if not hero_track and self.vertical_sync: - # driving layer is set as negative match - for (_in, _out), hero_data in self.vertical_clip_match.items(): - hero_data.update({"heroTrack": False}) - if _in == self.clip_in and _out == self.clip_out: - data_product_name = hero_data["productName"] - # add track index in case duplicity of names in hero data - if self.product_name in data_product_name: - hero_data["productName"] = self.product_name + str( - self.track_index) - # in case track name and product name is the same then add - if self.base_product_name == self.track_name: - hero_data["productName"] = self.product_name - # assign data to return hierarchy data to tag - tag_hierarchy_data = hero_data - - # add data to return data dict - return tag_hierarchy_data - - def _solve_tag_hierarchy_data(self, hierarchy_formatting_data): - """ Solve tag data from hierarchy data and templates. """ - # fill up clip name and hierarchy keys - hierarchy_filled = self.hierarchy.format(**hierarchy_formatting_data) - clip_name_filled = self.clip_name.format(**hierarchy_formatting_data) - - # remove shot from hierarchy data: is not needed anymore - hierarchy_formatting_data.pop("shot") - - return { - "newClipName": clip_name_filled, - "hierarchy": hierarchy_filled, - "parents": self.parents, - "hierarchyData": hierarchy_formatting_data, - "productName": self.product_name, - "productType": self.product_type, - "families": [self.product_type, self.data["productType"]] - } - - def _convert_to_entity(self, src_type, template): - """ Converting input key to key with type. """ - # convert to entity type - folder_type = self.types.get(src_type, None) - - assert folder_type, "Missing folder type for `{}`".format( - src_type - ) - - # first collect formatting data to use for formatting template - formatting_data = {} - for _k, _v in self.hierarchy_data.items(): - value = _v["value"].format( - **self.track_item_default_data) - formatting_data[_k] = value - - return { - "folder_type": folder_type, - "entity_name": template.format( - **formatting_data - ) - } - - def _create_parents(self): - """ Create parents and return it in list. """ - self.parents = [] - - pattern = re.compile(self.parents_search_pattern) - - par_split = [(pattern.findall(t).pop(), t) - for t in self.hierarchy.split("/")] - - for type, template in par_split: - parent = self._convert_to_entity(type, template) - self.parents.append(parent) diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/HieroPlayer/PlayerPresets.hrox b/server_addon/hiero/client/ayon_hiero/api/startup/HieroPlayer/PlayerPresets.hrox deleted file mode 100644 index ec50e123f0..0000000000 --- a/server_addon/hiero/client/ayon_hiero/api/startup/HieroPlayer/PlayerPresets.hrox +++ /dev/null @@ -1,1108 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2 - 70 - - - - - - - - - - - - - - - - - - - - - - - - - - - 2 - 70 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2 - 70 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2 - 70 - - - 2 - 70 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2 - 70 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2 - 70 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2 - 70 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2 - 70 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2 - 50 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2 - 70 - - - - - - - - - - - - - - - - - - - - - - - - - - - 2 - 70 - - - - - - - - - - - - - - - - - - - - - - - - - - - 2 - 70 - - - 2 - 70 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2 - 70 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2 - 70 - - - 2 - 70 - - - 2 - 70 - 17 - - - 126935040 - 70 - -1 - - - 2 - 70 - 2 - - - - - - diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/1_add_handles_end.png b/server_addon/hiero/client/ayon_hiero/api/startup/Icons/1_add_handles_end.png deleted file mode 100644 index 4561745d66..0000000000 Binary files a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/1_add_handles_end.png and /dev/null differ diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/2_add_handles.png b/server_addon/hiero/client/ayon_hiero/api/startup/Icons/2_add_handles.png deleted file mode 100644 index bb4c1802aa..0000000000 Binary files a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/2_add_handles.png and /dev/null differ diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/3D.png b/server_addon/hiero/client/ayon_hiero/api/startup/Icons/3D.png deleted file mode 100644 index 2de7a72775..0000000000 Binary files a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/3D.png and /dev/null differ diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/3_add_handles_start.png b/server_addon/hiero/client/ayon_hiero/api/startup/Icons/3_add_handles_start.png deleted file mode 100644 index c98e4f74f1..0000000000 Binary files a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/3_add_handles_start.png and /dev/null differ diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/4_2D.png b/server_addon/hiero/client/ayon_hiero/api/startup/Icons/4_2D.png deleted file mode 100644 index 18555698fe..0000000000 Binary files a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/4_2D.png and /dev/null differ diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/edit.png b/server_addon/hiero/client/ayon_hiero/api/startup/Icons/edit.png deleted file mode 100644 index 97e42054e7..0000000000 Binary files a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/edit.png and /dev/null differ diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/fusion.png b/server_addon/hiero/client/ayon_hiero/api/startup/Icons/fusion.png deleted file mode 100644 index 2e498edd69..0000000000 Binary files a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/fusion.png and /dev/null differ diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/hierarchy.png b/server_addon/hiero/client/ayon_hiero/api/startup/Icons/hierarchy.png deleted file mode 100644 index 6acf39ced5..0000000000 Binary files a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/hierarchy.png and /dev/null differ diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/houdini.png b/server_addon/hiero/client/ayon_hiero/api/startup/Icons/houdini.png deleted file mode 100644 index d8c842dd17..0000000000 Binary files a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/houdini.png and /dev/null differ diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/layers.psd b/server_addon/hiero/client/ayon_hiero/api/startup/Icons/layers.psd deleted file mode 100644 index 20ba0e81b0..0000000000 Binary files a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/layers.psd and /dev/null differ diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/lense.png b/server_addon/hiero/client/ayon_hiero/api/startup/Icons/lense.png deleted file mode 100644 index 255b1753ed..0000000000 Binary files a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/lense.png and /dev/null differ diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/lense1.png b/server_addon/hiero/client/ayon_hiero/api/startup/Icons/lense1.png deleted file mode 100644 index 1ad1264807..0000000000 Binary files a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/lense1.png and /dev/null differ diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/maya.png b/server_addon/hiero/client/ayon_hiero/api/startup/Icons/maya.png deleted file mode 100644 index fcfa47ae4f..0000000000 Binary files a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/maya.png and /dev/null differ diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/nuke.png b/server_addon/hiero/client/ayon_hiero/api/startup/Icons/nuke.png deleted file mode 100644 index 107796914b..0000000000 Binary files a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/nuke.png and /dev/null differ diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/pype_icon.png b/server_addon/hiero/client/ayon_hiero/api/startup/Icons/pype_icon.png deleted file mode 100644 index bfacf6eeed..0000000000 Binary files a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/pype_icon.png and /dev/null differ diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/resolution.png b/server_addon/hiero/client/ayon_hiero/api/startup/Icons/resolution.png deleted file mode 100644 index 83803fc36d..0000000000 Binary files a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/resolution.png and /dev/null differ diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/resolution.psd b/server_addon/hiero/client/ayon_hiero/api/startup/Icons/resolution.psd deleted file mode 100644 index 2227b38fcd..0000000000 Binary files a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/resolution.psd and /dev/null differ diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/retiming.png b/server_addon/hiero/client/ayon_hiero/api/startup/Icons/retiming.png deleted file mode 100644 index 1c6f22e02c..0000000000 Binary files a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/retiming.png and /dev/null differ diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/retiming.psd b/server_addon/hiero/client/ayon_hiero/api/startup/Icons/retiming.psd deleted file mode 100644 index bac6fc6b58..0000000000 Binary files a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/retiming.psd and /dev/null differ diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/review.png b/server_addon/hiero/client/ayon_hiero/api/startup/Icons/review.png deleted file mode 100644 index 0d894b6987..0000000000 Binary files a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/review.png and /dev/null differ diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/review.psd b/server_addon/hiero/client/ayon_hiero/api/startup/Icons/review.psd deleted file mode 100644 index 779fcf156d..0000000000 Binary files a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/review.psd and /dev/null differ diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/volume.png b/server_addon/hiero/client/ayon_hiero/api/startup/Icons/volume.png deleted file mode 100644 index e5e1200653..0000000000 Binary files a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/volume.png and /dev/null differ diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/z_layer_bg.png b/server_addon/hiero/client/ayon_hiero/api/startup/Icons/z_layer_bg.png deleted file mode 100644 index 51742b5df2..0000000000 Binary files a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/z_layer_bg.png and /dev/null differ diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/z_layer_fg.png b/server_addon/hiero/client/ayon_hiero/api/startup/Icons/z_layer_fg.png deleted file mode 100644 index 01e5f4f816..0000000000 Binary files a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/z_layer_fg.png and /dev/null differ diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/z_layer_main.png b/server_addon/hiero/client/ayon_hiero/api/startup/Icons/z_layer_main.png deleted file mode 100644 index 0ffb939a7f..0000000000 Binary files a/server_addon/hiero/client/ayon_hiero/api/startup/Icons/z_layer_main.png and /dev/null differ diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Python/Startup/SpreadsheetExport.py b/server_addon/hiero/client/ayon_hiero/api/startup/Python/Startup/SpreadsheetExport.py deleted file mode 100644 index 6a8057ec1e..0000000000 --- a/server_addon/hiero/client/ayon_hiero/api/startup/Python/Startup/SpreadsheetExport.py +++ /dev/null @@ -1,142 +0,0 @@ -# This action adds itself to the Spreadsheet View context menu allowing the contents of the Spreadsheet be exported as a CSV file. -# Usage: Right-click in Spreadsheet > "Export as .CSV" -# Note: This only prints the text data that is visible in the active Spreadsheet View. -# If you've filtered text, only the visible text will be printed to the CSV file -# Usage: Copy to ~/.hiero/Python/StartupUI -import os -import csv - -import hiero.core.events -import hiero.ui -try: - from PySide.QtGui import * - from PySide.QtCore import * -except: - from PySide2.QtGui import * - from PySide2.QtWidgets import * - from PySide2.QtCore import * - - -### Magic Widget Finding Methods - This stuff crawls all the PySide widgets, looking for an answer -def findWidget(w): - global foundryWidgets - if "Foundry" in w.metaObject().className(): - foundryWidgets += [w] - - for c in w.children(): - findWidget(c) - return foundryWidgets - - -def getFoundryWidgetsWithClassName(filter=None): - global foundryWidgets - foundryWidgets = [] - widgets = [] - app = QApplication.instance() - for w in app.topLevelWidgets(): - findWidget(w) - - filteredWidgets = foundryWidgets - if filter: - filteredWidgets = [] - for widget in foundryWidgets: - if filter in widget.metaObject().className(): - filteredWidgets += [widget] - return filteredWidgets - - -# When right click, get the Sequence Name -def activeSpreadsheetTreeView(): - """ - Does some PySide widget Magic to detect the Active Spreadsheet TreeView. - """ - spreadsheetViews = getFoundryWidgetsWithClassName( - filter="SpreadsheetTreeView") - for spreadSheet in spreadsheetViews: - if spreadSheet.hasFocus(): - activeSpreadSheet = spreadSheet - return activeSpreadSheet - return None - - -#### Adds "Export .CSV" action to the Spreadsheet Context menu #### -class SpreadsheetExportCSVAction(QAction): - def __init__(self): - QAction.__init__(self, "Export as .CSV", None) - self.triggered.connect(self.exportCSVFromActiveSpreadsheetView) - hiero.core.events.registerInterest("kShowContextMenu/kSpreadsheet", - self.eventHandler) - self.setIcon(QIcon("icons:FBGridView.png")) - - def eventHandler(self, event): - # Insert the action to the Export CSV menu - event.menu.addAction(self) - - #### The guts!.. Writes a CSV file from a Sequence Object #### - def exportCSVFromActiveSpreadsheetView(self): - - # Get the active QTreeView from the active Spreadsheet - spreadsheetTreeView = activeSpreadsheetTreeView() - - if not spreadsheetTreeView: - return "Unable to detect the active TreeView." - seq = hiero.ui.activeView().sequence() - if not seq: - print("Unable to detect the active Sequence from the activeView.") - return - - # The data model of the QTreeView - model = spreadsheetTreeView.model() - - csvSavePath = os.path.join(QDir.homePath(), "Desktop", - seq.name() + ".csv") - savePath, filter = QFileDialog.getSaveFileName( - None, - caption="Export Spreadsheet to .CSV as...", - dir=csvSavePath, - filter="*.csv") - print("Saving To: {}".format(savePath)) - - # Saving was cancelled... - if len(savePath) == 0: - return - - # Get the Visible Header Columns from the QTreeView - - #csvHeader = ["Event", "Status", "Shot Name", "Reel", "Track", "Speed", "Src In", "Src Out","Src Duration", "Dst In", "Dst Out", "Dst Duration", "Clip", "Clip Media"] - - # Get a CSV writer object - f = open(savePath, "w") - csvWriter = csv.writer( - f, delimiter=',', quotechar="|", quoting=csv.QUOTE_MINIMAL) - - # This is a list of the Column titles - csvHeader = [] - - for col in range(0, model.columnCount()): - if not spreadsheetTreeView.isColumnHidden(col): - csvHeader += [model.headerData(col, Qt.Horizontal)] - - # Write the Header row to the CSV file - csvWriter.writerow(csvHeader) - - # Go through each row/column and print - for row in range(model.rowCount()): - row_data = [] - for col in range(model.columnCount()): - if not spreadsheetTreeView.isColumnHidden(col): - row_data.append( - model.index(row, col, QModelIndex()).data( - Qt.DisplayRole)) - - # Write row to CSV file... - csvWriter.writerow(row_data) - - f.close() - # Conveniently show the CSV file in the native file browser... - QDesktopServices.openUrl( - QUrl('file:///%s' % (os.path.dirname(savePath)))) - - -# Add the action... -csvActions = SpreadsheetExportCSVAction() diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Python/Startup/Startup.py b/server_addon/hiero/client/ayon_hiero/api/startup/Python/Startup/Startup.py deleted file mode 100644 index c916bf37e9..0000000000 --- a/server_addon/hiero/client/ayon_hiero/api/startup/Python/Startup/Startup.py +++ /dev/null @@ -1,19 +0,0 @@ -import traceback - -# activate hiero from pype -from ayon_core.pipeline import install_host -import ayon_hiero.api as phiero -install_host(phiero) - -try: - __import__("ayon_hiero.api") - __import__("pyblish") - -except ImportError as e: - print(traceback.format_exc()) - print("pyblish: Could not load integration: %s " % e) - -else: - # Setup integration - import ayon_hiero.api as phiero - phiero.lib.setup() diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Python/Startup/otioexporter/OTIOExportTask.py b/server_addon/hiero/client/ayon_hiero/api/startup/Python/Startup/otioexporter/OTIOExportTask.py deleted file mode 100644 index d4cb342c72..0000000000 --- a/server_addon/hiero/client/ayon_hiero/api/startup/Python/Startup/otioexporter/OTIOExportTask.py +++ /dev/null @@ -1,79 +0,0 @@ -# -*- coding: utf-8 -*- - -__author__ = "Daniel Flehner Heen" -__credits__ = ["Jakub Jezek", "Daniel Flehner Heen"] - -import os -import hiero.core -from hiero.core import util - -import opentimelineio as otio -from ayon_hiero.api.otio import hiero_export - -class OTIOExportTask(hiero.core.TaskBase): - - def __init__(self, initDict): - """Initialize""" - hiero.core.TaskBase.__init__(self, initDict) - self.otio_timeline = None - - def name(self): - return str(type(self)) - - def startTask(self): - self.otio_timeline = hiero_export.create_otio_timeline() - - def taskStep(self): - return False - - def finishTask(self): - try: - exportPath = self.resolvedExportPath() - - # Check file extension - if not exportPath.lower().endswith(".otio"): - exportPath += ".otio" - - # check export root exists - dirname = os.path.dirname(exportPath) - util.filesystem.makeDirs(dirname) - - # write otio file - hiero_export.write_to_file(self.otio_timeline, exportPath) - - # Catch all exceptions and log error - except Exception as e: - self.setError("failed to write file {f}\n{e}".format( - f=exportPath, - e=e) - ) - - hiero.core.TaskBase.finishTask(self) - - def forcedAbort(self): - pass - - -class OTIOExportPreset(hiero.core.TaskPresetBase): - def __init__(self, name, properties): - """Initialise presets to default values""" - hiero.core.TaskPresetBase.__init__(self, OTIOExportTask, name) - - self.properties()["includeTags"] = hiero_export.include_tags = True - self.properties().update(properties) - - def supportedItems(self): - return hiero.core.TaskPresetBase.kSequence - - def addCustomResolveEntries(self, resolver): - resolver.addResolver( - "{ext}", - "Extension of the file to be output", - lambda keyword, task: "otio" - ) - - def supportsAudio(self): - return True - - -hiero.core.taskRegistry.registerTask(OTIOExportPreset, OTIOExportTask) diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Python/Startup/otioexporter/OTIOExportUI.py b/server_addon/hiero/client/ayon_hiero/api/startup/Python/Startup/otioexporter/OTIOExportUI.py deleted file mode 100644 index 131b385f53..0000000000 --- a/server_addon/hiero/client/ayon_hiero/api/startup/Python/Startup/otioexporter/OTIOExportUI.py +++ /dev/null @@ -1,74 +0,0 @@ -# -*- coding: utf-8 -*- - -__author__ = "Daniel Flehner Heen" -__credits__ = ["Jakub Jezek", "Daniel Flehner Heen"] - -import hiero.ui -from .OTIOExportTask import ( - OTIOExportTask, - OTIOExportPreset -) - -try: - # Hiero >= 11.x - from PySide2 import QtCore - from PySide2.QtWidgets import QCheckBox - from hiero.ui.FnTaskUIFormLayout import TaskUIFormLayout as FormLayout - -except ImportError: - # Hiero <= 10.x - from PySide import QtCore # lint:ok - from PySide.QtGui import QCheckBox, QFormLayout # lint:ok - - FormLayout = QFormLayout # lint:ok - -from ayon_hiero.api.otio import hiero_export - -class OTIOExportUI(hiero.ui.TaskUIBase): - def __init__(self, preset): - """Initialize""" - hiero.ui.TaskUIBase.__init__( - self, - OTIOExportTask, - preset, - "OTIO Exporter" - ) - - def includeMarkersCheckboxChanged(self, state): - # Slot to handle change of checkbox state - hiero_export.include_tags = state == QtCore.Qt.Checked - - def populateUI(self, widget, exportTemplate): - layout = widget.layout() - formLayout = FormLayout() - - # Hiero ~= 10.0v4 - if layout is None: - layout = formLayout - widget.setLayout(layout) - - else: - layout.addLayout(formLayout) - - # Checkboxes for whether the OTIO should contain markers or not - self.includeMarkersCheckbox = QCheckBox() - self.includeMarkersCheckbox.setToolTip( - "Enable to include Tags as markers in the exported OTIO file." - ) - self.includeMarkersCheckbox.setCheckState(QtCore.Qt.Unchecked) - - if self._preset.properties()["includeTags"]: - self.includeMarkersCheckbox.setCheckState(QtCore.Qt.Checked) - - self.includeMarkersCheckbox.stateChanged.connect( - self.includeMarkersCheckboxChanged - ) - - # Add Checkbox to layout - formLayout.addRow("Include Tags:", self.includeMarkersCheckbox) - - -hiero.ui.taskUIRegistry.registerTaskUI( - OTIOExportPreset, - OTIOExportUI -) diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Python/Startup/otioexporter/__init__.py b/server_addon/hiero/client/ayon_hiero/api/startup/Python/Startup/otioexporter/__init__.py deleted file mode 100644 index 33d3fc6c59..0000000000 --- a/server_addon/hiero/client/ayon_hiero/api/startup/Python/Startup/otioexporter/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -from .OTIOExportTask import OTIOExportTask -from .OTIOExportUI import OTIOExportUI - -__all__ = [ - "OTIOExportTask", - "OTIOExportUI" -] diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Python/Startup/project_helpers.py b/server_addon/hiero/client/ayon_hiero/api/startup/Python/Startup/project_helpers.py deleted file mode 100644 index 64b5c37d7b..0000000000 --- a/server_addon/hiero/client/ayon_hiero/api/startup/Python/Startup/project_helpers.py +++ /dev/null @@ -1,246 +0,0 @@ -try: - from PySide.QtGui import * - from PySide.QtCore import * -except: - from PySide2.QtGui import * - from PySide2.QtWidgets import * - from PySide2.QtCore import * - -from hiero.core.util import uniquify, version_get, version_set -import hiero.core -import hiero.ui -import nuke - -# A globally variable for storing the current Project -gTrackedActiveProject = None - -# This selection handler will track changes in items selected/deselected in the Bin/Timeline/Spreadsheet Views - - -def __trackActiveProjectHandler(event): - global gTrackedActiveProject - selection = event.sender.selection() - binSelection = selection - if len(binSelection) > 0 and hasattr(binSelection[0], "project"): - proj = binSelection[0].project() - - # We only store this if its a valid, active User Project - if proj in hiero.core.projects(hiero.core.Project.kUserProjects): - gTrackedActiveProject = proj - - -hiero.core.events.registerInterest( - "kSelectionChanged/kBin", __trackActiveProjectHandler) -hiero.core.events.registerInterest( - "kSelectionChanged/kTimeline", __trackActiveProjectHandler) -hiero.core.events.registerInterest( - "kSelectionChanged/Spreadsheet", __trackActiveProjectHandler) - - -def activeProject(): - """hiero.ui.activeProject() -> returns the current Project - - Note: There is not technically a notion of a "active" Project in Hiero/NukeStudio, as it is a multi-project App. - This method determines what is "active" by going down the following rules... - - # 1 - If the current Viewer (hiero.ui.currentViewer) contains a Clip or Sequence, this item is assumed to give the active Project - # 2 - If nothing is currently in the Viewer, look to the active View, determine project from active selection - # 3 - If no current selection can be determined, fall back to a globally tracked last selection from trackActiveProjectHandler - # 4 - If all those rules fail, fall back to the last project in the list of hiero.core.projects() - - @return: hiero.core.Project""" - global gTrackedActiveProject - activeProject = None - - # Case 1 : Look for what the current Viewr tells us - this might not be what we want, and relies on hiero.ui.currentViewer() being robust. - cv = hiero.ui.currentViewer().player().sequence() - if hasattr(cv, "project"): - activeProject = cv.project() - else: - # Case 2: We can't determine a project from the current Viewer, so try seeing what's selected in the activeView - # Note that currently, if you run activeProject from the Script Editor, the activeView is always None, so this will rarely get used! - activeView = hiero.ui.activeView() - if activeView: - # We can determine an active View.. see what's being worked with - selection = activeView.selection() - - # Handle the case where nothing is selected in the active view - if len(selection) == 0: - # It's possible that there is no selection in a Timeline/Spreadsheet, but these views have "sequence" method, so try that... - if isinstance(hiero.ui.activeView(), (hiero.ui.TimelineEditor, hiero.ui.SpreadsheetView)): - activeSequence = activeView.sequence() - if hasattr(currentItem, "project"): - activeProject = activeSequence.project() - - # The active view has a selection... assume that the first item in the selection has the active Project - else: - currentItem = selection[0] - if hasattr(currentItem, "project"): - activeProject = currentItem.project() - - # Finally, Cases 3 and 4... - if not activeProject: - activeProjects = hiero.core.projects(hiero.core.Project.kUserProjects) - if gTrackedActiveProject in activeProjects: - activeProject = gTrackedActiveProject - else: - activeProject = activeProjects[-1] - - return activeProject - -# Method to get all recent projects - - -def recentProjects(): - """hiero.core.recentProjects() -> Returns a list of paths to recently opened projects - - Hiero stores up to 5 recent projects in uistate.ini with the [recentFile]/# key. - - @return: list of paths to .hrox Projects""" - - appSettings = hiero.core.ApplicationSettings() - recentProjects = [] - for i in range(0, 5): - proj = appSettings.value('recentFile/%i' % i) - if len(proj) > 0: - recentProjects.append(proj) - return recentProjects - -# Method to get recent project by index - - -def recentProject(k=0): - """hiero.core.recentProject(k) -> Returns the recent project path, specified by integer k (0-4) - - @param: k (optional, default = 0) - an integer from 0-4, relating to the index of recent projects. - - @return: hiero.core.Project""" - - appSettings = hiero.core.ApplicationSettings() - proj = appSettings.value('recentFile/%i' % int(k), None) - return proj - -# Method to get open project by index - - -def openRecentProject(k=0): - """hiero.core.openRecentProject(k) -> Opens the most the recent project as listed in the Open Recent list. - - @param: k (optional, default = 0) - an integer from 0-4, relating to the index of recent projects. - @return: hiero.core.Project""" - - appSettings = hiero.core.ApplicationSettings() - proj = appSettings.value('recentFile/%i' % int(k), None) - proj = hiero.core.openProject(proj) - return proj - - -# Duck punch these methods into the relevant ui/core namespaces -hiero.ui.activeProject = activeProject -hiero.core.recentProjects = recentProjects -hiero.core.recentProject = recentProject -hiero.core.openRecentProject = openRecentProject - - -# Method to Save a new Version of the activeHrox Project -class SaveAllProjects(QAction): - - def __init__(self): - QAction.__init__(self, "Save All Projects", None) - self.triggered.connect(self.projectSaveAll) - hiero.core.events.registerInterest( - "kShowContextMenu/kBin", self.eventHandler) - - def projectSaveAll(self): - allProjects = hiero.core.projects() - for proj in allProjects: - try: - proj.save() - print("Saved Project: {} to: {} ".format( - proj.name(), proj.path() - )) - except: - print(( - "Unable to save Project: {} to: {}. " - "Check file permissions.").format( - proj.name(), proj.path())) - - def eventHandler(self, event): - event.menu.addAction(self) - -# For projects with v# in the path name, saves out a new Project with v#+1 - - -class SaveNewProjectVersion(QAction): - - def __init__(self): - QAction.__init__(self, "Save New Version...", None) - self.triggered.connect(self.saveNewVersion) - hiero.core.events.registerInterest( - "kShowContextMenu/kBin", self.eventHandler) - self.selectedProjects = [] - - def saveNewVersion(self): - if len(self.selectedProjects) > 0: - projects = self.selectedProjects - else: - projects = [hiero.ui.activeProject()] - - if len(projects) < 1: - return - - for proj in projects: - oldName = proj.name() - path = proj.path() - v = None - prefix = None - try: - (prefix, v) = version_get(path, "v") - except ValueError as msg: - print(msg) - - if (prefix is not None) and (v is not None): - v = int(v) - newPath = version_set(path, prefix, v, v + 1) - try: - proj.saveAs(newPath) - print("Saved new project version: {} to: {} ".format( - oldName, newPath)) - except: - print(( - "Unable to save Project: {}. Check file permissions." - ).format(oldName)) - else: - newPath = path.replace(".hrox", "_v01.hrox") - answer = nuke.ask( - "%s does not contain a version number.\nDo you want to save as %s?" % (proj, newPath)) - if answer: - try: - proj.saveAs(newPath) - print("Saved new project version: {} to: {} ".format( - oldName, newPath)) - except: - print(( - "Unable to save Project: {}. Check file " - "permissions.").format(oldName)) - - def eventHandler(self, event): - self.selectedProjects = [] - if hasattr(event.sender, "selection") and event.sender.selection() is not None and len(event.sender.selection()) != 0: - selection = event.sender.selection() - self.selectedProjects = uniquify( - [item.project() for item in selection]) - event.menu.addAction(self) - - -# Instantiate the actions -saveAllAct = SaveAllProjects() -saveNewAct = SaveNewProjectVersion() - -fileMenu = hiero.ui.findMenuAction("foundry.menu.file") -importAct = hiero.ui.findMenuAction("foundry.project.importFiles") -hiero.ui.insertMenuAction(saveNewAct, fileMenu.menu(), - before="Import File(s)...") -hiero.ui.insertMenuAction(saveAllAct, fileMenu.menu(), - before="Import File(s)...") -fileMenu.menu().insertSeparator(importAct) diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Python/Startup/selection_tracker.py b/server_addon/hiero/client/ayon_hiero/api/startup/Python/Startup/selection_tracker.py deleted file mode 100644 index a9789cf508..0000000000 --- a/server_addon/hiero/client/ayon_hiero/api/startup/Python/Startup/selection_tracker.py +++ /dev/null @@ -1,9 +0,0 @@ -"""Puts the selection project into "hiero.selection""" - -import hiero - - -def selectionChanged(event): - hiero.selection = event.sender.selection() - -hiero.core.events.registerInterest("kSelectionChanged", selectionChanged) diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Python/Startup/setFrameRate.py b/server_addon/hiero/client/ayon_hiero/api/startup/Python/Startup/setFrameRate.py deleted file mode 100644 index 07ae48aef5..0000000000 --- a/server_addon/hiero/client/ayon_hiero/api/startup/Python/Startup/setFrameRate.py +++ /dev/null @@ -1,166 +0,0 @@ -# setFrameRate - adds a Right-click menu to the Project Bin view, allowing multiple BinItems (Clips/Sequences) to have their frame rates set. -# Install in: ~/.hiero/Python/StartupUI -# Requires 1.5v1 or later - -import hiero.core -import hiero.ui -try: - from PySide.QtGui import * - from PySide.QtCore import * -except: - from PySide2.QtGui import * - from PySide2.QtCore import * - from PySide2.QtWidgets import * - -# Dialog for setting a Custom frame rate. -class SetFrameRateDialog(QDialog): - - def __init__(self,itemSelection=None,parent=None): - super(SetFrameRateDialog, self).__init__(parent) - self.setWindowTitle("Set Custom Frame Rate") - self.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Fixed ) - layout = QFormLayout() - self._itemSelection = itemSelection - - self._frameRateField = QLineEdit() - self._frameRateField.setToolTip("Enter custom frame rate here.") - self._frameRateField.setValidator(QDoubleValidator(1, 99, 3, self)) - self._frameRateField.textChanged.connect(self._textChanged) - layout.addRow("Enter fps: ",self._frameRateField) - - # Standard buttons for Add/Cancel - self._buttonbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) - self._buttonbox.accepted.connect(self.accept) - self._buttonbox.rejected.connect(self.reject) - self._buttonbox.button(QDialogButtonBox.Ok).setEnabled(False) - layout.addRow("",self._buttonbox) - self.setLayout(layout) - - def _updateOkButtonState(self): - # Cancel is always an option but only enable Ok if there is some text. - currentFramerate = float(self.currentFramerateString()) - enableOk = False - enableOk = ((currentFramerate > 0.0) and (currentFramerate <= 250.0)) - print("enabledOk", enableOk) - self._buttonbox.button(QDialogButtonBox.Ok).setEnabled(enableOk) - - def _textChanged(self, newText): - self._updateOkButtonState() - - # Returns the current frame rate as a string - def currentFramerateString(self): - return str(self._frameRateField.text()) - - # Presents the Dialog and sets the Frame rate from a selection - def showDialogAndSetFrameRateFromSelection(self): - - if self._itemSelection is not None: - if self.exec_(): - # For the Undo loop... - - # Construct an TimeBase object for setting the Frame Rate (fps) - fps = hiero.core.TimeBase().fromString(self.currentFramerateString()) - - - # Set the frame rate for the selected BinItmes - for item in self._itemSelection: - item.setFramerate(fps) - return - -# This is just a convenience method for returning QActions with a title, triggered method and icon. -def makeAction(title, method, icon = None): - action = QAction(title,None) - action.setIcon(QIcon(icon)) - - # We do this magic, so that the title string from the action is used to set the frame rate! - def methodWrapper(): - method(title) - - action.triggered.connect( methodWrapper ) - return action - -# Menu which adds a Set Frame Rate Menu to Project Bin view -class SetFrameRateMenu: - - def __init__(self): - self._frameRateMenu = None - self._frameRatesDialog = None - - - # ant: Could use hiero.core.defaultFrameRates() here but messes up with string matching because we seem to mix decimal points - self.frameRates = ["8","12","12.50","15","23.98","24","25","29.97","30","48","50","59.94","60"] - hiero.core.events.registerInterest("kShowContextMenu/kBin", self.binViewEventHandler) - - self.menuActions = [] - - def createFrameRateMenus(self,selection): - selectedClipFPS = [str(bi.activeItem().framerate()) for bi in selection if (isinstance(bi,hiero.core.BinItem) and hasattr(bi,"activeItem"))] - selectedClipFPS = hiero.core.util.uniquify(selectedClipFPS) - sameFrameRate = len(selectedClipFPS)==1 - self.menuActions = [] - for fps in self.frameRates: - if fps in selectedClipFPS: - if sameFrameRate: - self.menuActions+=[makeAction(fps,self.setFrameRateFromMenuSelection, icon="icons:Ticked.png")] - else: - self.menuActions+=[makeAction(fps,self.setFrameRateFromMenuSelection, icon="icons:remove active.png")] - else: - self.menuActions+=[makeAction(fps,self.setFrameRateFromMenuSelection, icon=None)] - - # Now add Custom... menu - self.menuActions += [makeAction( - "Custom...", self.setFrameRateFromMenuSelection, icon=None) - ] - - frameRateMenu = QMenu("Set Frame Rate") - for a in self.menuActions: - frameRateMenu.addAction(a) - - return frameRateMenu - - def setFrameRateFromMenuSelection(self, menuSelectionFPS): - - selectedBinItems = [bi.activeItem() for bi in self._selection if (isinstance(bi,hiero.core.BinItem) and hasattr(bi,"activeItem"))] - currentProject = selectedBinItems[0].project() - - with currentProject.beginUndo("Set Frame Rate"): - if menuSelectionFPS == "Custom...": - self._frameRatesDialog = SetFrameRateDialog(itemSelection = selectedBinItems ) - self._frameRatesDialog.showDialogAndSetFrameRateFromSelection() - - else: - for b in selectedBinItems: - b.setFramerate(hiero.core.TimeBase().fromString(menuSelectionFPS)) - - return - - # This handles events from the Project Bin View - def binViewEventHandler(self,event): - if not hasattr(event.sender, "selection"): - # Something has gone wrong, we should only be here if raised - # by the Bin view which gives a selection. - return - - # Reset the selection to None... - self._selection = None - s = event.sender.selection() - - # Return if there's no Selection. We won't add the Menu. - if s == None: - return - # Filter the selection to BinItems - self._selection = [item for item in s if isinstance(item, hiero.core.BinItem)] - if len(self._selection)==0: - return - # Creating the menu based on items selected, to highlight which frame rates are contained - - self._frameRateMenu = self.createFrameRateMenus(self._selection) - - # Insert the Set Frame Rate Button before the Set Media Colour Transform Action - for action in event.menu.actions(): - if str(action.text()) == "Set Media Colour Transform": - event.menu.insertMenu(action, self._frameRateMenu) - break - -# Instantiate the Menu to get it to register itself. -SetFrameRateMenu = SetFrameRateMenu() \ No newline at end of file diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Python/StartupUI/PimpMySpreadsheet.py b/server_addon/hiero/client/ayon_hiero/api/startup/Python/StartupUI/PimpMySpreadsheet.py deleted file mode 100644 index fcfa24310e..0000000000 --- a/server_addon/hiero/client/ayon_hiero/api/startup/Python/StartupUI/PimpMySpreadsheet.py +++ /dev/null @@ -1,845 +0,0 @@ -# PimpMySpreadsheet 1.0, Antony Nasce, 23/05/13. -# Adds custom spreadsheet columns and right-click menu for setting the Shot Status, and Artist Shot Assignment. -# gStatusTags is a global dictionary of key(status)-value(icon) pairs, which can be overridden with custom icons if required -# Requires Hiero 1.7v2 or later. -# Install Instructions: Copy to ~/.hiero/Python/StartupUI - -import hiero.core -import hiero.ui - -try: - from PySide.QtGui import * - from PySide.QtCore import * -except: - from PySide2.QtGui import * - from PySide2.QtWidgets import * - from PySide2.QtCore import * - -# Set to True, if you wat "Set Status" right-click menu, False if not -kAddStatusMenu = True - -# Set to True, if you wat "Assign Artist" right-click menu, False if not -kAssignArtistMenu = True - -# Global list of Artist Name Dictionaries -# Note: Override this to add different names, icons, department, IDs. -gArtistList = [{ - "artistName": "John Smith", - "artistIcon": "icons:TagActor.png", - "artistDepartment": "3D", - "artistID": 0 -}, { - "artistName": "Savlvador Dali", - "artistIcon": "icons:TagActor.png", - "artistDepartment": "Roto", - "artistID": 1 -}, { - "artistName": "Leonardo Da Vinci", - "artistIcon": "icons:TagActor.png", - "artistDepartment": "Paint", - "artistID": 2 -}, { - "artistName": "Claude Monet", - "artistIcon": "icons:TagActor.png", - "artistDepartment": "Comp", - "artistID": 3 -}, { - "artistName": "Pablo Picasso", - "artistIcon": "icons:TagActor.png", - "artistDepartment": "Animation", - "artistID": 4 -}] - -# Global Dictionary of Status Tags. -# Note: This can be overwritten if you want to add a new status cellType or custom icon -# Override the gStatusTags dictionary by adding your own "Status":"Icon.png" key-value pairs. -# Add new custom keys like so: gStatusTags["For Client"] = "forClient.png" -gStatusTags = { - "Approved": "icons:status/TagApproved.png", - "Unapproved": "icons:status/TagUnapproved.png", - "Ready To Start": "icons:status/TagReadyToStart.png", - "Blocked": "icons:status/TagBlocked.png", - "On Hold": "icons:status/TagOnHold.png", - "In Progress": "icons:status/TagInProgress.png", - "Awaiting Approval": "icons:status/TagAwaitingApproval.png", - "Omitted": "icons:status/TagOmitted.png", - "Final": "icons:status/TagFinal.png" -} - - -# The Custom Spreadsheet Columns -class CustomSpreadsheetColumns(QObject): - """ - A class defining custom columns for Hiero's spreadsheet view. This has a similar, but - slightly simplified, interface to the QAbstractItemModel and QItemDelegate classes. - """ - global gStatusTags - global gArtistList - - # Ideally, we'd set this list on a Per Item basis, but this is expensive for a large mixed selection - standardColourSpaces = [ - "linear", "sRGB", "rec709", "Cineon", "Gamma1.8", "Gamma2.2", - "Panalog", "REDLog", "ViperLog" - ] - arriColourSpaces = [ - "Video - Rec709", "LogC - Camera Native", "Video - P3", "ACES", - "LogC - Film", "LogC - Wide Gamut" - ] - r3dColourSpaces = [ - "Linear", "Rec709", "REDspace", "REDlog", "PDlog685", "PDlog985", - "CustomPDlog", "REDgamma", "SRGB", "REDlogFilm", "REDgamma2", - "REDgamma3" - ] - gColourSpaces = standardColourSpaces + arriColourSpaces + r3dColourSpaces - - currentView = hiero.ui.activeView() - - # This is the list of Columns available - gCustomColumnList = [ - { - "name": "Tags", - "cellType": "readonly" - }, - { - "name": "Colourspace", - "cellType": "dropdown" - }, - { - "name": "Notes", - "cellType": "readonly" - }, - { - "name": "FileType", - "cellType": "readonly" - }, - { - "name": "Shot Status", - "cellType": "dropdown" - }, - { - "name": "Thumbnail", - "cellType": "readonly" - }, - { - "name": "MediaType", - "cellType": "readonly" - }, - { - "name": "Width", - "cellType": "readonly" - }, - { - "name": "Height", - "cellType": "readonly" - }, - { - "name": "Pixel Aspect", - "cellType": "readonly" - }, - { - "name": "Artist", - "cellType": "dropdown" - }, - { - "name": "Department", - "cellType": "readonly" - }, - ] - - def numColumns(self): - """ - Return the number of custom columns in the spreadsheet view - """ - return len(self.gCustomColumnList) - - def columnName(self, column): - """ - Return the name of a custom column - """ - return self.gCustomColumnList[column]["name"] - - def getTagsString(self, item): - """ - Convenience method for returning all the Notes in a Tag as a string - """ - tagNames = [] - tags = item.tags() - for tag in tags: - tagNames += [tag.name()] - tagNameString = ','.join(tagNames) - return tagNameString - - def getNotes(self, item): - """ - Convenience method for returning all the Notes in a Tag as a string - """ - notes = "" - tags = item.tags() - for tag in tags: - note = tag.note() - if len(note) > 0: - notes += tag.note() + ', ' - return notes[:-2] - - def getData(self, row, column, item): - """ - Return the data in a cell - """ - currentColumn = self.gCustomColumnList[column] - if currentColumn["name"] == "Tags": - return self.getTagsString(item) - - if currentColumn["name"] == "Colourspace": - try: - colTransform = item.sourceMediaColourTransform() - except: - colTransform = "--" - return colTransform - - if currentColumn["name"] == "Notes": - try: - note = self.getNotes(item) - except: - note = "" - return note - - if currentColumn["name"] == "FileType": - fileType = "--" - M = item.source().mediaSource().metadata() - if M.hasKey("foundry.source.type"): - fileType = M.value("foundry.source.type") - elif M.hasKey("media.input.filereader"): - fileType = M.value("media.input.filereader") - return fileType - - if currentColumn["name"] == "Shot Status": - status = item.status() - if not status: - status = "--" - return str(status) - - if currentColumn["name"] == "MediaType": - M = item.mediaType() - return str(M).split("MediaType")[-1].replace(".k", "") - - if currentColumn["name"] == "Thumbnail": - return str(item.eventNumber()) - - if currentColumn["name"] == "Width": - return str(item.source().format().width()) - - if currentColumn["name"] == "Height": - return str(item.source().format().height()) - - if currentColumn["name"] == "Pixel Aspect": - return str(item.source().format().pixelAspect()) - - if currentColumn["name"] == "Artist": - if item.artist(): - name = item.artist()["artistName"] - return name - else: - return "--" - - if currentColumn["name"] == "Department": - if item.artist(): - dep = item.artist()["artistDepartment"] - return dep - else: - return "--" - - return "" - - def setData(self, row, column, item, data): - """ - Set the data in a cell - unused in this example - """ - - return None - - def getTooltip(self, row, column, item): - """ - Return the tooltip for a cell - """ - currentColumn = self.gCustomColumnList[column] - if currentColumn["name"] == "Tags": - return str([item.name() for item in item.tags()]) - - if currentColumn["name"] == "Notes": - return str(self.getNotes(item)) - return "" - - def getFont(self, row, column, item): - """ - Return the tooltip for a cell - """ - return None - - def getBackground(self, row, column, item): - """ - Return the background colour for a cell - """ - if not item.source().mediaSource().isMediaPresent(): - return QColor(80, 20, 20) - return None - - def getForeground(self, row, column, item): - """ - Return the text colour for a cell - """ - #if column == 1: - # return QColor(255, 64, 64) - return None - - def getIcon(self, row, column, item): - """ - Return the icon for a cell - """ - currentColumn = self.gCustomColumnList[column] - if currentColumn["name"] == "Colourspace": - return QIcon("icons:LUT.png") - - if currentColumn["name"] == "Shot Status": - status = item.status() - if status: - return QIcon(gStatusTags[status]) - - if currentColumn["name"] == "MediaType": - mediaType = item.mediaType() - if mediaType == hiero.core.TrackItem.kVideo: - return QIcon("icons:VideoOnly.png") - elif mediaType == hiero.core.TrackItem.kAudio: - return QIcon("icons:AudioOnly.png") - - if currentColumn["name"] == "Artist": - try: - return QIcon(item.artist()["artistIcon"]) - except: - return None - return None - - def getSizeHint(self, row, column, item): - """ - Return the size hint for a cell - """ - currentColumnName = self.gCustomColumnList[column]["name"] - - if currentColumnName == "Thumbnail": - return QSize(90, 50) - - return QSize(50, 50) - - def paintCell(self, row, column, item, painter, option): - """ - Paint a custom cell. Return True if the cell was painted, or False to continue - with the default cell painting. - """ - currentColumn = self.gCustomColumnList[column] - if currentColumn["name"] == "Tags": - if option.state & QStyle.State_Selected: - painter.fillRect(option.rect, option.palette.highlight()) - iconSize = 20 - r = QRect(option.rect.x(), - option.rect.y() + (option.rect.height() - iconSize) / 2, - iconSize, iconSize) - tags = item.tags() - if len(tags) > 0: - painter.save() - painter.setClipRect(option.rect) - for tag in item.tags(): - M = tag.metadata() - if not (M.hasKey("tag.status") - or M.hasKey("tag.artistID")): - QIcon(tag.icon()).paint(painter, r, Qt.AlignLeft) - r.translate(r.width() + 2, 0) - painter.restore() - return True - - if currentColumn["name"] == "Thumbnail": - imageView = None - pen = QPen() - r = QRect(option.rect.x() + 2, (option.rect.y() + - (option.rect.height() - 46) / 2), - 85, 46) - if not item.source().mediaSource().isMediaPresent(): - imageView = QImage("icons:Offline.png") - pen.setColor(QColor(Qt.red)) - - if item.mediaType() == hiero.core.TrackItem.MediaType.kAudio: - imageView = QImage("icons:AudioOnly.png") - #pen.setColor(QColor(Qt.green)) - painter.fillRect(r, QColor(45, 59, 45)) - - if option.state & QStyle.State_Selected: - painter.fillRect(option.rect, option.palette.highlight()) - - tags = item.tags() - painter.save() - painter.setClipRect(option.rect) - - if not imageView: - try: - imageView = item.thumbnail(item.sourceIn()) - pen.setColor(QColor(20, 20, 20)) - # If we're here, we probably have a TC error, no thumbnail, so get it from the source Clip... - except: - pen.setColor(QColor(Qt.red)) - - if not imageView: - try: - imageView = item.source().thumbnail() - pen.setColor(QColor(Qt.yellow)) - except: - imageView = QImage("icons:Offline.png") - pen.setColor(QColor(Qt.red)) - - QIcon(QPixmap.fromImage(imageView)).paint(painter, r, - Qt.AlignCenter) - painter.setPen(pen) - painter.drawRoundedRect(r, 1, 1) - painter.restore() - return True - - return False - - def createEditor(self, row, column, item, view): - """ - Create an editing widget for a custom cell - """ - self.currentView = view - - currentColumn = self.gCustomColumnList[column] - if currentColumn["cellType"] == "readonly": - cle = QLabel() - cle.setEnabled(False) - cle.setVisible(False) - return cle - - if currentColumn["name"] == "Colourspace": - cb = QComboBox() - for colourspace in self.gColourSpaces: - cb.addItem(colourspace) - cb.currentIndexChanged.connect(self.colourspaceChanged) - return cb - - if currentColumn["name"] == "Shot Status": - cb = QComboBox() - cb.addItem("") - for key in gStatusTags.keys(): - cb.addItem(QIcon(gStatusTags[key]), key) - cb.addItem("--") - cb.currentIndexChanged.connect(self.statusChanged) - - return cb - - if currentColumn["name"] == "Artist": - cb = QComboBox() - cb.addItem("") - for artist in gArtistList: - cb.addItem(artist["artistName"]) - cb.addItem("--") - cb.currentIndexChanged.connect(self.artistNameChanged) - return cb - return None - - def setModelData(self, row, column, item, editor): - return False - - def dropMimeData(self, row, column, item, data, items): - """ - Handle a drag and drop operation - adds a Dragged Tag to the shot - """ - for thing in items: - if isinstance(thing, hiero.core.Tag): - item.addTag(thing) - return None - - def colourspaceChanged(self, index): - """ - This method is called when Colourspace widget changes index. - """ - index = self.sender().currentIndex() - colourspace = self.gColourSpaces[index] - selection = self.currentView.selection() - project = selection[0].project() - with project.beginUndo("Set Colourspace"): - items = [ - item for item in selection - if (item.mediaType() == hiero.core.TrackItem.MediaType.kVideo) - ] - for trackItem in items: - trackItem.setSourceMediaColourTransform(colourspace) - - def statusChanged(self, arg): - """ - This method is called when Shot Status widget changes index. - """ - view = hiero.ui.activeView() - selection = view.selection() - status = self.sender().currentText() - project = selection[0].project() - with project.beginUndo("Set Status"): - # A string of "--" characters denotes clear the status - if status != "--": - for trackItem in selection: - trackItem.setStatus(status) - else: - for trackItem in selection: - tTags = trackItem.tags() - for tag in tTags: - if tag.metadata().hasKey("tag.status"): - trackItem.removeTag(tag) - break - - def artistNameChanged(self, arg): - """ - This method is called when Artist widget changes index. - """ - view = hiero.ui.activeView() - selection = view.selection() - name = self.sender().currentText() - project = selection[0].project() - with project.beginUndo("Assign Artist"): - # A string of "--" denotes clear the assignee... - if name != "--": - for trackItem in selection: - trackItem.setArtistByName(name) - else: - for trackItem in selection: - tTags = trackItem.tags() - for tag in tTags: - if tag.metadata().hasKey("tag.artistID"): - trackItem.removeTag(tag) - break - - -def _getArtistFromID(self, artistID): - """ getArtistFromID -> returns an artist dictionary, by their given ID""" - global gArtistList - artist = [ - element for element in gArtistList - if element["artistID"] == int(artistID) - ] - if not artist: - return None - return artist[0] - - -def _getArtistFromName(self, artistName): - """ getArtistFromID -> returns an artist dictionary, by their given ID """ - global gArtistList - artist = [ - element for element in gArtistList - if element["artistName"] == artistName - ] - if not artist: - return None - return artist[0] - - -def _artist(self): - """_artist -> Returns the artist dictionary assigned to this shot""" - artist = None - tags = self.tags() - for tag in tags: - if tag.metadata().hasKey("tag.artistID"): - artistID = tag.metadata().value("tag.artistID") - artist = self.getArtistFromID(artistID) - return artist - - -def _updateArtistTag(self, artistDict): - # A shot will only have one artist assigned. Check if one exists and set accordingly - - artistTag = None - tags = self.tags() - for tag in tags: - if tag.metadata().hasKey("tag.artistID"): - artistTag = tag - break - - if not artistTag: - artistTag = hiero.core.Tag("Artist") - artistTag.setIcon(artistDict["artistIcon"]) - artistTag.metadata().setValue("tag.artistID", - str(artistDict["artistID"])) - artistTag.metadata().setValue("tag.artistName", - str(artistDict["artistName"])) - artistTag.metadata().setValue("tag.artistDepartment", - str(artistDict["artistDepartment"])) - self.sequence().editFinished() - self.addTag(artistTag) - self.sequence().editFinished() - return - - artistTag.setIcon(artistDict["artistIcon"]) - artistTag.metadata().setValue("tag.artistID", str(artistDict["artistID"])) - artistTag.metadata().setValue("tag.artistName", - str(artistDict["artistName"])) - artistTag.metadata().setValue("tag.artistDepartment", - str(artistDict["artistDepartment"])) - self.sequence().editFinished() - return - - -def _setArtistByName(self, artistName): - """ setArtistByName(artistName) -> sets the artist tag on a TrackItem by a given artistName string""" - global gArtistList - - artist = self.getArtistFromName(artistName) - if not artist: - print(( - "Artist name: {} was not found in " - "the gArtistList.").format(artistName)) - return - - # Do the update. - self.updateArtistTag(artist) - - -def _setArtistByID(self, artistID): - """ setArtistByID(artistID) -> sets the artist tag on a TrackItem by a given artistID integer""" - global gArtistList - - artist = self.getArtistFromID(artistID) - if not artist: - print("Artist name: {} was not found in the gArtistList.".format( - artistID)) - return - - # Do the update. - self.updateArtistTag(artist) - - -# Inject status getter and setter methods into hiero.core.TrackItem -hiero.core.TrackItem.artist = _artist -hiero.core.TrackItem.setArtistByName = _setArtistByName -hiero.core.TrackItem.setArtistByID = _setArtistByID -hiero.core.TrackItem.getArtistFromName = _getArtistFromName -hiero.core.TrackItem.getArtistFromID = _getArtistFromID -hiero.core.TrackItem.updateArtistTag = _updateArtistTag - - -def _status(self): - """status -> Returns the Shot status. None if no Status is set.""" - - status = None - tags = self.tags() - for tag in tags: - if tag.metadata().hasKey("tag.status"): - status = tag.metadata().value("tag.status") - return status - - -def _setStatus(self, status): - """setShotStatus(status) -> Method to set the Status of a Shot. - Adds a special kind of status Tag to a TrackItem - Example: myTrackItem.setStatus("Final") - - @param status - a string, corresponding to the Status name - """ - global gStatusTags - - # Get a valid Tag object from the Global list of statuses - if status not in gStatusTags.keys(): - print("Status requested was not a valid Status string.") - return - - # A shot should only have one status. Check if one exists and set accordingly - statusTag = None - tags = self.tags() - for tag in tags: - if tag.metadata().hasKey("tag.status"): - statusTag = tag - break - - if not statusTag: - statusTag = hiero.core.Tag("Status") - statusTag.setIcon(gStatusTags[status]) - statusTag.metadata().setValue("tag.status", status) - self.addTag(statusTag) - - statusTag.setIcon(gStatusTags[status]) - statusTag.metadata().setValue("tag.status", status) - - self.sequence().editFinished() - return - - -# Inject status getter and setter methods into hiero.core.TrackItem -hiero.core.TrackItem.setStatus = _setStatus -hiero.core.TrackItem.status = _status - - -# This is a convenience method for returning QActions with a triggered method based on the title string -def titleStringTriggeredAction(title, method, icon=None): - action = QAction(title, None) - action.setIcon(QIcon(icon)) - - # We do this magic, so that the title string from the action is used to set the status - def methodWrapper(): - method(title) - - action.triggered.connect(methodWrapper) - return action - - -# Menu which adds a Set Status Menu to Timeline and Spreadsheet Views -class SetStatusMenu(QMenu): - def __init__(self): - QMenu.__init__(self, "Set Status", None) - - global gStatusTags - self.statuses = gStatusTags - self._statusActions = self.createStatusMenuActions() - - # Add the Actions to the Menu. - for act in self.menuActions: - self.addAction(act) - - hiero.core.events.registerInterest("kShowContextMenu/kTimeline", - self.eventHandler) - hiero.core.events.registerInterest("kShowContextMenu/kSpreadsheet", - self.eventHandler) - - def createStatusMenuActions(self): - self.menuActions = [] - for status in self.statuses: - self.menuActions += [ - titleStringTriggeredAction( - status, - self.setStatusFromMenuSelection, - icon=gStatusTags[status]) - ] - - def setStatusFromMenuSelection(self, menuSelectionStatus): - selectedShots = [ - item for item in self._selection - if (isinstance(item, hiero.core.TrackItem)) - ] - selectedTracks = [ - item for item in self._selection - if (isinstance(item, (hiero.core.VideoTrack, - hiero.core.AudioTrack))) - ] - - # If we have a Track Header Selection, no shots could be selected, so create shotSelection list - if len(selectedTracks) >= 1: - for track in selectedTracks: - selectedShots += [ - item for item in track.items() - if (isinstance(item, hiero.core.TrackItem)) - ] - - # It's possible no shots exist on the Track, in which case nothing is required - if len(selectedShots) == 0: - return - - currentProject = selectedShots[0].project() - - with currentProject.beginUndo("Set Status"): - # Shots selected - for shot in selectedShots: - shot.setStatus(menuSelectionStatus) - - # This handles events from the Project Bin View - def eventHandler(self, event): - if not hasattr(event.sender, "selection"): - # Something has gone wrong, we should only be here if raised - # by the Timeline/Spreadsheet view which gives a selection. - return - - # Set the current selection - self._selection = event.sender.selection() - - # Return if there's no Selection. We won't add the Menu. - if len(self._selection) == 0: - return - - event.menu.addMenu(self) - - -# Menu which adds a Set Status Menu to Timeline and Spreadsheet Views -class AssignArtistMenu(QMenu): - def __init__(self): - QMenu.__init__(self, "Assign Artist", None) - - global gArtistList - self.artists = gArtistList - self._artistsActions = self.createAssignArtistMenuActions() - - # Add the Actions to the Menu. - for act in self.menuActions: - self.addAction(act) - - hiero.core.events.registerInterest("kShowContextMenu/kTimeline", - self.eventHandler) - hiero.core.events.registerInterest("kShowContextMenu/kSpreadsheet", - self.eventHandler) - - def createAssignArtistMenuActions(self): - self.menuActions = [] - for artist in self.artists: - self.menuActions += [ - titleStringTriggeredAction( - artist["artistName"], - self.setArtistFromMenuSelection, - icon=artist["artistIcon"]) - ] - - def setArtistFromMenuSelection(self, menuSelectionArtist): - selectedShots = [ - item for item in self._selection - if (isinstance(item, hiero.core.TrackItem)) - ] - selectedTracks = [ - item for item in self._selection - if (isinstance(item, (hiero.core.VideoTrack, - hiero.core.AudioTrack))) - ] - - # If we have a Track Header Selection, no shots could be selected, so create shotSelection list - if len(selectedTracks) >= 1: - for track in selectedTracks: - selectedShots += [ - item for item in track.items() - if (isinstance(item, hiero.core.TrackItem)) - ] - - # It's possible no shots exist on the Track, in which case nothing is required - if len(selectedShots) == 0: - return - - currentProject = selectedShots[0].project() - - with currentProject.beginUndo("Assign Artist"): - # Shots selected - for shot in selectedShots: - shot.setArtistByName(menuSelectionArtist) - - # This handles events from the Project Bin View - def eventHandler(self, event): - if not hasattr(event.sender, "selection"): - # Something has gone wrong, we should only be here if raised - # by the Timeline/Spreadsheet view which gives a selection. - return - - # Set the current selection - self._selection = event.sender.selection() - - # Return if there's no Selection. We won't add the Menu. - if len(self._selection) == 0: - return - - event.menu.addMenu(self) - - -# Add the "Set Status" context menu to Timeline and Spreadsheet -if kAddStatusMenu: - setStatusMenu = SetStatusMenu() - -if kAssignArtistMenu: - assignArtistMenu = AssignArtistMenu() - -# Register our custom columns -hiero.ui.customColumn = CustomSpreadsheetColumns() diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Python/StartupUI/Purge.py b/server_addon/hiero/client/ayon_hiero/api/startup/Python/StartupUI/Purge.py deleted file mode 100644 index 7b3cb11be3..0000000000 --- a/server_addon/hiero/client/ayon_hiero/api/startup/Python/StartupUI/Purge.py +++ /dev/null @@ -1,142 +0,0 @@ -# Purge Unused Clips - Removes any unused Clips from a Project -# Usage: Copy to ~/.hiero/Python/StartupUI -# Demonstrates the use of hiero.core.find_items module. -# Usage: Right-click on an item in the Bin View > "Purge Unused Clips" -# Result: Any Clips not used in a Sequence in the active project will be removed -# Requires Hiero 1.5v1 or later. -# Version 1.1 - -import hiero -import hiero.core.find_items -try: - from PySide.QtGui import * - from PySide.QtCore import * -except: - from PySide2.QtGui import * - from PySide2.QtWidgets import * - from PySide2.QtCore import * - - -class PurgeUnusedAction(QAction): - def __init__(self): - QAction.__init__(self, "Purge Unused Clips", None) - self.triggered.connect(self.PurgeUnused) - hiero.core.events.registerInterest("kShowContextMenu/kBin", - self.eventHandler) - self.setIcon(QIcon("icons:TagDelete.png")) - - # Method to return whether a Bin is empty... - def binIsEmpty(self, b): - numBinItems = 0 - bItems = b.items() - empty = False - - if len(bItems) == 0: - empty = True - return empty - else: - for b in bItems: - if isinstance(b, hiero.core.BinItem) or isinstance( - b, hiero.core.Bin): - numBinItems += 1 - if numBinItems == 0: - empty = True - - return empty - - def PurgeUnused(self): - - #Get selected items - item = self.selectedItem - proj = item.project() - - # Build a list of Projects - SEQS = hiero.core.findItems(proj, "Sequences") - - # Build a list of Clips - CLIPSTOREMOVE = hiero.core.findItems(proj, "Clips") - - if len(SEQS) == 0: - # Present Dialog Asking if User wants to remove Clips - msgBox = QMessageBox() - msgBox.setText("Purge Unused Clips") - msgBox.setInformativeText( - "You have no Sequences in this Project. Do you want to remove all Clips (%i) from Project: %s?" - % (len(CLIPSTOREMOVE), proj.name())) - msgBox.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel) - msgBox.setDefaultButton(QMessageBox.Ok) - ret = msgBox.exec_() - if ret == QMessageBox.Cancel: - print("Not purging anything.") - elif ret == QMessageBox.Ok: - with proj.beginUndo("Purge Unused Clips"): - BINS = [] - for clip in CLIPSTOREMOVE: - BI = clip.binItem() - B = BI.parentBin() - BINS += [B] - print("Removing: {}".format(BI)) - try: - B.removeItem(BI) - except: - print("Unable to remove: {}".format(BI)) - return - - # For each sequence, iterate through each track Item, see if the Clip is in the CLIPS list. - # Remaining items in CLIPS will be removed - - for seq in SEQS: - - #Loop through selected and make folders - for track in seq: - for trackitem in track: - - if trackitem.source() in CLIPSTOREMOVE: - CLIPSTOREMOVE.remove(trackitem.source()) - - # Present Dialog Asking if User wants to remove Clips - msgBox = QMessageBox() - msgBox.setText("Purge Unused Clips") - msgBox.setInformativeText("Remove %i unused Clips from Project %s?" % - (len(CLIPSTOREMOVE), proj.name())) - msgBox.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel) - msgBox.setDefaultButton(QMessageBox.Ok) - ret = msgBox.exec_() - - if ret == QMessageBox.Cancel: - print("Cancel") - return - elif ret == QMessageBox.Ok: - BINS = [] - with proj.beginUndo("Purge Unused Clips"): - # Delete the rest of the Clips - for clip in CLIPSTOREMOVE: - BI = clip.binItem() - B = BI.parentBin() - BINS += [B] - print("Removing: {}".format(BI)) - try: - B.removeItem(BI) - except: - print("Unable to remove: {}".format(BI)) - - def eventHandler(self, event): - if not hasattr(event.sender, "selection"): - # Something has gone wrong, we shouldn't only be here if raised - # by the Bin view which will give a selection. - return - - self.selectedItem = None - s = event.sender.selection() - - if len(s) >= 1: - self.selectedItem = s[0] - title = "Purge Unused Clips" - self.setText(title) - event.menu.addAction(self) - - return - - -# Instantiate the action to get it to register itself. -PurgeUnusedAction = PurgeUnusedAction() diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Python/StartupUI/nukeStyleKeyboardShortcuts.py b/server_addon/hiero/client/ayon_hiero/api/startup/Python/StartupUI/nukeStyleKeyboardShortcuts.py deleted file mode 100644 index 4172b2ff85..0000000000 --- a/server_addon/hiero/client/ayon_hiero/api/startup/Python/StartupUI/nukeStyleKeyboardShortcuts.py +++ /dev/null @@ -1,34 +0,0 @@ -# nukeStyleKeyboardShortcuts, v1, 30/07/2012, Ant Nasce. -# A few Nuke-Style File menu shortcuts for those whose muscle memory has set in... -# Usage: Copy this file to ~/.hiero/Python/StartupUI/ - -import hiero.ui -try: - from PySide.QtGui import * - from PySide.QtCore import * -except: - from PySide2.QtGui import * - from PySide2.QtWidgets import * - from PySide2.QtCore import * - -#---------------------------------------------- -a = hiero.ui.findMenuAction('Import File(s)...') -# Note: You probably best to make this 'Ctrl+R' - currently conflicts with "Red" in the Viewer! -a.setShortcut(QKeySequence("R")) -#---------------------------------------------- -a = hiero.ui.findMenuAction('Import Folder(s)...') -a.setShortcut(QKeySequence('Shift+R')) -#---------------------------------------------- -a = hiero.ui.findMenuAction("Import EDL/XML/AAF...") -a.setShortcut(QKeySequence('Ctrl+Shift+O')) -#---------------------------------------------- -a = hiero.ui.findMenuAction("Metadata View") -a.setShortcut(QKeySequence("I")) -#---------------------------------------------- -a = hiero.ui.findMenuAction("Edit Settings") -a.setShortcut(QKeySequence("S")) -#---------------------------------------------- -a = hiero.ui.findMenuAction("Monitor Output") -if a: - a.setShortcut(QKeySequence('Ctrl+U')) -#---------------------------------------------- diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Python/StartupUI/otioimporter/OTIOImport.py b/server_addon/hiero/client/ayon_hiero/api/startup/Python/StartupUI/otioimporter/OTIOImport.py deleted file mode 100644 index d2fe608d99..0000000000 --- a/server_addon/hiero/client/ayon_hiero/api/startup/Python/StartupUI/otioimporter/OTIOImport.py +++ /dev/null @@ -1,424 +0,0 @@ -# MIT License -# -# Copyright (c) 2018 Daniel Flehner Heen (Storm Studios) -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -import os -import sys -import hiero.core -import hiero.ui - -try: - from urllib import unquote - -except ImportError: - from urllib.parse import unquote # lint:ok - -import opentimelineio as otio - - -def get_transition_type(otio_item, otio_track): - _in, _out = otio_track.neighbors_of(otio_item) - - if isinstance(_in, otio.schema.Gap): - _in = None - - if isinstance(_out, otio.schema.Gap): - _out = None - - if _in and _out: - return "dissolve" - - elif _in and not _out: - return "fade_out" - - elif not _in and _out: - return "fade_in" - - else: - return "unknown" - - -def find_trackitem(name, hiero_track): - for item in hiero_track.items(): - if item.name() == name: - return item - - return None - - -def get_neighboring_trackitems(otio_item, otio_track, hiero_track): - _in, _out = otio_track.neighbors_of(otio_item) - trackitem_in = None - trackitem_out = None - - if _in: - trackitem_in = find_trackitem(_in.name, hiero_track) - - if _out: - trackitem_out = find_trackitem(_out.name, hiero_track) - - return trackitem_in, trackitem_out - - -def apply_transition(otio_track, otio_item, track): - # Figure out type of transition - transition_type = get_transition_type(otio_item, otio_track) - - # Figure out track kind for getattr below - if isinstance(track, hiero.core.VideoTrack): - kind = "" - - else: - kind = "Audio" - - try: - # Gather TrackItems involved in transition - item_in, item_out = get_neighboring_trackitems( - otio_item, - otio_track, - track - ) - - # Create transition object - if transition_type == "dissolve": - transition_func = getattr( - hiero.core.Transition, - "create{kind}DissolveTransition".format(kind=kind) - ) - - transition = transition_func( - item_in, - item_out, - otio_item.in_offset.value, - otio_item.out_offset.value, - ) - - elif transition_type == "fade_in": - transition_func = getattr( - hiero.core.Transition, - 'create{kind}FadeInTransition'.format(kind=kind) - ) - transition = transition_func(item_out, otio_item.out_offset.value) - - elif transition_type == "fade_out": - transition_func = getattr( - hiero.core.Transition, - "create{kind}FadeOutTransition".format(kind=kind) - ) - transition = transition_func(item_in, otio_item.in_offset.value) - - else: - # Unknown transition - return - - # Apply transition to track - track.addTransition(transition) - - except Exception as e: - sys.stderr.write( - 'Unable to apply transition "{t}": "{e}"\n'.format( - t=otio_item, e=e - ) - ) - - -def prep_url(url_in): - url = unquote(url_in) - - if url.startswith("file://localhost/"): - return url.replace("file://localhost/", "") - - if url.startswith(os.sep): - url = url[1:] - - return url - - -def create_offline_mediasource(otio_clip, path=None): - hiero_rate = hiero.core.TimeBase(otio_clip.source_range.start_time.rate) - - if isinstance(otio_clip.media_reference, otio.schema.ExternalReference): - source_range = otio_clip.available_range() - - else: - source_range = otio_clip.source_range - - if path is None: - path = otio_clip.name - - media = hiero.core.MediaSource.createOfflineVideoMediaSource( - prep_url(path), - source_range.start_time.value, - source_range.duration.value, - hiero_rate, - source_range.start_time.value, - ) - - return media - - -def load_otio(otio_file): - otio_timeline = otio.adapters.read_from_file(otio_file) - build_sequence(otio_timeline) - - -marker_color_map = { - "PINK": "Magenta", - "RED": "Red", - "ORANGE": "Yellow", - "YELLOW": "Yellow", - "GREEN": "Green", - "CYAN": "Cyan", - "BLUE": "Blue", - "PURPLE": "Magenta", - "MAGENTA": "Magenta", - "BLACK": "Blue", - "WHITE": "Green", - "MINT": "Cyan", -} - - -def get_tag(tagname, tagsbin): - for tag in tagsbin.items(): - if tag.name() == tagname: - return tag - - if isinstance(tag, hiero.core.Bin): - tag = get_tag(tagname, tag) - - if tag is not None: - return tag - - return None - - -def add_metadata(metadata, hiero_item): - for key, value in metadata.items(): - if isinstance(value, dict): - add_metadata(value, hiero_item) - continue - - if value is not None: - if not key.startswith("tag."): - key = "tag." + key - - hiero_item.metadata().setValue(key, str(value)) - - -def add_markers(otio_item, hiero_item, tagsbin): - if isinstance(otio_item, (otio.schema.Stack, otio.schema.Clip)): - markers = otio_item.markers - - elif isinstance(otio_item, otio.schema.Timeline): - markers = otio_item.tracks.markers - - else: - markers = [] - - for marker in markers: - marker_color = marker.color - - _tag = get_tag(marker.name, tagsbin) - if _tag is None: - _tag = get_tag(marker_color_map[marker_color], tagsbin) - - if _tag is None: - _tag = hiero.core.Tag(marker_color_map[marker.color]) - - tag = hiero_item.addTag(_tag) - tag.setName(marker.name or marker_color_map[marker_color]) - - # Add metadata - add_metadata(marker.metadata, tag) - - -def create_track(otio_track, tracknum, track_kind): - # Add track kind when dealing with nested stacks - if isinstance(otio_track, otio.schema.Stack): - otio_track.kind = track_kind - - # Create a Track - if otio_track.kind == otio.schema.TrackKind.Video: - track = hiero.core.VideoTrack( - otio_track.name or "Video{n}".format(n=tracknum) - ) - - else: - track = hiero.core.AudioTrack( - otio_track.name or "Audio{n}".format(n=tracknum) - ) - - return track - - -def create_clip(otio_clip): - # Create MediaSource - otio_media = otio_clip.media_reference - if isinstance(otio_media, otio.schema.ExternalReference): - url = prep_url(otio_media.target_url) - media = hiero.core.MediaSource(url) - if media.isOffline(): - media = create_offline_mediasource(otio_clip, url) - - else: - media = create_offline_mediasource(otio_clip) - - # Create Clip - clip = hiero.core.Clip(media) - - return clip - - -def create_trackitem(playhead, track, otio_clip, clip, tagsbin): - source_range = otio_clip.source_range - - trackitem = track.createTrackItem(otio_clip.name) - trackitem.setPlaybackSpeed(source_range.start_time.rate) - trackitem.setSource(clip) - - # Check for speed effects and adjust playback speed accordingly - for effect in otio_clip.effects: - if isinstance(effect, otio.schema.LinearTimeWarp): - trackitem.setPlaybackSpeed( - trackitem.playbackSpeed() * effect.time_scalar - ) - - # If reverse playback speed swap source in and out - if trackitem.playbackSpeed() < 0: - source_out = source_range.start_time.value - source_in = ( - source_range.start_time.value + source_range.duration.value - ) - 1 - timeline_in = playhead + source_out - timeline_out = (timeline_in + source_range.duration.value) - 1 - else: - # Normal playback speed - source_in = source_range.start_time.value - source_out = ( - source_range.start_time.value + source_range.duration.value - ) - 1 - timeline_in = playhead - timeline_out = (timeline_in + source_range.duration.value) - 1 - - # Set source and timeline in/out points - trackitem.setSourceIn(source_in) - trackitem.setSourceOut(source_out) - trackitem.setTimelineIn(timeline_in) - trackitem.setTimelineOut(timeline_out) - - # Add markers - add_markers(otio_clip, trackitem, tagsbin) - - return trackitem - - -def build_sequence( - otio_timeline, project=None, sequence=None, track_kind=None -): - - if project is None: - if sequence: - project = sequence.project() - - else: - # Per version 12.1v2 there is no way of getting active project - project = hiero.core.projects(hiero.core.Project.kUserProjects)[-1] - - projectbin = project.clipsBin() - - if not sequence: - # Create a Sequence - sequence = hiero.core.Sequence(otio_timeline.name or "OTIOSequence") - - # Set sequence settings from otio timeline if available - if hasattr(otio_timeline, "global_start_time"): - if otio_timeline.global_start_time: - start_time = otio_timeline.global_start_time - sequence.setFramerate(start_time.rate) - sequence.setTimecodeStart(start_time.value) - - # Create a Bin to hold clips - projectbin.addItem(hiero.core.BinItem(sequence)) - - sequencebin = hiero.core.Bin(sequence.name()) - projectbin.addItem(sequencebin) - - else: - sequencebin = projectbin - - # Get tagsBin - tagsbin = hiero.core.project("Tag Presets").tagsBin() - - # Add timeline markers - add_markers(otio_timeline, sequence, tagsbin) - - if isinstance(otio_timeline, otio.schema.Timeline): - tracks = otio_timeline.tracks - - else: - tracks = [otio_timeline] - - for tracknum, otio_track in enumerate(tracks): - playhead = 0 - _transitions = [] - - # Add track to sequence - track = create_track(otio_track, tracknum, track_kind) - sequence.addTrack(track) - - # iterate over items in track - for itemnum, otio_clip in enumerate(otio_track): - if isinstance(otio_clip, otio.schema.Stack): - bar = hiero.ui.mainWindow().statusBar() - bar.showMessage( - "Nested sequences are created separately.", timeout=3000 - ) - build_sequence(otio_clip, project, otio_track.kind) - - elif isinstance(otio_clip, otio.schema.Clip): - # Create a Clip - clip = create_clip(otio_clip) - - # Add Clip to a Bin - sequencebin.addItem(hiero.core.BinItem(clip)) - - # Create TrackItem - trackitem = create_trackitem( - playhead, track, otio_clip, clip, tagsbin - ) - - # Add trackitem to track - track.addTrackItem(trackitem) - - # Update playhead - playhead = trackitem.timelineOut() + 1 - - elif isinstance(otio_clip, otio.schema.Transition): - # Store transitions for when all clips in the track are created - _transitions.append((otio_track, otio_clip)) - - elif isinstance(otio_clip, otio.schema.Gap): - # Hiero has no fillers, slugs or blanks at the moment - playhead += otio_clip.source_range.duration.value - - # Apply transitions we stored earlier now that all clips are present - for otio_track, otio_item in _transitions: - apply_transition(otio_track, otio_item, track) diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Python/StartupUI/otioimporter/__init__.py b/server_addon/hiero/client/ayon_hiero/api/startup/Python/StartupUI/otioimporter/__init__.py deleted file mode 100644 index c0f1cc9c67..0000000000 --- a/server_addon/hiero/client/ayon_hiero/api/startup/Python/StartupUI/otioimporter/__init__.py +++ /dev/null @@ -1,141 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -__author__ = "Daniel Flehner Heen" -__credits__ = ["Jakub Jezek", "Daniel Flehner Heen"] - -import hiero.ui -import hiero.core - -import PySide2.QtWidgets as qw - -from ayon_hiero.api.otio.hiero_import import load_otio - - -class OTIOProjectSelect(qw.QDialog): - - def __init__(self, projects, *args, **kwargs): - super(OTIOProjectSelect, self).__init__(*args, **kwargs) - self.setWindowTitle("Please select active project") - self.layout = qw.QVBoxLayout() - - self.label = qw.QLabel( - "Unable to determine which project to import sequence to.\n" - "Please select one." - ) - self.layout.addWidget(self.label) - - self.projects = qw.QComboBox() - self.projects.addItems(map(lambda p: p.name(), projects)) - self.layout.addWidget(self.projects) - - QBtn = qw.QDialogButtonBox.Ok | qw.QDialogButtonBox.Cancel - self.buttonBox = qw.QDialogButtonBox(QBtn) - self.buttonBox.accepted.connect(self.accept) - self.buttonBox.rejected.connect(self.reject) - - self.layout.addWidget(self.buttonBox) - self.setLayout(self.layout) - - -def get_sequence(view): - sequence = None - if isinstance(view, hiero.ui.TimelineEditor): - sequence = view.sequence() - - elif isinstance(view, hiero.ui.BinView): - for item in view.selection(): - if not hasattr(item, "acitveItem"): - continue - - if isinstance(item.activeItem(), hiero.core.Sequence): - sequence = item.activeItem() - - return sequence - - -def OTIO_menu_action(event): - # Menu actions - otio_import_action = hiero.ui.createMenuAction( - "Import OTIO...", - open_otio_file, - icon=None - ) - - otio_add_track_action = hiero.ui.createMenuAction( - "New Track(s) from OTIO...", - open_otio_file, - icon=None - ) - otio_add_track_action.setEnabled(False) - - hiero.ui.registerAction(otio_import_action) - hiero.ui.registerAction(otio_add_track_action) - - view = hiero.ui.currentContextMenuView() - - if view: - sequence = get_sequence(view) - if sequence: - otio_add_track_action.setEnabled(True) - - for action in event.menu.actions(): - if action.text() == "Import": - action.menu().addAction(otio_import_action) - action.menu().addAction(otio_add_track_action) - - elif action.text() == "New Track": - action.menu().addAction(otio_add_track_action) - - -def open_otio_file(): - files = hiero.ui.openFileBrowser( - caption="Please select an OTIO file of choice", - pattern="*.otio", - requiredExtension=".otio" - ) - - selection = None - sequence = None - - view = hiero.ui.currentContextMenuView() - if view: - sequence = get_sequence(view) - selection = view.selection() - - if sequence: - project = sequence.project() - - elif selection: - project = selection[0].project() - - elif len(hiero.core.projects()) > 1: - dialog = OTIOProjectSelect(hiero.core.projects()) - if dialog.exec_(): - project = hiero.core.projects()[dialog.projects.currentIndex()] - - else: - bar = hiero.ui.mainWindow().statusBar() - bar.showMessage( - "OTIO Import aborted by user", - timeout=3000 - ) - return - - else: - project = hiero.core.projects()[-1] - - for otio_file in files: - load_otio(otio_file, project, sequence) - - -# HieroPlayer is quite limited and can't create transitions etc. -if not hiero.core.isHieroPlayer(): - hiero.core.events.registerInterest( - "kShowContextMenu/kBin", - OTIO_menu_action - ) - hiero.core.events.registerInterest( - "kShowContextMenu/kTimeline", - OTIO_menu_action - ) diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/Python/StartupUI/setPosterFrame.py b/server_addon/hiero/client/ayon_hiero/api/startup/Python/StartupUI/setPosterFrame.py deleted file mode 100644 index 8614d51bb0..0000000000 --- a/server_addon/hiero/client/ayon_hiero/api/startup/Python/StartupUI/setPosterFrame.py +++ /dev/null @@ -1,45 +0,0 @@ -import hiero.core -import hiero.ui -try: - from PySide.QtGui import * - from PySide.QtCore import * -except: - from PySide2.QtGui import * - from PySide2.QtWidgets import * - from PySide2.QtCore import * - - -def setPosterFrame(posterFrame=.5): - """ - Update the poster frame of the given clipItmes - posterFrame = .5 uses the centre frame, a value of 0 uses the first frame, a value of 1 uses the last frame - """ - view = hiero.ui.activeView() - - selectedBinItems = view.selection() - selectedClipItems = [(item.activeItem() - if hasattr(item, "activeItem") else item) - for item in selectedBinItems] - - for clip in selectedClipItems: - centreFrame = int(clip.duration() * posterFrame) - clip.setPosterFrame(centreFrame) - - -class SetPosterFrameAction(QAction): - def __init__(self): - QAction.__init__(self, "Set Poster Frame (centre)", None) - self._selection = None - - self.triggered.connect(lambda: setPosterFrame(.5)) - hiero.core.events.registerInterest("kShowContextMenu/kBin", - self.eventHandler) - - def eventHandler(self, event): - view = event.sender - # Add the Menu to the right-click menu - event.menu.addAction(self) - - -# The act of initialising the action adds it to the right-click menu... -SetPosterFrameAction() diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/TaskPresets/10.5/Processors/hiero.exporters.FnShotProcessor.ShotProcessor/pipeline.xml b/server_addon/hiero/client/ayon_hiero/api/startup/TaskPresets/10.5/Processors/hiero.exporters.FnShotProcessor.ShotProcessor/pipeline.xml deleted file mode 100644 index 690820c788..0000000000 --- a/server_addon/hiero/client/ayon_hiero/api/startup/TaskPresets/10.5/Processors/hiero.exporters.FnShotProcessor.ShotProcessor/pipeline.xml +++ /dev/null @@ -1,198 +0,0 @@ - - 991 - //10.11.0.184/171001_ftrack/tgbvfx/editorial/hiero/workspace/ - 1 - True - 3 - - - {shot}/editorial_raw.%04d.{fileext} - - - default - exr - False - all - False - False - False - False - True - - - 8 bit - (auto detect) - True - False - - False - - None - None - None - None - None - None - None - None - None - - - Zip (16 scanline) - 32 bit float - False - False - False - channels, layers and views - 45.0 - False - all metadata - - Write_{ext} - - Cubic - None - 1.0 -
True
- width -
- False - Blend -
-
-
- - {shot}/editorial.%04d.{ext} - - - default - exr - False - all - False - False - False - False - True - - - 8 bit - (auto detect) - True - False - - True - - None - None - None - None - None - None - None - None - None - - - Zip (16 scanline) - 16 bit half - False - False - False - channels, layers and views - 45.0 - False - all metadata - - Write_{ext} - - Cubic - To Sequence Resolution - 1.0 -
True
- width -
- False - Blend -
-
-
- - {shot}/editorial.nk - - - True - default - mov - - rgb - False - - False - False - False - - True - True - - {shot}/editorial_raw.%04d.{fileext} - - - Cubic - None - 1.0 -
True
- width -
- False - Blend - False - True - True - - 0 - 40000000 - 12 - 31 - 2 - avc1 H.264 - Auto - mov32 - 20000 - - False - True - True - False - False - {shot}/editorial_raw.%04d.{fileext} - - None - None - None - None - None - None - None - None - None - - - 8 bit - (auto detect) - True - False - - Write_{ext} - False -
-
-
-
- - - False - Custom - True - 10 -
diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/TaskPresets/11.1/Processors/hiero.exporters.FnShotProcessor.ShotProcessor/pipeline.xml b/server_addon/hiero/client/ayon_hiero/api/startup/TaskPresets/11.1/Processors/hiero.exporters.FnShotProcessor.ShotProcessor/pipeline.xml deleted file mode 100644 index 690820c788..0000000000 --- a/server_addon/hiero/client/ayon_hiero/api/startup/TaskPresets/11.1/Processors/hiero.exporters.FnShotProcessor.ShotProcessor/pipeline.xml +++ /dev/null @@ -1,198 +0,0 @@ - - 991 - //10.11.0.184/171001_ftrack/tgbvfx/editorial/hiero/workspace/ - 1 - True - 3 - - - {shot}/editorial_raw.%04d.{fileext} - - - default - exr - False - all - False - False - False - False - True - - - 8 bit - (auto detect) - True - False - - False - - None - None - None - None - None - None - None - None - None - - - Zip (16 scanline) - 32 bit float - False - False - False - channels, layers and views - 45.0 - False - all metadata - - Write_{ext} - - Cubic - None - 1.0 -
True
- width -
- False - Blend -
-
-
- - {shot}/editorial.%04d.{ext} - - - default - exr - False - all - False - False - False - False - True - - - 8 bit - (auto detect) - True - False - - True - - None - None - None - None - None - None - None - None - None - - - Zip (16 scanline) - 16 bit half - False - False - False - channels, layers and views - 45.0 - False - all metadata - - Write_{ext} - - Cubic - To Sequence Resolution - 1.0 -
True
- width -
- False - Blend -
-
-
- - {shot}/editorial.nk - - - True - default - mov - - rgb - False - - False - False - False - - True - True - - {shot}/editorial_raw.%04d.{fileext} - - - Cubic - None - 1.0 -
True
- width -
- False - Blend - False - True - True - - 0 - 40000000 - 12 - 31 - 2 - avc1 H.264 - Auto - mov32 - 20000 - - False - True - True - False - False - {shot}/editorial_raw.%04d.{fileext} - - None - None - None - None - None - None - None - None - None - - - 8 bit - (auto detect) - True - False - - Write_{ext} - False -
-
-
-
- - - False - Custom - True - 10 -
diff --git a/server_addon/hiero/client/ayon_hiero/api/startup/TaskPresets/11.2/hiero.exporters.FnShotProcessor.ShotProcessor/pipeline.xml b/server_addon/hiero/client/ayon_hiero/api/startup/TaskPresets/11.2/hiero.exporters.FnShotProcessor.ShotProcessor/pipeline.xml deleted file mode 100644 index 690820c788..0000000000 --- a/server_addon/hiero/client/ayon_hiero/api/startup/TaskPresets/11.2/hiero.exporters.FnShotProcessor.ShotProcessor/pipeline.xml +++ /dev/null @@ -1,198 +0,0 @@ - - 991 - //10.11.0.184/171001_ftrack/tgbvfx/editorial/hiero/workspace/ - 1 - True - 3 - - - {shot}/editorial_raw.%04d.{fileext} - - - default - exr - False - all - False - False - False - False - True - - - 8 bit - (auto detect) - True - False - - False - - None - None - None - None - None - None - None - None - None - - - Zip (16 scanline) - 32 bit float - False - False - False - channels, layers and views - 45.0 - False - all metadata - - Write_{ext} - - Cubic - None - 1.0 -
True
- width -
- False - Blend -
-
-
- - {shot}/editorial.%04d.{ext} - - - default - exr - False - all - False - False - False - False - True - - - 8 bit - (auto detect) - True - False - - True - - None - None - None - None - None - None - None - None - None - - - Zip (16 scanline) - 16 bit half - False - False - False - channels, layers and views - 45.0 - False - all metadata - - Write_{ext} - - Cubic - To Sequence Resolution - 1.0 -
True
- width -
- False - Blend -
-
-
- - {shot}/editorial.nk - - - True - default - mov - - rgb - False - - False - False - False - - True - True - - {shot}/editorial_raw.%04d.{fileext} - - - Cubic - None - 1.0 -
True
- width -
- False - Blend - False - True - True - - 0 - 40000000 - 12 - 31 - 2 - avc1 H.264 - Auto - mov32 - 20000 - - False - True - True - False - False - {shot}/editorial_raw.%04d.{fileext} - - None - None - None - None - None - None - None - None - None - - - 8 bit - (auto detect) - True - False - - Write_{ext} - False -
-
-
-
- - - False - Custom - True - 10 -
diff --git a/server_addon/hiero/client/ayon_hiero/api/style.css b/server_addon/hiero/client/ayon_hiero/api/style.css deleted file mode 100644 index b64c391c6e..0000000000 --- a/server_addon/hiero/client/ayon_hiero/api/style.css +++ /dev/null @@ -1,26 +0,0 @@ -QWidget { - font-size: 13px; -} - -QSpinBox { - padding: 2; - max-width: 8em; -} - -QLineEdit { - padding: 2; - min-width: 15em; -} - -QVBoxLayout { - min-width: 15em; - background-color: #201f1f; -} - -QComboBox { - min-width: 8em; -} - -#sectionContent { - background-color: #2E2D2D; -} \ No newline at end of file diff --git a/server_addon/hiero/client/ayon_hiero/api/tags.py b/server_addon/hiero/client/ayon_hiero/api/tags.py deleted file mode 100644 index d4acb23493..0000000000 --- a/server_addon/hiero/client/ayon_hiero/api/tags.py +++ /dev/null @@ -1,197 +0,0 @@ -import json -import re -import hiero - -import ayon_api - -from ayon_core.lib import Logger -from ayon_core.pipeline import get_current_project_name - -log = Logger.get_logger(__name__) - - -def tag_data(): - return { - "[Lenses]": { - "Set lense here": { - "editable": "1", - "note": "Adjust parameters of your lense and then drop to clip. Remember! You can always overwrite on clip", # noqa - "icon": "lense.png", - "metadata": { - "focalLengthMm": 57 - - } - } - }, - # "NukeScript": { - # "editable": "1", - # "note": "Collecting track items to Nuke scripts.", - # "icon": "icons:TagNuke.png", - # "metadata": { - # "productType": "nukescript", - # "productName": "main" - # } - # }, - "Comment": { - "editable": "1", - "note": "Comment on a shot.", - "icon": "icons:TagComment.png", - "metadata": { - "productType": "comment", - "productName": "main" - } - }, - "FrameMain": { - "editable": "1", - "note": "Publishing a frame product.", - "icon": "z_layer_main.png", - "metadata": { - "productType": "frame", - "productName": "main", - "format": "png" - } - } - } - - -def create_tag(key, data): - """ - Creating Tag object. - - Args: - key (str): name of tag - data (dict): parameters of tag - - Returns: - object: Tag object - """ - tag = hiero.core.Tag(str(key)) - return update_tag(tag, data) - - -def update_tag(tag, data): - """ - Fixing Tag object. - - Args: - tag (obj): Tag object - data (dict): parameters of tag - """ - # set icon if any available in input data - if data.get("icon"): - tag.setIcon(str(data["icon"])) - - # get metadata of tag - mtd = tag.metadata() - # get metadata key from data - data_mtd = data.get("metadata", {}) - - # set all data metadata to tag metadata - for _k, _v in data_mtd.items(): - value = str(_v) - if isinstance(_v, dict): - value = json.dumps(_v) - - # set the value - mtd.setValue( - "tag.{}".format(str(_k)), - value - ) - - # set note description of tag - tag.setNote(str(data["note"])) - return tag - - -def add_tags_to_workfile(): - """ - Will create default tags from presets. - """ - from .lib import get_current_project - - def add_tag_to_bin(root_bin, name, data): - # for Tags to be created in root level Bin - # at first check if any of input data tag is not already created - done_tag = next((t for t in root_bin.items() - if str(name) in t.name()), None) - - if not done_tag: - # create Tag - tag = create_tag(name, data) - tag.setName(str(name)) - - log.debug("__ creating tag: {}".format(tag)) - # adding Tag to Root Bin - root_bin.addItem(tag) - else: - # update only non hierarchy tags - update_tag(done_tag, data) - done_tag.setName(str(name)) - log.debug("__ updating tag: {}".format(done_tag)) - - # get project and root bin object - project = get_current_project() - root_bin = project.tagsBin() - - if "Tag Presets" in project.name(): - return - - log.debug("Setting default tags on project: {}".format(project.name())) - - # get hiero tags.json - nks_pres_tags = tag_data() - - # Get project task types. - project_name = get_current_project_name() - project_entity = ayon_api.get_project(project_name) - task_types = project_entity["taskTypes"] - nks_pres_tags["[Tasks]"] = {} - log.debug("__ tasks: {}".format(task_types)) - for task_type in task_types: - task_type_name = task_type["name"] - nks_pres_tags["[Tasks]"][task_type_name.lower()] = { - "editable": "1", - "note": task_type_name, - "icon": "icons:TagGood.png", - "metadata": { - "productType": "task", - "type": task_type_name - } - } - - # loop through tag data dict and create deep tag structure - for _k, _val in nks_pres_tags.items(): - # check if key is not decorated with [] so it is defined as bin - bin_find = None - pattern = re.compile(r"\[(.*)\]") - _bin_finds = pattern.findall(_k) - # if there is available any then pop it to string - if _bin_finds: - bin_find = _bin_finds.pop() - - # if bin was found then create or update - if bin_find: - root_add = False - # first check if in root lever is not already created bins - bins = [b for b in root_bin.items() - if b.name() in str(bin_find)] - - if bins: - bin = bins.pop() - else: - root_add = True - # create Bin object for processing - bin = hiero.core.Bin(str(bin_find)) - - # update or create tags in the bin - for __k, __v in _val.items(): - add_tag_to_bin(bin, __k, __v) - - # finally add the Bin object to the root level Bin - if root_add: - # adding Tag to Root Bin - root_bin.addItem(bin) - else: - add_tag_to_bin(root_bin, _k, _val) - - log.info("Default Tags were set...") diff --git a/server_addon/hiero/client/ayon_hiero/api/workio.py b/server_addon/hiero/client/ayon_hiero/api/workio.py deleted file mode 100644 index 6e8fc20172..0000000000 --- a/server_addon/hiero/client/ayon_hiero/api/workio.py +++ /dev/null @@ -1,72 +0,0 @@ -import os -import hiero - -from ayon_core.lib import Logger - -log = Logger.get_logger(__name__) - - -def file_extensions(): - return [".hrox"] - - -def has_unsaved_changes(): - # There are no methods for querying unsaved changes to a project, so - # enforcing to always save. - # but we could at least check if a current open script has a path - project = hiero.core.projects()[-1] - if project.path(): - return True - else: - return False - - -def save_file(filepath): - file = os.path.basename(filepath) - project = hiero.core.projects()[-1] - - if project: - log.info("Saving project: `{}` as '{}'".format(project.name(), file)) - project.saveAs(filepath) - else: - log.info("Creating new project...") - project = hiero.core.newProject() - project.saveAs(filepath) - - -def open_file(filepath): - """Manually fire the kBeforeProjectLoad event in order to work around a bug in Hiero. - The Foundry has logged this bug as: - Bug 40413 - Python API - kBeforeProjectLoad event type is not triggered - when calling hiero.core.openProject() (only triggered through UI) - It exists in all versions of Hiero through (at least) v1.9v1b12. - - Once this bug is fixed, a version check will need to be added here in order to - prevent accidentally firing this event twice. The following commented-out code - is just an example, and will need to be updated when the bug is fixed to catch the - correct versions.""" - # if (hiero.core.env['VersionMajor'] < 1 or - # hiero.core.env['VersionMajor'] == 1 and hiero.core.env['VersionMinor'] < 10: - hiero.core.events.sendEvent("kBeforeProjectLoad", None) - - project = hiero.core.projects()[-1] - - # Close previous project if its different to the current project. - filepath = filepath.replace(os.path.sep, "/") - if project.path().replace(os.path.sep, "/") != filepath: - # open project file - hiero.core.openProject(filepath) - project.close() - - return True - - -def current_file(): - current_file = hiero.core.projects()[-1].path() - if not current_file: - return None - return os.path.normpath(current_file) - - -def work_root(session): - return os.path.normpath(session["AYON_WORKDIR"]).replace("\\", "/") diff --git a/server_addon/hiero/client/ayon_hiero/plugins/create/create_shot_clip.py b/server_addon/hiero/client/ayon_hiero/plugins/create/create_shot_clip.py deleted file mode 100644 index 201cf382e2..0000000000 --- a/server_addon/hiero/client/ayon_hiero/plugins/create/create_shot_clip.py +++ /dev/null @@ -1,262 +0,0 @@ -from copy import deepcopy -import ayon_hiero.api as phiero -# from ayon_hiero.api import plugin, lib -# reload(lib) -# reload(plugin) -# reload(phiero) - - -class CreateShotClip(phiero.Creator): - """Publishable clip""" - - label = "Create Publishable Clip" - product_type = "clip" - icon = "film" - defaults = ["Main"] - - gui_tracks = [track.name() - for track in phiero.get_current_sequence().videoTracks()] - gui_name = "AYON publish attributes creator" - gui_info = "Define sequential rename and fill hierarchy data." - gui_inputs = { - "renameHierarchy": { - "type": "section", - "label": "Shot Hierarchy And Rename Settings", - "target": "ui", - "order": 0, - "value": { - "hierarchy": { - "value": "{folder}/{sequence}", - "type": "QLineEdit", - "label": "Shot Parent Hierarchy", - "target": "tag", - "toolTip": "Parents folder for shot root folder, Template filled with `Hierarchy Data` section", # noqa - "order": 0}, - "clipRename": { - "value": False, - "type": "QCheckBox", - "label": "Rename clips", - "target": "ui", - "toolTip": "Renaming selected clips on fly", # noqa - "order": 1}, - "clipName": { - "value": "{sequence}{shot}", - "type": "QLineEdit", - "label": "Clip Name Template", - "target": "ui", - "toolTip": "template for creating shot namespaused for renaming (use rename: on)", # noqa - "order": 2}, - "countFrom": { - "value": 10, - "type": "QSpinBox", - "label": "Count sequence from", - "target": "ui", - "toolTip": "Set when the sequence number stafrom", # noqa - "order": 3}, - "countSteps": { - "value": 10, - "type": "QSpinBox", - "label": "Stepping number", - "target": "ui", - "toolTip": "What number is adding every new step", # noqa - "order": 4}, - } - }, - "hierarchyData": { - "type": "dict", - "label": "Shot Template Keywords", - "target": "tag", - "order": 1, - "value": { - "folder": { - "value": "shots", - "type": "QLineEdit", - "label": "{folder}", - "target": "tag", - "toolTip": "Name of folder used for root of generated shots.\nUsable tokens:\n\t{_clip_}: name of used clip\n\t{_track_}: name of parent track layer\n\t{_sequence_}: name of parent sequence (timeline)", # noqa - "order": 0}, - "episode": { - "value": "ep01", - "type": "QLineEdit", - "label": "{episode}", - "target": "tag", - "toolTip": "Name of episode.\nUsable tokens:\n\t{_clip_}: name of used clip\n\t{_track_}: name of parent track layer\n\t{_sequence_}: name of parent sequence (timeline)", # noqa - "order": 1}, - "sequence": { - "value": "sq01", - "type": "QLineEdit", - "label": "{sequence}", - "target": "tag", - "toolTip": "Name of sequence of shots.\nUsable tokens:\n\t{_clip_}: name of used clip\n\t{_track_}: name of parent track layer\n\t{_sequence_}: name of parent sequence (timeline)", # noqa - "order": 2}, - "track": { - "value": "{_track_}", - "type": "QLineEdit", - "label": "{track}", - "target": "tag", - "toolTip": "Name of sequence of shots.\nUsable tokens:\n\t{_clip_}: name of used clip\n\t{_track_}: name of parent track layer\n\t{_sequence_}: name of parent sequence (timeline)", # noqa - "order": 3}, - "shot": { - "value": "sh###", - "type": "QLineEdit", - "label": "{shot}", - "target": "tag", - "toolTip": "Name of shot. `#` is converted to paded number. \nAlso could be used with usable tokens:\n\t{_clip_}: name of used clip\n\t{_track_}: name of parent track layer\n\t{_sequence_}: name of parent sequence (timeline)", # noqa - "order": 4} - } - }, - "verticalSync": { - "type": "section", - "label": "Vertical Synchronization Of Attributes", - "target": "ui", - "order": 2, - "value": { - "vSyncOn": { - "value": True, - "type": "QCheckBox", - "label": "Enable Vertical Sync", - "target": "ui", - "toolTip": "Switch on if you want clips above each other to share its attributes", # noqa - "order": 0}, - "vSyncTrack": { - "value": gui_tracks, # noqa - "type": "QComboBox", - "label": "Hero track", - "target": "ui", - "toolTip": "Select driving track name which should be hero for all others", # noqa - "order": 1} - } - }, - "publishSettings": { - "type": "section", - "label": "Publish Settings", - "target": "ui", - "order": 3, - "value": { - "productName": { - "value": ["", "main", "bg", "fg", "bg", - "animatic"], - "type": "QComboBox", - "label": "Product Name", - "target": "ui", - "toolTip": "chose product name pattern, if is selected, name of track layer will be used", # noqa - "order": 0}, - "productType": { - "value": ["plate", "take"], - "type": "QComboBox", - "label": "Product Type", - "target": "ui", "toolTip": "What use of this product is for", # noqa - "order": 1}, - "reviewTrack": { - "value": ["< none >"] + gui_tracks, - "type": "QComboBox", - "label": "Use Review Track", - "target": "ui", - "toolTip": "Generate preview videos on fly, if `< none >` is defined nothing will be generated.", # noqa - "order": 2}, - "audio": { - "value": False, - "type": "QCheckBox", - "label": "Include audio", - "target": "tag", - "toolTip": "Process products with corresponding audio", # noqa - "order": 3}, - "sourceResolution": { - "value": False, - "type": "QCheckBox", - "label": "Source resolution", - "target": "tag", - "toolTip": "Is resolution taken from timeline or source?", # noqa - "order": 4}, - } - }, - "frameRangeAttr": { - "type": "section", - "label": "Shot Attributes", - "target": "ui", - "order": 4, - "value": { - "workfileFrameStart": { - "value": 1001, - "type": "QSpinBox", - "label": "Workfiles Start Frame", - "target": "tag", - "toolTip": "Set workfile starting frame number", # noqa - "order": 0 - }, - "handleStart": { - "value": 0, - "type": "QSpinBox", - "label": "Handle Start", - "target": "tag", - "toolTip": "Handle at start of clip", # noqa - "order": 1 - }, - "handleEnd": { - "value": 0, - "type": "QSpinBox", - "label": "Handle End", - "target": "tag", - "toolTip": "Handle at end of clip", # noqa - "order": 2 - } - } - } - } - - presets = None - - def process(self): - # Creator copy of object attributes that are modified during `process` - presets = deepcopy(self.presets) - gui_inputs = deepcopy(self.gui_inputs) - - # get key pairs from presets and match it on ui inputs - for k, v in gui_inputs.items(): - if v["type"] in ("dict", "section"): - # nested dictionary (only one level allowed - # for sections and dict) - for _k, _v in v["value"].items(): - if presets.get(_k): - gui_inputs[k][ - "value"][_k]["value"] = presets[_k] - if presets.get(k): - gui_inputs[k]["value"] = presets[k] - - # open widget for plugins inputs - widget = self.widget(self.gui_name, self.gui_info, gui_inputs) - widget.exec_() - - if len(self.selected) < 1: - return - - if not widget.result: - print("Operation aborted") - return - - self.rename_add = 0 - - # get ui output for track name for vertical sync - v_sync_track = widget.result["vSyncTrack"]["value"] - - # sort selected trackItems by - sorted_selected_track_items = list() - unsorted_selected_track_items = list() - for _ti in self.selected: - if _ti.parent().name() in v_sync_track: - sorted_selected_track_items.append(_ti) - else: - unsorted_selected_track_items.append(_ti) - - sorted_selected_track_items.extend(unsorted_selected_track_items) - - kwargs = { - "ui_inputs": widget.result, - "avalon": self.data - } - - for i, track_item in enumerate(sorted_selected_track_items): - self.rename_index = i - - # convert track item to timeline media pool item - phiero.PublishClip(self, track_item, **kwargs).convert() diff --git a/server_addon/hiero/client/ayon_hiero/plugins/load/load_clip.py b/server_addon/hiero/client/ayon_hiero/plugins/load/load_clip.py deleted file mode 100644 index d93730c735..0000000000 --- a/server_addon/hiero/client/ayon_hiero/plugins/load/load_clip.py +++ /dev/null @@ -1,230 +0,0 @@ -import ayon_api - -from ayon_core.pipeline import get_representation_path -from ayon_core.lib.transcoding import ( - VIDEO_EXTENSIONS, - IMAGE_EXTENSIONS -) -import ayon_hiero.api as phiero - - -class LoadClip(phiero.SequenceLoader): - """Load a product to timeline as clip - - Place clip to timeline on its asset origin timings collected - during conforming to project - """ - - product_types = {"render2d", "source", "plate", "render", "review"} - representations = {"*"} - extensions = set( - ext.lstrip(".") for ext in IMAGE_EXTENSIONS.union(VIDEO_EXTENSIONS) - ) - - label = "Load as clip" - order = -10 - icon = "code-fork" - color = "orange" - - # for loader multiselection - sequence = None - track = None - - # presets - clip_color_last = "green" - clip_color = "red" - - clip_name_template = "{asset}_{subset}_{representation}" - - @classmethod - def apply_settings(cls, project_settings): - plugin_type_settings = ( - project_settings - .get("hiero", {}) - .get("load", {}) - ) - - if not plugin_type_settings: - return - - plugin_name = cls.__name__ - - # Look for plugin settings in host specific settings - plugin_settings = plugin_type_settings.get(plugin_name) - if not plugin_settings: - return - - print(">>> We have preset for {}".format(plugin_name)) - for option, value in plugin_settings.items(): - if option == "representations": - continue - - if option == "clip_name_template": - # TODO remove the formatting replacement - value = ( - value - .replace("{folder[name]}", "{asset}") - .replace("{product[name]}", "{subset}") - ) - - if option == "enabled" and value is False: - print(" - is disabled by preset") - else: - print(" - setting `{}`: `{}`".format(option, value)) - setattr(cls, option, value) - - def load(self, context, name, namespace, options): - # add clip name template to options - options.update({ - "clipNameTemplate": self.clip_name_template - }) - # in case loader uses multiselection - if self.track and self.sequence: - options.update({ - "sequence": self.sequence, - "track": self.track, - "clipNameTemplate": self.clip_name_template - }) - - # load clip to timeline and get main variables - path = self.filepath_from_context(context) - track_item = phiero.ClipLoader(self, context, path, **options).load() - namespace = namespace or track_item.name() - version_entity = context["version"] - version_attributes = version_entity["attrib"] - version_name = version_entity["version"] - colorspace = version_attributes.get("colorSpace") - object_name = self.clip_name_template.format( - **context["representation"]["context"]) - - # set colorspace - if colorspace: - track_item.source().setSourceMediaColourTransform(colorspace) - - # add additional metadata from the version to imprint Avalon knob - add_keys = [ - "frameStart", "frameEnd", "source", "author", - "fps", "handleStart", "handleEnd" - ] - - # move all version data keys to tag data - data_imprint = { - key: version_attributes.get(key, str(None)) - for key in add_keys - - } - - # add variables related to version context - data_imprint.update({ - "version": version_name, - "colorspace": colorspace, - "objectName": object_name - }) - - # update color of clip regarding the version order - self.set_item_color( - context["project"]["name"], track_item, version_entity - ) - - # deal with multiselection - self.multiselection(track_item) - - self.log.info("Loader done: `{}`".format(name)) - - return phiero.containerise( - track_item, - name, namespace, context, - self.__class__.__name__, - data_imprint) - - def switch(self, container, context): - self.update(container, context) - - def update(self, container, context): - """ Updating previously loaded clips - """ - version_entity = context["version"] - repre_entity = context["representation"] - - # load clip to timeline and get main variables - name = container["name"] - namespace = container["namespace"] - track_item = phiero.get_track_items( - track_item_name=namespace).pop() - - version_attributes = version_entity["attrib"] - version_name = version_entity["version"] - colorspace = version_attributes.get("colorSpace") - object_name = "{}_{}".format(name, namespace) - - file = get_representation_path(repre_entity).replace("\\", "/") - clip = track_item.source() - - # reconnect media to new path - clip.reconnectMedia(file) - - # set colorspace - if colorspace: - clip.setSourceMediaColourTransform(colorspace) - - # add additional metadata from the version to imprint metadata knob - - # move all version data keys to tag data - data_imprint = {} - for key in [ - "frameStart", - "frameEnd", - "source", - "author", - "fps", - "handleStart", - "handleEnd", - ]: - data_imprint.update({ - key: version_attributes.get(key, str(None)) - }) - - # add variables related to version context - data_imprint.update({ - "representation": repre_entity["id"], - "version": version_name, - "colorspace": colorspace, - "objectName": object_name - }) - - # update color of clip regarding the version order - self.set_item_color( - context["project"]["name"], track_item, version_entity - ) - - return phiero.update_container(track_item, data_imprint) - - def remove(self, container): - """ Removing previously loaded clips - """ - # load clip to timeline and get main variables - namespace = container['namespace'] - track_item = phiero.get_track_items( - track_item_name=namespace).pop() - track = track_item.parent() - - # remove track item from track - track.removeItem(track_item) - - @classmethod - def multiselection(cls, track_item): - if not cls.track: - cls.track = track_item.parent() - cls.sequence = cls.track.parent() - - @classmethod - def set_item_color(cls, project_name, track_item, version_entity): - last_version_entity = ayon_api.get_last_version_by_product_id( - project_name, version_entity["productId"], fields={"id"} - ) - clip = track_item.source() - # set clip colour - if version_entity["id"] == last_version_entity["id"]: - clip.binItem().setColor(cls.clip_color_last) - else: - clip.binItem().setColor(cls.clip_color) diff --git a/server_addon/hiero/client/ayon_hiero/plugins/load/load_effects.py b/server_addon/hiero/client/ayon_hiero/plugins/load/load_effects.py deleted file mode 100644 index 24130f7485..0000000000 --- a/server_addon/hiero/client/ayon_hiero/plugins/load/load_effects.py +++ /dev/null @@ -1,305 +0,0 @@ -import json -from collections import OrderedDict -import six - -from ayon_core.pipeline import ( - AVALON_CONTAINER_ID, - load, - get_representation_path, -) -from ayon_hiero import api as phiero -from ayon_core.lib import Logger - - -class LoadEffects(load.LoaderPlugin): - """Loading colorspace soft effect exported from nukestudio""" - - product_types = {"effect"} - representations = {"*"} - extension = {"json"} - - label = "Load Effects" - order = 0 - icon = "cc" - color = "white" - - log = Logger.get_logger(__name__) - - def load(self, context, name, namespace, data): - """ - Loading function to get the soft effects to particular read node - - Arguments: - context (dict): context of version - name (str): name of the version - namespace (str): Folder name. - data (dict): compulsory attribute > not used - - Returns: - nuke node: containerised nuke node object - """ - active_sequence = phiero.get_current_sequence() - active_track = phiero.get_current_track( - active_sequence, "Loaded_{}".format(name)) - - # get main variables - namespace = namespace or context["folder"]["name"] - object_name = "{}_{}".format(name, namespace) - clip_in = context["folder"]["attrib"]["clipIn"] - clip_out = context["folder"]["attrib"]["clipOut"] - - data_imprint = { - "objectName": object_name, - "children_names": [] - } - - # getting file path - file = self.filepath_from_context(context) - file = file.replace("\\", "/") - - if self._shared_loading( - file, - active_track, - clip_in, - clip_out, - data_imprint - ): - self.containerise( - active_track, - name=name, - namespace=namespace, - object_name=object_name, - context=context, - loader=self.__class__.__name__, - data=data_imprint) - - def _shared_loading( - self, - file, - active_track, - clip_in, - clip_out, - data_imprint, - update=False - ): - # getting data from json file with unicode conversion - with open(file, "r") as f: - json_f = {self.byteify(key): self.byteify(value) - for key, value in json.load(f).items()} - - # get correct order of nodes by positions on track and subtrack - nodes_order = self.reorder_nodes(json_f) - - used_subtracks = { - stitem.name(): stitem - for stitem in phiero.flatten(active_track.subTrackItems()) - } - - loaded = False - for index_order, (ef_name, ef_val) in enumerate(nodes_order.items()): - new_name = "{}_loaded".format(ef_name) - if new_name not in used_subtracks: - effect_track_item = active_track.createEffect( - effectType=ef_val["class"], - timelineIn=clip_in, - timelineOut=clip_out, - subTrackIndex=index_order - - ) - effect_track_item.setName(new_name) - else: - effect_track_item = used_subtracks[new_name] - - node = effect_track_item.node() - for knob_name, knob_value in ef_val["node"].items(): - if ( - not knob_value - or knob_name == "name" - ): - continue - - try: - # assume list means animation - # except 4 values could be RGBA or vector - if isinstance(knob_value, list) and len(knob_value) > 4: - node[knob_name].setAnimated() - for i, value in enumerate(knob_value): - if isinstance(value, list): - # list can have vector animation - for ci, cv in enumerate(value): - node[knob_name].setValueAt( - cv, - (clip_in + i), - ci - ) - else: - # list is single values - node[knob_name].setValueAt( - value, - (clip_in + i) - ) - else: - node[knob_name].setValue(knob_value) - except NameError: - self.log.warning("Knob: {} cannot be set".format( - knob_name)) - - # register all loaded children - data_imprint["children_names"].append(new_name) - - # make sure containerisation will happen - loaded = True - - return loaded - - def update(self, container, context): - """ Updating previously loaded effects - """ - version_entity = context["version"] - repre_entity = context["representation"] - active_track = container["_item"] - file = get_representation_path(repre_entity).replace("\\", "/") - - # get main variables - name = container['name'] - namespace = container['namespace'] - - # get timeline in out data - version_attributes = version_entity["attrib"] - clip_in = version_attributes["clipIn"] - clip_out = version_attributes["clipOut"] - - object_name = "{}_{}".format(name, namespace) - - # Disable previously created nodes - used_subtracks = { - stitem.name(): stitem - for stitem in phiero.flatten(active_track.subTrackItems()) - } - container = phiero.get_track_openpype_data( - active_track, object_name - ) - - loaded_subtrack_items = container["children_names"] - for loaded_stitem in loaded_subtrack_items: - if loaded_stitem not in used_subtracks: - continue - item_to_remove = used_subtracks.pop(loaded_stitem) - # TODO: find a way to erase nodes - self.log.debug( - "This node needs to be removed: {}".format(item_to_remove)) - - data_imprint = { - "objectName": object_name, - "name": name, - "representation": repre_entity["id"], - "children_names": [] - } - - if self._shared_loading( - file, - active_track, - clip_in, - clip_out, - data_imprint, - update=True - ): - return phiero.update_container(active_track, data_imprint) - - def reorder_nodes(self, data): - new_order = OrderedDict() - trackNums = [v["trackIndex"] for k, v in data.items() - if isinstance(v, dict)] - subTrackNums = [v["subTrackIndex"] for k, v in data.items() - if isinstance(v, dict)] - - for trackIndex in range( - min(trackNums), max(trackNums) + 1): - for subTrackIndex in range( - min(subTrackNums), max(subTrackNums) + 1): - item = self.get_item(data, trackIndex, subTrackIndex) - if item is not {}: - new_order.update(item) - return new_order - - def get_item(self, data, trackIndex, subTrackIndex): - return {key: val for key, val in data.items() - if isinstance(val, dict) - if subTrackIndex == val["subTrackIndex"] - if trackIndex == val["trackIndex"]} - - def byteify(self, input): - """ - Converts unicode strings to strings - It goes through all dictionary - - Arguments: - input (dict/str): input - - Returns: - dict: with fixed values and keys - - """ - - if isinstance(input, dict): - return {self.byteify(key): self.byteify(value) - for key, value in input.items()} - elif isinstance(input, list): - return [self.byteify(element) for element in input] - elif isinstance(input, six.text_type): - return str(input) - else: - return input - - def switch(self, container, context): - self.update(container, context) - - def remove(self, container): - pass - - def containerise( - self, - track, - name, - namespace, - object_name, - context, - loader=None, - data=None - ): - """Bundle Hiero's object into an assembly and imprint it with metadata - - Containerisation enables a tracking of version, author and origin - for loaded assets. - - Arguments: - track (hiero.core.VideoTrack): object to imprint as container - name (str): Name of resulting assembly - namespace (str): Namespace under which to host container - object_name (str): name of container - context (dict): Asset information - loader (str, optional): Name of node used to produce this - container. - - Returns: - track_item (hiero.core.TrackItem): containerised object - - """ - - data_imprint = { - object_name: { - "schema": "openpype:container-2.0", - "id": AVALON_CONTAINER_ID, - "name": str(name), - "namespace": str(namespace), - "loader": str(loader), - "representation": context["representation"]["id"], - } - } - - if data: - for k, v in data.items(): - data_imprint[object_name].update({k: v}) - - self.log.debug("_ data_imprint: {}".format(data_imprint)) - phiero.set_track_openpype_tag(track, data_imprint) diff --git a/server_addon/hiero/client/ayon_hiero/plugins/publish/collect_clip_effects.py b/server_addon/hiero/client/ayon_hiero/plugins/publish/collect_clip_effects.py deleted file mode 100644 index 850dda9676..0000000000 --- a/server_addon/hiero/client/ayon_hiero/plugins/publish/collect_clip_effects.py +++ /dev/null @@ -1,239 +0,0 @@ -import re - -import pyblish.api - - -class CollectClipEffects(pyblish.api.InstancePlugin): - """Collect soft effects instances.""" - - order = pyblish.api.CollectorOrder - 0.078 - label = "Collect Clip Effects Instances" - families = ["clip"] - settings_category = "hiero" - - effect_categories = [] - effect_tracks = [] - - def process(self, instance): - product_type = "effect" - effects = {} - review = instance.data.get("review") - review_track_index = instance.context.data.get("reviewTrackIndex") - item = instance.data["item"] - - if "audio" in instance.data["productType"]: - return - - # frame range - self.handle_start = instance.data["handleStart"] - self.handle_end = instance.data["handleEnd"] - self.clip_in = int(item.timelineIn()) - self.clip_out = int(item.timelineOut()) - self.clip_in_h = self.clip_in - self.handle_start - self.clip_out_h = self.clip_out + self.handle_end - - track_item = instance.data["item"] - track = track_item.parent() - track_index = track.trackIndex() - tracks_effect_items = instance.context.data.get("tracksEffectItems") - clip_effect_items = instance.data.get("clipEffectItems") - - # add clips effects to track's: - if clip_effect_items: - tracks_effect_items[track_index] = clip_effect_items - - # process all effects and divide them to instance - for _track_index, sub_track_items in tracks_effect_items.items(): - # skip if track index is the same as review track index - if review and review_track_index == _track_index: - continue - for sitem in sub_track_items: - # make sure this subtrack item is relative of track item - if ((track_item not in sitem.linkedItems()) - and (len(sitem.linkedItems()) > 0)): - continue - - if not (track_index <= _track_index): - continue - - effect = self.add_effect(_track_index, sitem) - if effect: - effects.update(effect) - - # skip any without effects - if not effects: - return - - product_name = instance.data.get("productName") - effects.update({"assignTo": product_name}) - - product_name_split = re.findall(r'[A-Z][^A-Z]*', product_name) - - if len(product_name_split) > 0: - root_name = product_name.replace(product_name_split[0], "") - product_name_split.insert(0, root_name.capitalize()) - - product_name_split.insert(0, "effect") - - # Categorize effects by class. - effect_categories = { - x["name"]: x["effect_classes"] for x in self.effect_categories - } - - category_by_effect = {"": ""} - for key, values in effect_categories.items(): - for cls in values: - category_by_effect[cls] = key - - effects_categorized = {k: {} for k in effect_categories.keys()} - for key, value in effects.items(): - if key == "assignTo": - continue - - # Some classes can have a number in them. Like Text2. - found_cls = "" - for cls in category_by_effect.keys(): - if cls in value["class"]: - found_cls = cls - - if not found_cls: - continue - - effects_categorized[category_by_effect[found_cls]][key] = value - - # Categorize effects by track name. - track_names_by_category = { - x["name"]: x["track_names"] for x in self.effect_tracks - } - for category, track_names in track_names_by_category.items(): - for key, value in effects.items(): - if key == "assignTo": - continue - - if value["track"] not in track_names: - continue - - if category in effects_categorized: - effects_categorized[category][key] = value - else: - effects_categorized[category] = {key: value} - - # Ensure required `assignTo` data member exists. - categories = list(effects_categorized.keys()) - for category in categories: - if not effects_categorized[category]: - effects_categorized.pop(category) - continue - - effects_categorized[category]["assignTo"] = effects["assignTo"] - - # If no effects have been categorized, publish all effects together. - if not effects_categorized: - effects_categorized[""] = effects - - for category, effects in effects_categorized.items(): - product_name = "".join(product_name_split) - product_name += category.capitalize() - - # create new instance and inherit data - data = {} - for key, value in instance.data.items(): - if "clipEffectItems" in key: - continue - data[key] = value - - data.update({ - "productName": product_name, - "productType": product_type, - "family": product_type, - "families": [product_type], - "name": product_name + "_" + data["folderPath"], - "label": "{} - {}".format( - data["folderPath"], product_name - ), - "effects": effects, - }) - - # create new instance - _instance = instance.context.create_instance(**data) - self.log.info("Created instance `{}`".format(_instance)) - self.log.debug("instance.data `{}`".format(_instance.data)) - - def test_overlap(self, effect_t_in, effect_t_out): - covering_exp = bool( - (effect_t_in <= self.clip_in) - and (effect_t_out >= self.clip_out) - ) - overlaying_right_exp = bool( - (effect_t_in < self.clip_out) - and (effect_t_out >= self.clip_out) - ) - overlaying_left_exp = bool( - (effect_t_out > self.clip_in) - and (effect_t_in <= self.clip_in) - ) - - return any(( - covering_exp, - overlaying_right_exp, - overlaying_left_exp - )) - - def add_effect(self, track_index, sitem): - track = sitem.parentTrack().name() - # node serialization - node = sitem.node() - node_serialized = self.node_serialization(node) - node_name = sitem.name() - node_class = node.Class() - - # collect timelineIn/Out - effect_t_in = int(sitem.timelineIn()) - effect_t_out = int(sitem.timelineOut()) - - if not self.test_overlap(effect_t_in, effect_t_out): - return - - self.log.debug("node_name: `{}`".format(node_name)) - self.log.debug("node_class: `{}`".format(node_class)) - - return {node_name: { - "class": node_class, - "timelineIn": effect_t_in, - "timelineOut": effect_t_out, - "subTrackIndex": sitem.subTrackIndex(), - "trackIndex": track_index, - "track": track, - "node": node_serialized - }} - - def node_serialization(self, node): - node_serialized = {} - - # adding ignoring knob keys - _ignoring_keys = ['invert_mask', 'help', 'mask', - 'xpos', 'ypos', 'layer', 'process_mask', 'channel', - 'channels', 'maskChannelMask', 'maskChannelInput', - 'note_font', 'note_font_size', 'unpremult', - 'postage_stamp_frame', 'maskChannel', 'export_cc', - 'select_cccid', 'mix', 'version', 'matrix'] - - # loop through all knobs and collect not ignored - # and any with any value - for knob in node.knobs().keys(): - # skip nodes in ignore keys - if knob in _ignoring_keys: - continue - - # get animation if node is animated - if node[knob].isAnimated(): - # grab animation including handles - knob_anim = [node[knob].getValueAt(i) - for i in range( - self.clip_in_h, self.clip_out_h + 1)] - - node_serialized[knob] = knob_anim - else: - node_serialized[knob] = node[knob].value() - - return node_serialized diff --git a/server_addon/hiero/client/ayon_hiero/plugins/publish/collect_frame_tag_instances.py b/server_addon/hiero/client/ayon_hiero/plugins/publish/collect_frame_tag_instances.py deleted file mode 100644 index 0e5d849b78..0000000000 --- a/server_addon/hiero/client/ayon_hiero/plugins/publish/collect_frame_tag_instances.py +++ /dev/null @@ -1,151 +0,0 @@ -from pprint import pformat -import re -import ast -import json - -import pyblish.api - - -class CollectFrameTagInstances(pyblish.api.ContextPlugin): - """Collect frames from tags. - - Tag is expected to have metadata: - { - "productType": "frame" - "productName": "main" - } - """ - - order = pyblish.api.CollectorOrder - label = "Collect Frames" - hosts = ["hiero"] - - def process(self, context): - self._context = context - - # collect all sequence tags - product_data = self._create_frame_product_data_sequence(context) - - self.log.debug("__ product_data: {}".format( - pformat(product_data) - )) - - # create instances - self._create_instances(product_data) - - def _get_tag_data(self, tag): - data = {} - - # get tag metadata attribute - tag_data = tag.metadata() - - # convert tag metadata to normal keys names and values to correct types - for k, v in dict(tag_data).items(): - key = k.replace("tag.", "") - - try: - # capture exceptions which are related to strings only - if re.match(r"^[\d]+$", v): - value = int(v) - elif re.match(r"^True$", v): - value = True - elif re.match(r"^False$", v): - value = False - elif re.match(r"^None$", v): - value = None - elif re.match(r"^[\w\d_]+$", v): - value = v - else: - value = ast.literal_eval(v) - except (ValueError, SyntaxError): - value = v - - data[key] = value - - return data - - def _create_frame_product_data_sequence(self, context): - - sequence_tags = [] - sequence = context.data["activeTimeline"] - - # get all publishable sequence frames - publish_frames = range(int(sequence.duration() + 1)) - - self.log.debug("__ publish_frames: {}".format( - pformat(publish_frames) - )) - - # get all sequence tags - for tag in sequence.tags(): - tag_data = self._get_tag_data(tag) - self.log.debug("__ tag_data: {}".format( - pformat(tag_data) - )) - if not tag_data: - continue - - product_type = tag_data.get("productType") - if product_type is None: - product_type = tag_data.get("family") - if not product_type: - continue - - if product_type != "frame": - continue - - sequence_tags.append(tag_data) - - self.log.debug("__ sequence_tags: {}".format( - pformat(sequence_tags) - )) - - # first collect all available product tag frames - product_data = {} - context_folder_path = context.data["folderEntity"]["path"] - - for tag_data in sequence_tags: - frame = int(tag_data["start"]) - - if frame not in publish_frames: - continue - - product_name = tag_data.get("productName") - if product_name is None: - product_name = tag_data["subset"] - - if product_name in product_data: - # update existing product key - product_data[product_name]["frames"].append(frame) - else: - # create new product key - product_data[product_name] = { - "frames": [frame], - "format": tag_data["format"], - "folderPath": context_folder_path - } - return product_data - - def _create_instances(self, product_data): - # create instance per product - product_type = "image" - for product_name, product_data in product_data.items(): - name = "frame" + product_name.title() - data = { - "name": name, - "label": "{} {}".format(name, product_data["frames"]), - "productType": product_type, - "family": product_type, - "families": [product_type, "frame"], - "folderPath": product_data["folderPath"], - "productName": name, - "format": product_data["format"], - "frames": product_data["frames"] - } - self._context.create_instance(**data) - - self.log.info( - "Created instance: {}".format( - json.dumps(data, sort_keys=True, indent=4) - ) - ) diff --git a/server_addon/hiero/client/ayon_hiero/plugins/publish/collect_tag_tasks.py b/server_addon/hiero/client/ayon_hiero/plugins/publish/collect_tag_tasks.py deleted file mode 100644 index 35a8c02cc0..0000000000 --- a/server_addon/hiero/client/ayon_hiero/plugins/publish/collect_tag_tasks.py +++ /dev/null @@ -1,33 +0,0 @@ -from pyblish import api - - -class CollectClipTagTasks(api.InstancePlugin): - """Collect Tags from selected track items.""" - - order = api.CollectorOrder - 0.077 - label = "Collect Tag Tasks" - hosts = ["hiero"] - families = ["shot"] - - def process(self, instance): - # gets tags - tags = instance.data["tags"] - - tasks = {} - for tag in tags: - t_metadata = dict(tag.metadata()) - t_product_type = t_metadata.get("tag.productType") - if t_product_type is None: - t_product_type = t_metadata.get("tag.family", "") - - # gets only task product type tags and collect labels - if "task" in t_product_type: - t_task_name = t_metadata.get("tag.label", "") - t_task_type = t_metadata.get("tag.type", "") - tasks[t_task_name] = {"type": t_task_type} - - instance.data["tasks"] = tasks - - self.log.info("Collected Tasks from Tags: `{}`".format( - instance.data["tasks"])) - return diff --git a/server_addon/hiero/client/ayon_hiero/plugins/publish/extract_clip_effects.py b/server_addon/hiero/client/ayon_hiero/plugins/publish/extract_clip_effects.py deleted file mode 100644 index 7ee979c37a..0000000000 --- a/server_addon/hiero/client/ayon_hiero/plugins/publish/extract_clip_effects.py +++ /dev/null @@ -1,103 +0,0 @@ -import os -import json -import pyblish.api - -from ayon_core.pipeline import publish - - -class ExtractClipEffects(publish.Extractor): - """Extract clip effects instances.""" - - order = pyblish.api.ExtractorOrder - label = "Export Clip Effects" - families = ["effect"] - - def process(self, instance): - item = instance.data["item"] - effects = instance.data.get("effects") - - # skip any without effects - if not effects: - return - - product_name = instance.data.get("productName") - product_type = instance.data["productType"] - - self.log.debug("creating staging dir") - staging_dir = self.staging_dir(instance) - - transfers = list() - if "transfers" not in instance.data: - instance.data["transfers"] = list() - - ext = "json" - file = product_name + "." + ext - - # when instance is created during collection part - resources_dir = instance.data["resourcesDir"] - - # change paths in effects to files - for k, effect in effects.items(): - if "assignTo" in k: - continue - trn = self.copy_linked_files(effect, resources_dir) - if trn: - transfers.append((trn[0], trn[1])) - - instance.data["transfers"].extend(transfers) - self.log.debug("_ transfers: `{}`".format( - instance.data["transfers"])) - - # create representations - instance.data["representations"] = list() - - transfer_data = [ - "handleStart", "handleEnd", - "sourceStart", "sourceStartH", "sourceEnd", "sourceEndH", - "frameStart", "frameEnd", - "clipIn", "clipOut", "clipInH", "clipOutH", - "folderPath", "version" - ] - - # pass data to version - version_data = dict() - version_data.update({k: instance.data[k] for k in transfer_data}) - - # add to data of representation - version_data.update({ - "colorspace": item.sourceMediaColourTransform(), - "colorspaceScript": instance.context.data["colorspace"], - "families": [product_type, "plate"], - # TODO find out if 'subset' is needed (and 'productName') - "subset": product_name, - "productName": product_name, - "fps": instance.context.data["fps"] - }) - instance.data["versionData"] = version_data - - representation = { - 'files': file, - 'stagingDir': staging_dir, - 'name': product_type + ext.title(), - 'ext': ext - } - instance.data["representations"].append(representation) - - self.log.debug("_ representations: `{}`".format( - instance.data["representations"])) - - self.log.debug("_ version_data: `{}`".format( - instance.data["versionData"])) - - with open(os.path.join(staging_dir, file), "w") as outfile: - outfile.write(json.dumps(effects, indent=4, sort_keys=True)) - - def copy_linked_files(self, effect, dst_dir): - for k, v in effect["node"].items(): - if k in "file" and v != '': - base_name = os.path.basename(v) - dst = os.path.join(dst_dir, base_name).replace("\\", "/") - - # add it to the json - effect["node"][k] = dst - return (v, dst) diff --git a/server_addon/hiero/client/ayon_hiero/plugins/publish/extract_frames.py b/server_addon/hiero/client/ayon_hiero/plugins/publish/extract_frames.py deleted file mode 100644 index 9ea3134d4c..0000000000 --- a/server_addon/hiero/client/ayon_hiero/plugins/publish/extract_frames.py +++ /dev/null @@ -1,87 +0,0 @@ -import os -import pyblish.api - -from ayon_core.lib import ( - get_oiio_tool_args, - run_subprocess, -) -from ayon_core.pipeline import publish - - -class ExtractFrames(publish.Extractor): - """Extracts frames""" - - order = pyblish.api.ExtractorOrder - label = "Extract Frames" - hosts = ["hiero"] - families = ["frame"] - movie_extensions = ["mov", "mp4"] - - def process(self, instance): - oiio_tool_args = get_oiio_tool_args("oiiotool") - staging_dir = self.staging_dir(instance) - output_template = os.path.join(staging_dir, instance.data["name"]) - sequence = instance.context.data["activeTimeline"] - - files = [] - for frame in instance.data["frames"]: - track_item = sequence.trackItemAt(frame) - media_source = track_item.source().mediaSource() - input_path = media_source.fileinfos()[0].filename() - input_frame = ( - track_item.mapTimelineToSource(frame) + - track_item.source().mediaSource().startTime() - ) - output_ext = instance.data["format"] - output_path = output_template - output_path += ".{:04d}.{}".format(int(frame), output_ext) - - args = list(oiio_tool_args) - - ext = os.path.splitext(input_path)[1][1:] - if ext in self.movie_extensions: - args.extend(["--subimage", str(int(input_frame))]) - else: - args.extend(["--frames", str(int(input_frame))]) - - if ext == "exr": - args.extend(["--powc", "0.45,0.45,0.45,1.0"]) - - args.extend([input_path, "-o", output_path]) - output = run_subprocess(args) - - failed_output = "oiiotool produced no output." - if failed_output in output: - raise ValueError( - "oiiotool processing failed. Args: {}".format(args) - ) - - files.append(output_path) - - # Feedback to user because "oiiotool" can make the publishing - # appear unresponsive. - self.log.info( - "Processed {} of {} frames".format( - instance.data["frames"].index(frame) + 1, - len(instance.data["frames"]) - ) - ) - - if len(files) == 1: - instance.data["representations"] = [ - { - "name": output_ext, - "ext": output_ext, - "files": os.path.basename(files[0]), - "stagingDir": staging_dir - } - ] - else: - instance.data["representations"] = [ - { - "name": output_ext, - "ext": output_ext, - "files": [os.path.basename(x) for x in files], - "stagingDir": staging_dir - } - ] diff --git a/server_addon/hiero/client/ayon_hiero/plugins/publish/extract_thumbnail.py b/server_addon/hiero/client/ayon_hiero/plugins/publish/extract_thumbnail.py deleted file mode 100644 index 3599a830d2..0000000000 --- a/server_addon/hiero/client/ayon_hiero/plugins/publish/extract_thumbnail.py +++ /dev/null @@ -1,60 +0,0 @@ -import os -import pyblish.api - -from ayon_core.pipeline import publish - - -class ExtractThumbnail(publish.Extractor): - """ - Extractor for track item's tumbnails - """ - - label = "Extract Thumbnail" - order = pyblish.api.ExtractorOrder - families = ["plate", "take"] - hosts = ["hiero"] - - def process(self, instance): - # create representation data - if "representations" not in instance.data: - instance.data["representations"] = [] - - staging_dir = self.staging_dir(instance) - - self.create_thumbnail(staging_dir, instance) - - def create_thumbnail(self, staging_dir, instance): - track_item = instance.data["item"] - track_item_name = track_item.name() - - # frames - duration = track_item.sourceDuration() - frame_start = track_item.sourceIn() - self.log.debug( - "__ frame_start: `{}`, duration: `{}`".format( - frame_start, duration)) - - # get thumbnail frame from the middle - thumb_frame = int(frame_start + (duration / 2)) - - thumb_file = "{}thumbnail{}{}".format( - track_item_name, thumb_frame, ".png") - thumb_path = os.path.join(staging_dir, thumb_file) - - thumbnail = track_item.thumbnail(thumb_frame, "colour").save( - thumb_path, - format='png' - ) - self.log.debug( - "__ thumb_path: `{}`, frame: `{}`".format(thumbnail, thumb_frame)) - - self.log.info("Thumbnail was generated to: {}".format(thumb_path)) - thumb_representation = { - 'files': thumb_file, - 'stagingDir': staging_dir, - 'name': "thumbnail", - 'thumbnail': True, - 'ext': "png" - } - instance.data["representations"].append( - thumb_representation) diff --git a/server_addon/hiero/client/ayon_hiero/plugins/publish/integrate_version_up_workfile.py b/server_addon/hiero/client/ayon_hiero/plugins/publish/integrate_version_up_workfile.py deleted file mode 100644 index 27a8bc2604..0000000000 --- a/server_addon/hiero/client/ayon_hiero/plugins/publish/integrate_version_up_workfile.py +++ /dev/null @@ -1,24 +0,0 @@ -from pyblish import api - -from ayon_core.lib import version_up - - -class IntegrateVersionUpWorkfile(api.ContextPlugin): - """Save as new workfile version""" - - order = api.IntegratorOrder + 10.1 - label = "Version-up Workfile" - hosts = ["hiero"] - - optional = True - active = True - - def process(self, context): - project = context.data["activeProject"] - path = context.data.get("currentFile") - new_path = version_up(path) - - if project: - project.saveAs(new_path) - - self.log.info("Project workfile was versioned up") diff --git a/server_addon/hiero/client/ayon_hiero/plugins/publish/precollect_instances.py b/server_addon/hiero/client/ayon_hiero/plugins/publish/precollect_instances.py deleted file mode 100644 index ca60231361..0000000000 --- a/server_addon/hiero/client/ayon_hiero/plugins/publish/precollect_instances.py +++ /dev/null @@ -1,451 +0,0 @@ -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_hiero import api as phiero -from ayon_hiero.api.otio import hiero_export - -import hiero -# # developer reload modules -from pprint import pformat - - -class PrecollectInstances(pyblish.api.ContextPlugin): - """Collect all Track items selection.""" - - order = pyblish.api.CollectorOrder - 0.49 - label = "Precollect Instances" - hosts = ["hiero"] - - audio_track_items = [] - - def process(self, context): - self.otio_timeline = context.data["otioTimeline"] - timeline_selection = phiero.get_timeline_selection() - selected_timeline_items = phiero.get_track_items( - selection=timeline_selection, - check_tagged=True, - check_enabled=True - ) - - # only return enabled track items - if not selected_timeline_items: - selected_timeline_items = phiero.get_track_items( - check_enabled=True, check_tagged=True) - - self.log.info( - "Processing enabled track items: {}".format( - selected_timeline_items)) - - # add all tracks subtreck effect items to context - all_tracks = hiero.ui.activeSequence().videoTracks() - tracks_effect_items = self.collect_sub_track_items(all_tracks) - context.data["tracksEffectItems"] = tracks_effect_items - - # process all selected timeline track items - for track_item in selected_timeline_items: - data = {} - clip_name = track_item.name() - source_clip = track_item.source() - self.log.debug("clip_name: {}".format(clip_name)) - - # get openpype tag data - tag_data = phiero.get_trackitem_openpype_data(track_item) - self.log.debug("__ tag_data: {}".format(pformat(tag_data))) - - if not tag_data: - continue - - if tag_data.get("id") not in { - AYON_INSTANCE_ID, AVALON_INSTANCE_ID - }: - continue - - # get clips subtracks and annotations - annotations = self.clip_annotations(source_clip) - subtracks = self.clip_subtrack(track_item) - self.log.debug("Annotations: {}".format(annotations)) - self.log.debug(">> Subtracks: {}".format(subtracks)) - - # solve handles length - tag_data["handleStart"] = min( - tag_data["handleStart"], int(track_item.handleInLength())) - tag_data["handleEnd"] = min( - tag_data["handleEnd"], int(track_item.handleOutLength())) - - # add audio to families - with_audio = False - if tag_data.pop("audio"): - with_audio = True - - # add tag data to instance data - data.update({ - k: v for k, v in tag_data.items() - if k not in ("id", "applieswhole", "label") - }) - # Backward compatibility fix of 'entity_type' > 'folder_type' - if "parents" in data: - for parent in data["parents"]: - if "entity_type" in parent: - parent["folder_type"] = parent.pop("entity_type") - - folder_path, folder_name = self._get_folder_data(tag_data) - - families = [str(f) for f in tag_data["families"]] - - # TODO: remove backward compatibility - product_name = tag_data.get("productName") - if product_name is None: - # backward compatibility: subset -> productName - product_name = tag_data.get("subset") - - # backward compatibility: product_name should not be missing - if not product_name: - self.log.error( - "Product name is not defined for: {}".format(folder_path)) - - # TODO: remove backward compatibility - product_type = tag_data.get("productType") - if product_type is None: - # backward compatibility: family -> productType - product_type = tag_data.get("family") - - # backward compatibility: product_type should not be missing - if not product_type: - self.log.error( - "Product type is not defined for: {}".format(folder_path)) - - # form label - label = "{} -".format(folder_path) - if folder_name != clip_name: - label += " ({})".format(clip_name) - label += " {}".format(product_name) - - data.update({ - "name": "{}_{}".format(folder_path, product_name), - "label": label, - "productName": product_name, - "productType": product_type, - "folderPath": folder_path, - "asset_name": folder_name, - "item": track_item, - "families": families, - "publish": tag_data["publish"], - "fps": context.data["fps"], - - # clip's effect - "clipEffectItems": subtracks, - "clipAnnotations": annotations, - - # add all additional tags - "tags": phiero.get_track_item_tags(track_item), - "newHierarchyIntegration": True, - # Backwards compatible (Deprecated since 24/06/06) - "newAssetPublishing": True, - }) - - # otio clip data - otio_data = self.get_otio_clip_instance_data(track_item) or {} - self.log.debug("__ otio_data: {}".format(pformat(otio_data))) - data.update(otio_data) - self.log.debug("__ data: {}".format(pformat(data))) - - # add resolution - self.get_resolution_to_data(data, context) - - # create instance - instance = context.create_instance(**data) - - # add colorspace data - instance.data.update({ - "versionData": { - "colorspace": track_item.sourceMediaColourTransform(), - } - }) - - # create shot instance for shot attributes create/update - self.create_shot_instance(context, **data) - - self.log.info("Creating instance: {}".format(instance)) - self.log.info( - "_ instance.data: {}".format(pformat(instance.data))) - - if not with_audio: - continue - - # create audio product instance - self.create_audio_instance(context, **data) - - # add audioReview attribute to plate instance data - # if reviewTrack is on - if tag_data.get("reviewTrack") is not None: - instance.data["reviewAudio"] = True - - def get_resolution_to_data(self, data, context): - assert data.get("otioClip"), "Missing `otioClip` data" - - # solve source resolution option - if data.get("sourceResolution", None): - otio_clip_metadata = data[ - "otioClip"].media_reference.metadata - data.update({ - "resolutionWidth": otio_clip_metadata[ - "openpype.source.width"], - "resolutionHeight": otio_clip_metadata[ - "openpype.source.height"], - "pixelAspect": otio_clip_metadata[ - "openpype.source.pixelAspect"] - }) - else: - otio_tl_metadata = context.data["otioTimeline"].metadata - data.update({ - "resolutionWidth": otio_tl_metadata["openpype.timeline.width"], - "resolutionHeight": otio_tl_metadata[ - "openpype.timeline.height"], - "pixelAspect": otio_tl_metadata[ - "openpype.timeline.pixelAspect"] - }) - - def create_shot_instance(self, context, **data): - product_name = "shotMain" - master_layer = data.get("heroTrack") - hierarchy_data = data.get("hierarchyData") - item = data.get("item") - clip_name = item.name() - - if not master_layer: - return - - if not hierarchy_data: - return - - folder_path = data["folderPath"] - folder_name = data["asset_name"] - - product_type = "shot" - - # form label - label = "{} -".format(folder_path) - if folder_name != clip_name: - label += " ({}) ".format(clip_name) - label += " {}".format(product_name) - - data.update({ - "name": "{}_{}".format(folder_path, product_name), - "label": label, - "productName": product_name, - "productType": product_type, - "family": product_type, - "families": [product_type], - "integrate": False, - }) - - instance = context.create_instance(**data) - self.log.info("Creating instance: {}".format(instance)) - self.log.debug( - "_ instance.data: {}".format(pformat(instance.data))) - - def _get_folder_data(self, data): - folder_path = data.pop("folderPath", None) - - if data.get("asset_name"): - folder_name = data["asset_name"] - else: - folder_name = data["asset"] - - # backward compatibility for clip tags - # which are missing folderPath key - # TODO remove this in future versions - if not folder_path: - hierarchy_path = data["hierarchy"] - folder_path = "/{}/{}".format( - hierarchy_path, - folder_name - ) - - return folder_path, folder_name - - def create_audio_instance(self, context, **data): - product_name = "audioMain" - master_layer = data.get("heroTrack") - - if not master_layer: - return - - item = data.get("item") - clip_name = item.name() - - # test if any audio clips - if not self.test_any_audio(item): - return - - folder_path = data["folderPath"] - asset_name = data["asset_name"] - - product_type = "audio" - - # form label - label = "{} -".format(folder_path) - if asset_name != clip_name: - label += " ({}) ".format(clip_name) - label += " {}".format(product_name) - - data.update({ - "name": "{}_{}".format(folder_path, product_name), - "label": label, - "productName": product_name, - "productType": product_type, - "family": product_type, - "families": [product_type, "clip"] - }) - # remove review track attr if any - data.pop("reviewTrack") - - # create instance - instance = context.create_instance(**data) - self.log.info("Creating instance: {}".format(instance)) - self.log.debug( - "_ instance.data: {}".format(pformat(instance.data))) - - def test_any_audio(self, track_item): - # collect all audio tracks to class variable - if not self.audio_track_items: - for otio_clip in self.otio_timeline.each_clip(): - if otio_clip.parent().kind != "Audio": - continue - self.audio_track_items.append(otio_clip) - - # get track item timeline range - timeline_range = self.create_otio_time_range_from_timeline_item_data( - track_item) - - # loop through audio track items and search for overlapping clip - for otio_audio in self.audio_track_items: - parent_range = otio_audio.range_in_parent() - - # if any overaling clip found then return True - if is_overlapping_otio_ranges( - parent_range, timeline_range, strict=False): - return True - - def get_otio_clip_instance_data(self, track_item): - """ - Return otio objects for timeline, track and clip - - Args: - timeline_item_data (dict): timeline_item_data from list returned by - resolve.get_current_timeline_items() - otio_timeline (otio.schema.Timeline): otio object - - Returns: - dict: otio clip object - - """ - ti_track_name = track_item.parent().name() - timeline_range = self.create_otio_time_range_from_timeline_item_data( - track_item) - for otio_clip in self.otio_timeline.each_clip(): - track_name = otio_clip.parent().name - parent_range = otio_clip.range_in_parent() - if ti_track_name != track_name: - continue - if otio_clip.name != track_item.name(): - continue - self.log.debug("__ parent_range: {}".format(parent_range)) - self.log.debug("__ timeline_range: {}".format(timeline_range)) - if is_overlapping_otio_ranges( - parent_range, timeline_range, strict=True): - - # add pypedata marker to otio_clip metadata - for marker in otio_clip.markers: - if phiero.OPENPYPE_TAG_NAME in marker.name: - otio_clip.metadata.update(marker.metadata) - return {"otioClip": otio_clip} - - return None - - @staticmethod - def create_otio_time_range_from_timeline_item_data(track_item): - timeline = phiero.get_current_sequence() - frame_start = int(track_item.timelineIn()) - frame_duration = int(track_item.duration()) - fps = timeline.framerate().toFloat() - - return hiero_export.create_otio_time_range( - frame_start, frame_duration, fps) - - def collect_sub_track_items(self, tracks): - """ - Returns dictionary with track index as key and list of subtracks - """ - # collect all subtrack items - sub_track_items = {} - for track in tracks: - effect_items = track.subTrackItems() - - # skip if no clips on track > need track with effect only - if not effect_items: - continue - - # skip all disabled tracks - if not track.isEnabled(): - continue - - track_index = track.trackIndex() - _sub_track_items = phiero.flatten(effect_items) - - _sub_track_items = list(_sub_track_items) - # continue only if any subtrack items are collected - if not _sub_track_items: - continue - - enabled_sti = [] - # loop all found subtrack items and check if they are enabled - for _sti in _sub_track_items: - # checking if not enabled - if not _sti.isEnabled(): - continue - if isinstance(_sti, hiero.core.Annotation): - continue - # collect the subtrack item - enabled_sti.append(_sti) - - # continue only if any subtrack items are collected - if not enabled_sti: - continue - - # add collection of subtrackitems to dict - sub_track_items[track_index] = enabled_sti - - return sub_track_items - - @staticmethod - def clip_annotations(clip): - """ - Returns list of Clip's hiero.core.Annotation - """ - annotations = [] - subTrackItems = phiero.flatten(clip.subTrackItems()) - annotations += [item for item in subTrackItems if isinstance( - item, hiero.core.Annotation)] - return annotations - - @staticmethod - def clip_subtrack(clip): - """ - Returns list of Clip's hiero.core.SubTrackItem - """ - subtracks = [] - subTrackItems = phiero.flatten(clip.parent().subTrackItems()) - for item in subTrackItems: - if "TimeWarp" in item.name(): - continue - # avoid all annotation - if isinstance(item, hiero.core.Annotation): - continue - # avoid all disabled - if not item.isEnabled(): - continue - subtracks.append(item) - return subtracks diff --git a/server_addon/hiero/client/ayon_hiero/plugins/publish/precollect_workfile.py b/server_addon/hiero/client/ayon_hiero/plugins/publish/precollect_workfile.py deleted file mode 100644 index 1dd21b3f21..0000000000 --- a/server_addon/hiero/client/ayon_hiero/plugins/publish/precollect_workfile.py +++ /dev/null @@ -1,111 +0,0 @@ -import os -import tempfile -from pprint import pformat - -import pyblish.api -from qtpy.QtGui import QPixmap - -import hiero.ui - -from ayon_hiero.api.otio import hiero_export - - -class PrecollectWorkfile(pyblish.api.ContextPlugin): - """Inject the current working file into context""" - - label = "Precollect Workfile" - order = pyblish.api.CollectorOrder - 0.491 - - def process(self, context): - folder_path = context.data["folderPath"] - folder_name = folder_path.split("/")[-1] - - active_timeline = hiero.ui.activeSequence() - project = active_timeline.project() - fps = active_timeline.framerate().toFloat() - - # adding otio timeline to context - otio_timeline = hiero_export.create_otio_timeline() - - # get workfile thumbnail paths - tmp_staging = tempfile.mkdtemp(prefix="pyblish_tmp_") - thumbnail_name = "workfile_thumbnail.png" - thumbnail_path = os.path.join(tmp_staging, thumbnail_name) - - # search for all windows with name of actual sequence - _windows = [w for w in hiero.ui.windowManager().windows() - if active_timeline.name() in w.windowTitle()] - - # export window to thumb path - QPixmap.grabWidget(_windows[-1]).save(thumbnail_path, 'png') - - # thumbnail - thumb_representation = { - 'files': thumbnail_name, - 'stagingDir': tmp_staging, - 'name': "thumbnail", - 'thumbnail': True, - 'ext': "png" - } - - # get workfile paths - current_file = project.path() - staging_dir, base_name = os.path.split(current_file) - - # creating workfile representation - workfile_representation = { - 'name': 'hrox', - 'ext': 'hrox', - 'files': base_name, - "stagingDir": staging_dir, - } - product_type = "workfile" - instance_data = { - "label": "{} - {}Main".format( - folder_path, product_type), - "name": "{}_{}".format(folder_name, product_type), - "folderPath": folder_path, - # TODO use 'get_product_name' - "productName": "{}{}Main".format( - folder_name, product_type.capitalize() - ), - "item": project, - "productType": product_type, - "family": product_type, - "families": [product_type], - "representations": [workfile_representation, thumb_representation] - } - - # create instance with workfile - instance = context.create_instance(**instance_data) - - # update context with main project attributes - context_data = { - "activeProject": project, - "activeTimeline": active_timeline, - "otioTimeline": otio_timeline, - "currentFile": current_file, - "colorspace": self.get_colorspace(project), - "fps": fps - } - self.log.debug("__ context_data: {}".format(pformat(context_data))) - context.data.update(context_data) - - self.log.info("Creating instance: {}".format(instance)) - self.log.debug("__ instance.data: {}".format(pformat(instance.data))) - self.log.debug("__ context_data: {}".format(pformat(context_data))) - - def get_colorspace(self, project): - # get workfile's colorspace properties - return { - "useOCIOEnvironmentOverride": project.useOCIOEnvironmentOverride(), - "lutSetting16Bit": project.lutSetting16Bit(), - "lutSetting8Bit": project.lutSetting8Bit(), - "lutSettingFloat": project.lutSettingFloat(), - "lutSettingLog": project.lutSettingLog(), - "lutSettingViewer": project.lutSettingViewer(), - "lutSettingWorkingSpace": project.lutSettingWorkingSpace(), - "lutUseOCIOForExport": project.lutUseOCIOForExport(), - "ocioConfigName": project.ocioConfigName(), - "ocioConfigPath": project.ocioConfigPath() - } diff --git a/server_addon/hiero/client/ayon_hiero/plugins/publish_old_workflow/collect_tag_comments.py b/server_addon/hiero/client/ayon_hiero/plugins/publish_old_workflow/collect_tag_comments.py deleted file mode 100644 index 76d7b6a67c..0000000000 --- a/server_addon/hiero/client/ayon_hiero/plugins/publish_old_workflow/collect_tag_comments.py +++ /dev/null @@ -1,35 +0,0 @@ -from pyblish import api - - -class CollectClipTagComments(api.InstancePlugin): - """Collect comments from tags on selected track items and their sources.""" - - order = api.CollectorOrder + 0.013 - label = "Collect Comments" - hosts = ["hiero"] - families = ["clip"] - - def process(self, instance): - # Collect comments. - instance.data["comments"] = [] - - # Exclude non-tagged instances. - for tag in instance.data["tags"]: - if tag["name"].lower() == "comment": - instance.data["comments"].append( - tag["metadata"]["tag.note"] - ) - - # Find tags on the source clip. - tags = instance.data["item"].source().tags() - for tag in tags: - if tag.name().lower() == "comment": - instance.data["comments"].append( - tag.metadata().dict()["tag.note"] - ) - - # Update label with comments counter. - instance.data["label"] = "{} - comments:{}".format( - instance.data["label"], - len(instance.data["comments"]) - ) diff --git a/server_addon/hiero/client/ayon_hiero/plugins/publish_old_workflow/precollect_retime.py b/server_addon/hiero/client/ayon_hiero/plugins/publish_old_workflow/precollect_retime.py deleted file mode 100644 index c511b40abc..0000000000 --- a/server_addon/hiero/client/ayon_hiero/plugins/publish_old_workflow/precollect_retime.py +++ /dev/null @@ -1,167 +0,0 @@ -from pyblish import api -import hiero -import math -from ayon_hiero.api.otio.hiero_export import create_otio_time_range - -class PrecollectRetime(api.InstancePlugin): - """Calculate Retiming of selected track items.""" - - order = api.CollectorOrder - 0.578 - label = "Precollect Retime" - hosts = ["hiero"] - families = ['retime_'] - - def process(self, instance): - if not instance.data.get("versionData"): - instance.data["versionData"] = {} - - # get basic variables - otio_clip = instance.data["otioClip"] - - source_range = otio_clip.source_range - oc_source_fps = source_range.start_time.rate - oc_source_in = source_range.start_time.value - - handle_start = instance.data["handleStart"] - handle_end = instance.data["handleEnd"] - frame_start = instance.data["frameStart"] - - track_item = instance.data["item"] - - # define basic clip frame range variables - timeline_in = int(track_item.timelineIn()) - timeline_out = int(track_item.timelineOut()) - source_in = int(track_item.sourceIn()) - source_out = int(track_item.sourceOut()) - speed = track_item.playbackSpeed() - - self.log.debug(( - "_BEFORE: \n timeline_in: `{0}`,\n timeline_out: `{1}`, \n " - "source_in: `{2}`,\n source_out: `{3}`,\n speed: `{4}`,\n " - "handle_start: `{5}`,\n handle_end: `{6}`").format( - timeline_in, - timeline_out, - source_in, - source_out, - speed, - handle_start, - handle_end - )) - - # loop within subtrack items - time_warp_nodes = [] - source_in_change = 0 - source_out_change = 0 - for s_track_item in track_item.linkedItems(): - if isinstance(s_track_item, hiero.core.EffectTrackItem) \ - and "TimeWarp" in s_track_item.node().Class(): - - # adding timewarp attribute to instance - time_warp_nodes = [] - - # ignore item if not enabled - if s_track_item.isEnabled(): - node = s_track_item.node() - name = node["name"].value() - look_up = node["lookup"].value() - animated = node["lookup"].isAnimated() - if animated: - look_up = [ - ((node["lookup"].getValueAt(i)) - i) - for i in range( - (timeline_in - handle_start), - (timeline_out + handle_end) + 1) - ] - # calculate difference - diff_in = (node["lookup"].getValueAt( - timeline_in)) - timeline_in - diff_out = (node["lookup"].getValueAt( - timeline_out)) - timeline_out - - # calculate source - source_in_change += diff_in - source_out_change += diff_out - - # calculate speed - speed_in = (node["lookup"].getValueAt(timeline_in) / ( - float(timeline_in) * .01)) * .01 - speed_out = (node["lookup"].getValueAt(timeline_out) / ( - float(timeline_out) * .01)) * .01 - - # calculate handles - handle_start = int( - math.ceil( - (handle_start * speed_in * 1000) / 1000.0) - ) - - handle_end = int( - math.ceil( - (handle_end * speed_out * 1000) / 1000.0) - ) - self.log.debug( - ("diff_in, diff_out", diff_in, diff_out)) - self.log.debug( - ("source_in_change, source_out_change", - source_in_change, source_out_change)) - - time_warp_nodes.append({ - "Class": "TimeWarp", - "name": name, - "lookup": look_up - }) - - self.log.debug( - "timewarp source in changes: in {}, out {}".format( - source_in_change, source_out_change)) - - # recalculate handles by the speed - handle_start *= speed - handle_end *= speed - self.log.debug("speed: handle_start: '{0}', handle_end: '{1}'".format( - handle_start, handle_end)) - - # recalculate source with timewarp and by the speed - source_in += int(source_in_change) - source_out += int(source_out_change * speed) - - source_in_h = int(source_in - math.ceil( - (handle_start * 1000) / 1000.0)) - source_out_h = int(source_out + math.ceil( - (handle_end * 1000) / 1000.0)) - - self.log.debug( - "retimed: source_in_h: '{0}', source_out_h: '{1}'".format( - source_in_h, source_out_h)) - - # add all data to Instance - instance.data["handleStart"] = handle_start - instance.data["handleEnd"] = handle_end - instance.data["sourceIn"] = source_in - instance.data["sourceOut"] = source_out - instance.data["sourceInH"] = source_in_h - instance.data["sourceOutH"] = source_out_h - instance.data["speed"] = speed - - source_handle_start = source_in_h - source_in - # frame_start = instance.data["frameStart"] + source_handle_start - duration = source_out_h - source_in_h - frame_end = int(frame_start + duration - (handle_start + handle_end)) - - instance.data["versionData"].update({ - "retime": True, - "speed": speed, - "timewarps": time_warp_nodes, - "frameStart": frame_start, - "frameEnd": frame_end, - "handleStart": abs(source_handle_start), - "handleEnd": source_out_h - source_out - }) - self.log.debug("versionData: {}".format(instance.data["versionData"])) - self.log.debug("sourceIn: {}".format(instance.data["sourceIn"])) - self.log.debug("sourceOut: {}".format(instance.data["sourceOut"])) - self.log.debug("speed: {}".format(instance.data["speed"])) - - # change otio clip data - instance.data["otioClip"].source_range = create_otio_time_range( - oc_source_in, (source_out - source_in + 1), oc_source_fps) - self.log.debug("otioClip: {}".format(instance.data["otioClip"])) diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/__init__.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/__init__.py deleted file mode 100644 index 03f3b29ee7..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/__init__.py +++ /dev/null @@ -1,33 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -# Copyright 2007 Google Inc. All Rights Reserved. - -__version__ = '3.20.1' diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/any_pb2.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/any_pb2.py deleted file mode 100644 index 9121193d11..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/any_pb2.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/any.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x19google/protobuf/any.proto\x12\x0fgoogle.protobuf\"&\n\x03\x41ny\x12\x10\n\x08type_url\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x0c\x42v\n\x13\x63om.google.protobufB\x08\x41nyProtoP\x01Z,google.golang.org/protobuf/types/known/anypb\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.any_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.google.protobufB\010AnyProtoP\001Z,google.golang.org/protobuf/types/known/anypb\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' - _ANY._serialized_start=46 - _ANY._serialized_end=84 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/api_pb2.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/api_pb2.py deleted file mode 100644 index 1721b10a75..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/api_pb2.py +++ /dev/null @@ -1,32 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/api.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.protobuf import source_context_pb2 as google_dot_protobuf_dot_source__context__pb2 -from google.protobuf import type_pb2 as google_dot_protobuf_dot_type__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x19google/protobuf/api.proto\x12\x0fgoogle.protobuf\x1a$google/protobuf/source_context.proto\x1a\x1agoogle/protobuf/type.proto\"\x81\x02\n\x03\x41pi\x12\x0c\n\x04name\x18\x01 \x01(\t\x12(\n\x07methods\x18\x02 \x03(\x0b\x32\x17.google.protobuf.Method\x12(\n\x07options\x18\x03 \x03(\x0b\x32\x17.google.protobuf.Option\x12\x0f\n\x07version\x18\x04 \x01(\t\x12\x36\n\x0esource_context\x18\x05 \x01(\x0b\x32\x1e.google.protobuf.SourceContext\x12&\n\x06mixins\x18\x06 \x03(\x0b\x32\x16.google.protobuf.Mixin\x12\'\n\x06syntax\x18\x07 \x01(\x0e\x32\x17.google.protobuf.Syntax\"\xd5\x01\n\x06Method\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x18\n\x10request_type_url\x18\x02 \x01(\t\x12\x19\n\x11request_streaming\x18\x03 \x01(\x08\x12\x19\n\x11response_type_url\x18\x04 \x01(\t\x12\x1a\n\x12response_streaming\x18\x05 \x01(\x08\x12(\n\x07options\x18\x06 \x03(\x0b\x32\x17.google.protobuf.Option\x12\'\n\x06syntax\x18\x07 \x01(\x0e\x32\x17.google.protobuf.Syntax\"#\n\x05Mixin\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04root\x18\x02 \x01(\tBv\n\x13\x63om.google.protobufB\x08\x41piProtoP\x01Z,google.golang.org/protobuf/types/known/apipb\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.api_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.google.protobufB\010ApiProtoP\001Z,google.golang.org/protobuf/types/known/apipb\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' - _API._serialized_start=113 - _API._serialized_end=370 - _METHOD._serialized_start=373 - _METHOD._serialized_end=586 - _MIXIN._serialized_start=588 - _MIXIN._serialized_end=623 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/compiler/__init__.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/compiler/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/compiler/plugin_pb2.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/compiler/plugin_pb2.py deleted file mode 100644 index 715a891370..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/compiler/plugin_pb2.py +++ /dev/null @@ -1,35 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/compiler/plugin.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n%google/protobuf/compiler/plugin.proto\x12\x18google.protobuf.compiler\x1a google/protobuf/descriptor.proto\"F\n\x07Version\x12\r\n\x05major\x18\x01 \x01(\x05\x12\r\n\x05minor\x18\x02 \x01(\x05\x12\r\n\x05patch\x18\x03 \x01(\x05\x12\x0e\n\x06suffix\x18\x04 \x01(\t\"\xba\x01\n\x14\x43odeGeneratorRequest\x12\x18\n\x10\x66ile_to_generate\x18\x01 \x03(\t\x12\x11\n\tparameter\x18\x02 \x01(\t\x12\x38\n\nproto_file\x18\x0f \x03(\x0b\x32$.google.protobuf.FileDescriptorProto\x12;\n\x10\x63ompiler_version\x18\x03 \x01(\x0b\x32!.google.protobuf.compiler.Version\"\xc1\x02\n\x15\x43odeGeneratorResponse\x12\r\n\x05\x65rror\x18\x01 \x01(\t\x12\x1a\n\x12supported_features\x18\x02 \x01(\x04\x12\x42\n\x04\x66ile\x18\x0f \x03(\x0b\x32\x34.google.protobuf.compiler.CodeGeneratorResponse.File\x1a\x7f\n\x04\x46ile\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x17\n\x0finsertion_point\x18\x02 \x01(\t\x12\x0f\n\x07\x63ontent\x18\x0f \x01(\t\x12?\n\x13generated_code_info\x18\x10 \x01(\x0b\x32\".google.protobuf.GeneratedCodeInfo\"8\n\x07\x46\x65\x61ture\x12\x10\n\x0c\x46\x45\x41TURE_NONE\x10\x00\x12\x1b\n\x17\x46\x45\x41TURE_PROTO3_OPTIONAL\x10\x01\x42W\n\x1c\x63om.google.protobuf.compilerB\x0cPluginProtosZ)google.golang.org/protobuf/types/pluginpb') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.compiler.plugin_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\034com.google.protobuf.compilerB\014PluginProtosZ)google.golang.org/protobuf/types/pluginpb' - _VERSION._serialized_start=101 - _VERSION._serialized_end=171 - _CODEGENERATORREQUEST._serialized_start=174 - _CODEGENERATORREQUEST._serialized_end=360 - _CODEGENERATORRESPONSE._serialized_start=363 - _CODEGENERATORRESPONSE._serialized_end=684 - _CODEGENERATORRESPONSE_FILE._serialized_start=499 - _CODEGENERATORRESPONSE_FILE._serialized_end=626 - _CODEGENERATORRESPONSE_FEATURE._serialized_start=628 - _CODEGENERATORRESPONSE_FEATURE._serialized_end=684 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/descriptor.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/descriptor.py deleted file mode 100644 index 5d16ae2a0c..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/descriptor.py +++ /dev/null @@ -1,1224 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Descriptors essentially contain exactly the information found in a .proto -file, in types that make this information accessible in Python. -""" - -__author__ = 'robinson@google.com (Will Robinson)' - -import threading -import warnings - -from google.protobuf.internal import api_implementation - -_USE_C_DESCRIPTORS = False -if api_implementation.Type() == 'cpp': - # Used by MakeDescriptor in cpp mode - import binascii - import os - from google.protobuf.pyext import _message - _USE_C_DESCRIPTORS = True - - -class Error(Exception): - """Base error for this module.""" - - -class TypeTransformationError(Error): - """Error transforming between python proto type and corresponding C++ type.""" - - -if _USE_C_DESCRIPTORS: - # This metaclass allows to override the behavior of code like - # isinstance(my_descriptor, FieldDescriptor) - # and make it return True when the descriptor is an instance of the extension - # type written in C++. - class DescriptorMetaclass(type): - def __instancecheck__(cls, obj): - if super(DescriptorMetaclass, cls).__instancecheck__(obj): - return True - if isinstance(obj, cls._C_DESCRIPTOR_CLASS): - return True - return False -else: - # The standard metaclass; nothing changes. - DescriptorMetaclass = type - - -class _Lock(object): - """Wrapper class of threading.Lock(), which is allowed by 'with'.""" - - def __new__(cls): - self = object.__new__(cls) - self._lock = threading.Lock() # pylint: disable=protected-access - return self - - def __enter__(self): - self._lock.acquire() - - def __exit__(self, exc_type, exc_value, exc_tb): - self._lock.release() - - -_lock = threading.Lock() - - -def _Deprecated(name): - if _Deprecated.count > 0: - _Deprecated.count -= 1 - warnings.warn( - 'Call to deprecated create function %s(). Note: Create unlinked ' - 'descriptors is going to go away. Please use get/find descriptors from ' - 'generated code or query the descriptor_pool.' - % name, - category=DeprecationWarning, stacklevel=3) - - -# Deprecated warnings will print 100 times at most which should be enough for -# users to notice and do not cause timeout. -_Deprecated.count = 100 - - -_internal_create_key = object() - - -class DescriptorBase(metaclass=DescriptorMetaclass): - - """Descriptors base class. - - This class is the base of all descriptor classes. It provides common options - related functionality. - - Attributes: - has_options: True if the descriptor has non-default options. Usually it - is not necessary to read this -- just call GetOptions() which will - happily return the default instance. However, it's sometimes useful - for efficiency, and also useful inside the protobuf implementation to - avoid some bootstrapping issues. - """ - - if _USE_C_DESCRIPTORS: - # The class, or tuple of classes, that are considered as "virtual - # subclasses" of this descriptor class. - _C_DESCRIPTOR_CLASS = () - - def __init__(self, options, serialized_options, options_class_name): - """Initialize the descriptor given its options message and the name of the - class of the options message. The name of the class is required in case - the options message is None and has to be created. - """ - self._options = options - self._options_class_name = options_class_name - self._serialized_options = serialized_options - - # Does this descriptor have non-default options? - self.has_options = (options is not None) or (serialized_options is not None) - - def _SetOptions(self, options, options_class_name): - """Sets the descriptor's options - - This function is used in generated proto2 files to update descriptor - options. It must not be used outside proto2. - """ - self._options = options - self._options_class_name = options_class_name - - # Does this descriptor have non-default options? - self.has_options = options is not None - - def GetOptions(self): - """Retrieves descriptor options. - - This method returns the options set or creates the default options for the - descriptor. - """ - if self._options: - return self._options - - from google.protobuf import descriptor_pb2 - try: - options_class = getattr(descriptor_pb2, - self._options_class_name) - except AttributeError: - raise RuntimeError('Unknown options class name %s!' % - (self._options_class_name)) - - with _lock: - if self._serialized_options is None: - self._options = options_class() - else: - self._options = _ParseOptions(options_class(), - self._serialized_options) - - return self._options - - -class _NestedDescriptorBase(DescriptorBase): - """Common class for descriptors that can be nested.""" - - def __init__(self, options, options_class_name, name, full_name, - file, containing_type, serialized_start=None, - serialized_end=None, serialized_options=None): - """Constructor. - - Args: - options: Protocol message options or None - to use default message options. - options_class_name (str): The class name of the above options. - name (str): Name of this protocol message type. - full_name (str): Fully-qualified name of this protocol message type, - which will include protocol "package" name and the name of any - enclosing types. - file (FileDescriptor): Reference to file info. - containing_type: if provided, this is a nested descriptor, with this - descriptor as parent, otherwise None. - serialized_start: The start index (inclusive) in block in the - file.serialized_pb that describes this descriptor. - serialized_end: The end index (exclusive) in block in the - file.serialized_pb that describes this descriptor. - serialized_options: Protocol message serialized options or None. - """ - super(_NestedDescriptorBase, self).__init__( - options, serialized_options, options_class_name) - - self.name = name - # TODO(falk): Add function to calculate full_name instead of having it in - # memory? - self.full_name = full_name - self.file = file - self.containing_type = containing_type - - self._serialized_start = serialized_start - self._serialized_end = serialized_end - - def CopyToProto(self, proto): - """Copies this to the matching proto in descriptor_pb2. - - Args: - proto: An empty proto instance from descriptor_pb2. - - Raises: - Error: If self couldn't be serialized, due to to few constructor - arguments. - """ - if (self.file is not None and - self._serialized_start is not None and - self._serialized_end is not None): - proto.ParseFromString(self.file.serialized_pb[ - self._serialized_start:self._serialized_end]) - else: - raise Error('Descriptor does not contain serialization.') - - -class Descriptor(_NestedDescriptorBase): - - """Descriptor for a protocol message type. - - Attributes: - name (str): Name of this protocol message type. - full_name (str): Fully-qualified name of this protocol message type, - which will include protocol "package" name and the name of any - enclosing types. - containing_type (Descriptor): Reference to the descriptor of the type - containing us, or None if this is top-level. - fields (list[FieldDescriptor]): Field descriptors for all fields in - this type. - fields_by_number (dict(int, FieldDescriptor)): Same - :class:`FieldDescriptor` objects as in :attr:`fields`, but indexed - by "number" attribute in each FieldDescriptor. - fields_by_name (dict(str, FieldDescriptor)): Same - :class:`FieldDescriptor` objects as in :attr:`fields`, but indexed by - "name" attribute in each :class:`FieldDescriptor`. - nested_types (list[Descriptor]): Descriptor references - for all protocol message types nested within this one. - nested_types_by_name (dict(str, Descriptor)): Same Descriptor - objects as in :attr:`nested_types`, but indexed by "name" attribute - in each Descriptor. - enum_types (list[EnumDescriptor]): :class:`EnumDescriptor` references - for all enums contained within this type. - enum_types_by_name (dict(str, EnumDescriptor)): Same - :class:`EnumDescriptor` objects as in :attr:`enum_types`, but - indexed by "name" attribute in each EnumDescriptor. - enum_values_by_name (dict(str, EnumValueDescriptor)): Dict mapping - from enum value name to :class:`EnumValueDescriptor` for that value. - extensions (list[FieldDescriptor]): All extensions defined directly - within this message type (NOT within a nested type). - extensions_by_name (dict(str, FieldDescriptor)): Same FieldDescriptor - objects as :attr:`extensions`, but indexed by "name" attribute of each - FieldDescriptor. - is_extendable (bool): Does this type define any extension ranges? - oneofs (list[OneofDescriptor]): The list of descriptors for oneof fields - in this message. - oneofs_by_name (dict(str, OneofDescriptor)): Same objects as in - :attr:`oneofs`, but indexed by "name" attribute. - file (FileDescriptor): Reference to file descriptor. - - """ - - if _USE_C_DESCRIPTORS: - _C_DESCRIPTOR_CLASS = _message.Descriptor - - def __new__( - cls, - name=None, - full_name=None, - filename=None, - containing_type=None, - fields=None, - nested_types=None, - enum_types=None, - extensions=None, - options=None, - serialized_options=None, - is_extendable=True, - extension_ranges=None, - oneofs=None, - file=None, # pylint: disable=redefined-builtin - serialized_start=None, - serialized_end=None, - syntax=None, - create_key=None): - _message.Message._CheckCalledFromGeneratedFile() - return _message.default_pool.FindMessageTypeByName(full_name) - - # NOTE(tmarek): The file argument redefining a builtin is nothing we can - # fix right now since we don't know how many clients already rely on the - # name of the argument. - def __init__(self, name, full_name, filename, containing_type, fields, - nested_types, enum_types, extensions, options=None, - serialized_options=None, - is_extendable=True, extension_ranges=None, oneofs=None, - file=None, serialized_start=None, serialized_end=None, # pylint: disable=redefined-builtin - syntax=None, create_key=None): - """Arguments to __init__() are as described in the description - of Descriptor fields above. - - Note that filename is an obsolete argument, that is not used anymore. - Please use file.name to access this as an attribute. - """ - if create_key is not _internal_create_key: - _Deprecated('Descriptor') - - super(Descriptor, self).__init__( - options, 'MessageOptions', name, full_name, file, - containing_type, serialized_start=serialized_start, - serialized_end=serialized_end, serialized_options=serialized_options) - - # We have fields in addition to fields_by_name and fields_by_number, - # so that: - # 1. Clients can index fields by "order in which they're listed." - # 2. Clients can easily iterate over all fields with the terse - # syntax: for f in descriptor.fields: ... - self.fields = fields - for field in self.fields: - field.containing_type = self - self.fields_by_number = dict((f.number, f) for f in fields) - self.fields_by_name = dict((f.name, f) for f in fields) - self._fields_by_camelcase_name = None - - self.nested_types = nested_types - for nested_type in nested_types: - nested_type.containing_type = self - self.nested_types_by_name = dict((t.name, t) for t in nested_types) - - self.enum_types = enum_types - for enum_type in self.enum_types: - enum_type.containing_type = self - self.enum_types_by_name = dict((t.name, t) for t in enum_types) - self.enum_values_by_name = dict( - (v.name, v) for t in enum_types for v in t.values) - - self.extensions = extensions - for extension in self.extensions: - extension.extension_scope = self - self.extensions_by_name = dict((f.name, f) for f in extensions) - self.is_extendable = is_extendable - self.extension_ranges = extension_ranges - self.oneofs = oneofs if oneofs is not None else [] - self.oneofs_by_name = dict((o.name, o) for o in self.oneofs) - for oneof in self.oneofs: - oneof.containing_type = self - self.syntax = syntax or "proto2" - - @property - def fields_by_camelcase_name(self): - """Same FieldDescriptor objects as in :attr:`fields`, but indexed by - :attr:`FieldDescriptor.camelcase_name`. - """ - if self._fields_by_camelcase_name is None: - self._fields_by_camelcase_name = dict( - (f.camelcase_name, f) for f in self.fields) - return self._fields_by_camelcase_name - - def EnumValueName(self, enum, value): - """Returns the string name of an enum value. - - This is just a small helper method to simplify a common operation. - - Args: - enum: string name of the Enum. - value: int, value of the enum. - - Returns: - string name of the enum value. - - Raises: - KeyError if either the Enum doesn't exist or the value is not a valid - value for the enum. - """ - return self.enum_types_by_name[enum].values_by_number[value].name - - def CopyToProto(self, proto): - """Copies this to a descriptor_pb2.DescriptorProto. - - Args: - proto: An empty descriptor_pb2.DescriptorProto. - """ - # This function is overridden to give a better doc comment. - super(Descriptor, self).CopyToProto(proto) - - -# TODO(robinson): We should have aggressive checking here, -# for example: -# * If you specify a repeated field, you should not be allowed -# to specify a default value. -# * [Other examples here as needed]. -# -# TODO(robinson): for this and other *Descriptor classes, we -# might also want to lock things down aggressively (e.g., -# prevent clients from setting the attributes). Having -# stronger invariants here in general will reduce the number -# of runtime checks we must do in reflection.py... -class FieldDescriptor(DescriptorBase): - - """Descriptor for a single field in a .proto file. - - Attributes: - name (str): Name of this field, exactly as it appears in .proto. - full_name (str): Name of this field, including containing scope. This is - particularly relevant for extensions. - index (int): Dense, 0-indexed index giving the order that this - field textually appears within its message in the .proto file. - number (int): Tag number declared for this field in the .proto file. - - type (int): (One of the TYPE_* constants below) Declared type. - cpp_type (int): (One of the CPPTYPE_* constants below) C++ type used to - represent this field. - - label (int): (One of the LABEL_* constants below) Tells whether this - field is optional, required, or repeated. - has_default_value (bool): True if this field has a default value defined, - otherwise false. - default_value (Varies): Default value of this field. Only - meaningful for non-repeated scalar fields. Repeated fields - should always set this to [], and non-repeated composite - fields should always set this to None. - - containing_type (Descriptor): Descriptor of the protocol message - type that contains this field. Set by the Descriptor constructor - if we're passed into one. - Somewhat confusingly, for extension fields, this is the - descriptor of the EXTENDED message, not the descriptor - of the message containing this field. (See is_extension and - extension_scope below). - message_type (Descriptor): If a composite field, a descriptor - of the message type contained in this field. Otherwise, this is None. - enum_type (EnumDescriptor): If this field contains an enum, a - descriptor of that enum. Otherwise, this is None. - - is_extension: True iff this describes an extension field. - extension_scope (Descriptor): Only meaningful if is_extension is True. - Gives the message that immediately contains this extension field. - Will be None iff we're a top-level (file-level) extension field. - - options (descriptor_pb2.FieldOptions): Protocol message field options or - None to use default field options. - - containing_oneof (OneofDescriptor): If the field is a member of a oneof - union, contains its descriptor. Otherwise, None. - - file (FileDescriptor): Reference to file descriptor. - """ - - # Must be consistent with C++ FieldDescriptor::Type enum in - # descriptor.h. - # - # TODO(robinson): Find a way to eliminate this repetition. - TYPE_DOUBLE = 1 - TYPE_FLOAT = 2 - TYPE_INT64 = 3 - TYPE_UINT64 = 4 - TYPE_INT32 = 5 - TYPE_FIXED64 = 6 - TYPE_FIXED32 = 7 - TYPE_BOOL = 8 - TYPE_STRING = 9 - TYPE_GROUP = 10 - TYPE_MESSAGE = 11 - TYPE_BYTES = 12 - TYPE_UINT32 = 13 - TYPE_ENUM = 14 - TYPE_SFIXED32 = 15 - TYPE_SFIXED64 = 16 - TYPE_SINT32 = 17 - TYPE_SINT64 = 18 - MAX_TYPE = 18 - - # Must be consistent with C++ FieldDescriptor::CppType enum in - # descriptor.h. - # - # TODO(robinson): Find a way to eliminate this repetition. - CPPTYPE_INT32 = 1 - CPPTYPE_INT64 = 2 - CPPTYPE_UINT32 = 3 - CPPTYPE_UINT64 = 4 - CPPTYPE_DOUBLE = 5 - CPPTYPE_FLOAT = 6 - CPPTYPE_BOOL = 7 - CPPTYPE_ENUM = 8 - CPPTYPE_STRING = 9 - CPPTYPE_MESSAGE = 10 - MAX_CPPTYPE = 10 - - _PYTHON_TO_CPP_PROTO_TYPE_MAP = { - TYPE_DOUBLE: CPPTYPE_DOUBLE, - TYPE_FLOAT: CPPTYPE_FLOAT, - TYPE_ENUM: CPPTYPE_ENUM, - TYPE_INT64: CPPTYPE_INT64, - TYPE_SINT64: CPPTYPE_INT64, - TYPE_SFIXED64: CPPTYPE_INT64, - TYPE_UINT64: CPPTYPE_UINT64, - TYPE_FIXED64: CPPTYPE_UINT64, - TYPE_INT32: CPPTYPE_INT32, - TYPE_SFIXED32: CPPTYPE_INT32, - TYPE_SINT32: CPPTYPE_INT32, - TYPE_UINT32: CPPTYPE_UINT32, - TYPE_FIXED32: CPPTYPE_UINT32, - TYPE_BYTES: CPPTYPE_STRING, - TYPE_STRING: CPPTYPE_STRING, - TYPE_BOOL: CPPTYPE_BOOL, - TYPE_MESSAGE: CPPTYPE_MESSAGE, - TYPE_GROUP: CPPTYPE_MESSAGE - } - - # Must be consistent with C++ FieldDescriptor::Label enum in - # descriptor.h. - # - # TODO(robinson): Find a way to eliminate this repetition. - LABEL_OPTIONAL = 1 - LABEL_REQUIRED = 2 - LABEL_REPEATED = 3 - MAX_LABEL = 3 - - # Must be consistent with C++ constants kMaxNumber, kFirstReservedNumber, - # and kLastReservedNumber in descriptor.h - MAX_FIELD_NUMBER = (1 << 29) - 1 - FIRST_RESERVED_FIELD_NUMBER = 19000 - LAST_RESERVED_FIELD_NUMBER = 19999 - - if _USE_C_DESCRIPTORS: - _C_DESCRIPTOR_CLASS = _message.FieldDescriptor - - def __new__(cls, name, full_name, index, number, type, cpp_type, label, - default_value, message_type, enum_type, containing_type, - is_extension, extension_scope, options=None, - serialized_options=None, - has_default_value=True, containing_oneof=None, json_name=None, - file=None, create_key=None): # pylint: disable=redefined-builtin - _message.Message._CheckCalledFromGeneratedFile() - if is_extension: - return _message.default_pool.FindExtensionByName(full_name) - else: - return _message.default_pool.FindFieldByName(full_name) - - def __init__(self, name, full_name, index, number, type, cpp_type, label, - default_value, message_type, enum_type, containing_type, - is_extension, extension_scope, options=None, - serialized_options=None, - has_default_value=True, containing_oneof=None, json_name=None, - file=None, create_key=None): # pylint: disable=redefined-builtin - """The arguments are as described in the description of FieldDescriptor - attributes above. - - Note that containing_type may be None, and may be set later if necessary - (to deal with circular references between message types, for example). - Likewise for extension_scope. - """ - if create_key is not _internal_create_key: - _Deprecated('FieldDescriptor') - - super(FieldDescriptor, self).__init__( - options, serialized_options, 'FieldOptions') - self.name = name - self.full_name = full_name - self.file = file - self._camelcase_name = None - if json_name is None: - self.json_name = _ToJsonName(name) - else: - self.json_name = json_name - self.index = index - self.number = number - self.type = type - self.cpp_type = cpp_type - self.label = label - self.has_default_value = has_default_value - self.default_value = default_value - self.containing_type = containing_type - self.message_type = message_type - self.enum_type = enum_type - self.is_extension = is_extension - self.extension_scope = extension_scope - self.containing_oneof = containing_oneof - if api_implementation.Type() == 'cpp': - if is_extension: - self._cdescriptor = _message.default_pool.FindExtensionByName(full_name) - else: - self._cdescriptor = _message.default_pool.FindFieldByName(full_name) - else: - self._cdescriptor = None - - @property - def camelcase_name(self): - """Camelcase name of this field. - - Returns: - str: the name in CamelCase. - """ - if self._camelcase_name is None: - self._camelcase_name = _ToCamelCase(self.name) - return self._camelcase_name - - @property - def has_presence(self): - """Whether the field distinguishes between unpopulated and default values. - - Raises: - RuntimeError: singular field that is not linked with message nor file. - """ - if self.label == FieldDescriptor.LABEL_REPEATED: - return False - if (self.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE or - self.containing_oneof): - return True - if hasattr(self.file, 'syntax'): - return self.file.syntax == 'proto2' - if hasattr(self.message_type, 'syntax'): - return self.message_type.syntax == 'proto2' - raise RuntimeError( - 'has_presence is not ready to use because field %s is not' - ' linked with message type nor file' % self.full_name) - - @staticmethod - def ProtoTypeToCppProtoType(proto_type): - """Converts from a Python proto type to a C++ Proto Type. - - The Python ProtocolBuffer classes specify both the 'Python' datatype and the - 'C++' datatype - and they're not the same. This helper method should - translate from one to another. - - Args: - proto_type: the Python proto type (descriptor.FieldDescriptor.TYPE_*) - Returns: - int: descriptor.FieldDescriptor.CPPTYPE_*, the C++ type. - Raises: - TypeTransformationError: when the Python proto type isn't known. - """ - try: - return FieldDescriptor._PYTHON_TO_CPP_PROTO_TYPE_MAP[proto_type] - except KeyError: - raise TypeTransformationError('Unknown proto_type: %s' % proto_type) - - -class EnumDescriptor(_NestedDescriptorBase): - - """Descriptor for an enum defined in a .proto file. - - Attributes: - name (str): Name of the enum type. - full_name (str): Full name of the type, including package name - and any enclosing type(s). - - values (list[EnumValueDescriptor]): List of the values - in this enum. - values_by_name (dict(str, EnumValueDescriptor)): Same as :attr:`values`, - but indexed by the "name" field of each EnumValueDescriptor. - values_by_number (dict(int, EnumValueDescriptor)): Same as :attr:`values`, - but indexed by the "number" field of each EnumValueDescriptor. - containing_type (Descriptor): Descriptor of the immediate containing - type of this enum, or None if this is an enum defined at the - top level in a .proto file. Set by Descriptor's constructor - if we're passed into one. - file (FileDescriptor): Reference to file descriptor. - options (descriptor_pb2.EnumOptions): Enum options message or - None to use default enum options. - """ - - if _USE_C_DESCRIPTORS: - _C_DESCRIPTOR_CLASS = _message.EnumDescriptor - - def __new__(cls, name, full_name, filename, values, - containing_type=None, options=None, - serialized_options=None, file=None, # pylint: disable=redefined-builtin - serialized_start=None, serialized_end=None, create_key=None): - _message.Message._CheckCalledFromGeneratedFile() - return _message.default_pool.FindEnumTypeByName(full_name) - - def __init__(self, name, full_name, filename, values, - containing_type=None, options=None, - serialized_options=None, file=None, # pylint: disable=redefined-builtin - serialized_start=None, serialized_end=None, create_key=None): - """Arguments are as described in the attribute description above. - - Note that filename is an obsolete argument, that is not used anymore. - Please use file.name to access this as an attribute. - """ - if create_key is not _internal_create_key: - _Deprecated('EnumDescriptor') - - super(EnumDescriptor, self).__init__( - options, 'EnumOptions', name, full_name, file, - containing_type, serialized_start=serialized_start, - serialized_end=serialized_end, serialized_options=serialized_options) - - self.values = values - for value in self.values: - value.type = self - self.values_by_name = dict((v.name, v) for v in values) - # Values are reversed to ensure that the first alias is retained. - self.values_by_number = dict((v.number, v) for v in reversed(values)) - - def CopyToProto(self, proto): - """Copies this to a descriptor_pb2.EnumDescriptorProto. - - Args: - proto (descriptor_pb2.EnumDescriptorProto): An empty descriptor proto. - """ - # This function is overridden to give a better doc comment. - super(EnumDescriptor, self).CopyToProto(proto) - - -class EnumValueDescriptor(DescriptorBase): - - """Descriptor for a single value within an enum. - - Attributes: - name (str): Name of this value. - index (int): Dense, 0-indexed index giving the order that this - value appears textually within its enum in the .proto file. - number (int): Actual number assigned to this enum value. - type (EnumDescriptor): :class:`EnumDescriptor` to which this value - belongs. Set by :class:`EnumDescriptor`'s constructor if we're - passed into one. - options (descriptor_pb2.EnumValueOptions): Enum value options message or - None to use default enum value options options. - """ - - if _USE_C_DESCRIPTORS: - _C_DESCRIPTOR_CLASS = _message.EnumValueDescriptor - - def __new__(cls, name, index, number, - type=None, # pylint: disable=redefined-builtin - options=None, serialized_options=None, create_key=None): - _message.Message._CheckCalledFromGeneratedFile() - # There is no way we can build a complete EnumValueDescriptor with the - # given parameters (the name of the Enum is not known, for example). - # Fortunately generated files just pass it to the EnumDescriptor() - # constructor, which will ignore it, so returning None is good enough. - return None - - def __init__(self, name, index, number, - type=None, # pylint: disable=redefined-builtin - options=None, serialized_options=None, create_key=None): - """Arguments are as described in the attribute description above.""" - if create_key is not _internal_create_key: - _Deprecated('EnumValueDescriptor') - - super(EnumValueDescriptor, self).__init__( - options, serialized_options, 'EnumValueOptions') - self.name = name - self.index = index - self.number = number - self.type = type - - -class OneofDescriptor(DescriptorBase): - """Descriptor for a oneof field. - - Attributes: - name (str): Name of the oneof field. - full_name (str): Full name of the oneof field, including package name. - index (int): 0-based index giving the order of the oneof field inside - its containing type. - containing_type (Descriptor): :class:`Descriptor` of the protocol message - type that contains this field. Set by the :class:`Descriptor` constructor - if we're passed into one. - fields (list[FieldDescriptor]): The list of field descriptors this - oneof can contain. - """ - - if _USE_C_DESCRIPTORS: - _C_DESCRIPTOR_CLASS = _message.OneofDescriptor - - def __new__( - cls, name, full_name, index, containing_type, fields, options=None, - serialized_options=None, create_key=None): - _message.Message._CheckCalledFromGeneratedFile() - return _message.default_pool.FindOneofByName(full_name) - - def __init__( - self, name, full_name, index, containing_type, fields, options=None, - serialized_options=None, create_key=None): - """Arguments are as described in the attribute description above.""" - if create_key is not _internal_create_key: - _Deprecated('OneofDescriptor') - - super(OneofDescriptor, self).__init__( - options, serialized_options, 'OneofOptions') - self.name = name - self.full_name = full_name - self.index = index - self.containing_type = containing_type - self.fields = fields - - -class ServiceDescriptor(_NestedDescriptorBase): - - """Descriptor for a service. - - Attributes: - name (str): Name of the service. - full_name (str): Full name of the service, including package name. - index (int): 0-indexed index giving the order that this services - definition appears within the .proto file. - methods (list[MethodDescriptor]): List of methods provided by this - service. - methods_by_name (dict(str, MethodDescriptor)): Same - :class:`MethodDescriptor` objects as in :attr:`methods_by_name`, but - indexed by "name" attribute in each :class:`MethodDescriptor`. - options (descriptor_pb2.ServiceOptions): Service options message or - None to use default service options. - file (FileDescriptor): Reference to file info. - """ - - if _USE_C_DESCRIPTORS: - _C_DESCRIPTOR_CLASS = _message.ServiceDescriptor - - def __new__( - cls, - name=None, - full_name=None, - index=None, - methods=None, - options=None, - serialized_options=None, - file=None, # pylint: disable=redefined-builtin - serialized_start=None, - serialized_end=None, - create_key=None): - _message.Message._CheckCalledFromGeneratedFile() # pylint: disable=protected-access - return _message.default_pool.FindServiceByName(full_name) - - def __init__(self, name, full_name, index, methods, options=None, - serialized_options=None, file=None, # pylint: disable=redefined-builtin - serialized_start=None, serialized_end=None, create_key=None): - if create_key is not _internal_create_key: - _Deprecated('ServiceDescriptor') - - super(ServiceDescriptor, self).__init__( - options, 'ServiceOptions', name, full_name, file, - None, serialized_start=serialized_start, - serialized_end=serialized_end, serialized_options=serialized_options) - self.index = index - self.methods = methods - self.methods_by_name = dict((m.name, m) for m in methods) - # Set the containing service for each method in this service. - for method in self.methods: - method.containing_service = self - - def FindMethodByName(self, name): - """Searches for the specified method, and returns its descriptor. - - Args: - name (str): Name of the method. - Returns: - MethodDescriptor or None: the descriptor for the requested method, if - found. - """ - return self.methods_by_name.get(name, None) - - def CopyToProto(self, proto): - """Copies this to a descriptor_pb2.ServiceDescriptorProto. - - Args: - proto (descriptor_pb2.ServiceDescriptorProto): An empty descriptor proto. - """ - # This function is overridden to give a better doc comment. - super(ServiceDescriptor, self).CopyToProto(proto) - - -class MethodDescriptor(DescriptorBase): - - """Descriptor for a method in a service. - - Attributes: - name (str): Name of the method within the service. - full_name (str): Full name of method. - index (int): 0-indexed index of the method inside the service. - containing_service (ServiceDescriptor): The service that contains this - method. - input_type (Descriptor): The descriptor of the message that this method - accepts. - output_type (Descriptor): The descriptor of the message that this method - returns. - client_streaming (bool): Whether this method uses client streaming. - server_streaming (bool): Whether this method uses server streaming. - options (descriptor_pb2.MethodOptions or None): Method options message, or - None to use default method options. - """ - - if _USE_C_DESCRIPTORS: - _C_DESCRIPTOR_CLASS = _message.MethodDescriptor - - def __new__(cls, - name, - full_name, - index, - containing_service, - input_type, - output_type, - client_streaming=False, - server_streaming=False, - options=None, - serialized_options=None, - create_key=None): - _message.Message._CheckCalledFromGeneratedFile() # pylint: disable=protected-access - return _message.default_pool.FindMethodByName(full_name) - - def __init__(self, - name, - full_name, - index, - containing_service, - input_type, - output_type, - client_streaming=False, - server_streaming=False, - options=None, - serialized_options=None, - create_key=None): - """The arguments are as described in the description of MethodDescriptor - attributes above. - - Note that containing_service may be None, and may be set later if necessary. - """ - if create_key is not _internal_create_key: - _Deprecated('MethodDescriptor') - - super(MethodDescriptor, self).__init__( - options, serialized_options, 'MethodOptions') - self.name = name - self.full_name = full_name - self.index = index - self.containing_service = containing_service - self.input_type = input_type - self.output_type = output_type - self.client_streaming = client_streaming - self.server_streaming = server_streaming - - def CopyToProto(self, proto): - """Copies this to a descriptor_pb2.MethodDescriptorProto. - - Args: - proto (descriptor_pb2.MethodDescriptorProto): An empty descriptor proto. - - Raises: - Error: If self couldn't be serialized, due to too few constructor - arguments. - """ - if self.containing_service is not None: - from google.protobuf import descriptor_pb2 - service_proto = descriptor_pb2.ServiceDescriptorProto() - self.containing_service.CopyToProto(service_proto) - proto.CopyFrom(service_proto.method[self.index]) - else: - raise Error('Descriptor does not contain a service.') - - -class FileDescriptor(DescriptorBase): - """Descriptor for a file. Mimics the descriptor_pb2.FileDescriptorProto. - - Note that :attr:`enum_types_by_name`, :attr:`extensions_by_name`, and - :attr:`dependencies` fields are only set by the - :py:mod:`google.protobuf.message_factory` module, and not by the generated - proto code. - - Attributes: - name (str): Name of file, relative to root of source tree. - package (str): Name of the package - syntax (str): string indicating syntax of the file (can be "proto2" or - "proto3") - serialized_pb (bytes): Byte string of serialized - :class:`descriptor_pb2.FileDescriptorProto`. - dependencies (list[FileDescriptor]): List of other :class:`FileDescriptor` - objects this :class:`FileDescriptor` depends on. - public_dependencies (list[FileDescriptor]): A product of - :attr:`dependencies`, which were declared as "public". - message_types_by_name (dict(str, Descriptor)): Mapping from message names - to their :class:`Descriptor`. - enum_types_by_name (dict(str, EnumDescriptor)): Mapping from enum names to - their :class:`EnumDescriptor`. - extensions_by_name (dict(str, FieldDescriptor)): Mapping from extension - names declared at file scope to their :class:`FieldDescriptor`. - services_by_name (dict(str, ServiceDescriptor)): Mapping from services' - names to their :class:`ServiceDescriptor`. - pool (DescriptorPool): The pool this descriptor belongs to. When not - passed to the constructor, the global default pool is used. - """ - - if _USE_C_DESCRIPTORS: - _C_DESCRIPTOR_CLASS = _message.FileDescriptor - - def __new__(cls, name, package, options=None, - serialized_options=None, serialized_pb=None, - dependencies=None, public_dependencies=None, - syntax=None, pool=None, create_key=None): - # FileDescriptor() is called from various places, not only from generated - # files, to register dynamic proto files and messages. - # pylint: disable=g-explicit-bool-comparison - if serialized_pb == b'': - # Cpp generated code must be linked in if serialized_pb is '' - try: - return _message.default_pool.FindFileByName(name) - except KeyError: - raise RuntimeError('Please link in cpp generated lib for %s' % (name)) - elif serialized_pb: - return _message.default_pool.AddSerializedFile(serialized_pb) - else: - return super(FileDescriptor, cls).__new__(cls) - - def __init__(self, name, package, options=None, - serialized_options=None, serialized_pb=None, - dependencies=None, public_dependencies=None, - syntax=None, pool=None, create_key=None): - """Constructor.""" - if create_key is not _internal_create_key: - _Deprecated('FileDescriptor') - - super(FileDescriptor, self).__init__( - options, serialized_options, 'FileOptions') - - if pool is None: - from google.protobuf import descriptor_pool - pool = descriptor_pool.Default() - self.pool = pool - self.message_types_by_name = {} - self.name = name - self.package = package - self.syntax = syntax or "proto2" - self.serialized_pb = serialized_pb - - self.enum_types_by_name = {} - self.extensions_by_name = {} - self.services_by_name = {} - self.dependencies = (dependencies or []) - self.public_dependencies = (public_dependencies or []) - - def CopyToProto(self, proto): - """Copies this to a descriptor_pb2.FileDescriptorProto. - - Args: - proto: An empty descriptor_pb2.FileDescriptorProto. - """ - proto.ParseFromString(self.serialized_pb) - - -def _ParseOptions(message, string): - """Parses serialized options. - - This helper function is used to parse serialized options in generated - proto2 files. It must not be used outside proto2. - """ - message.ParseFromString(string) - return message - - -def _ToCamelCase(name): - """Converts name to camel-case and returns it.""" - capitalize_next = False - result = [] - - for c in name: - if c == '_': - if result: - capitalize_next = True - elif capitalize_next: - result.append(c.upper()) - capitalize_next = False - else: - result += c - - # Lower-case the first letter. - if result and result[0].isupper(): - result[0] = result[0].lower() - return ''.join(result) - - -def _OptionsOrNone(descriptor_proto): - """Returns the value of the field `options`, or None if it is not set.""" - if descriptor_proto.HasField('options'): - return descriptor_proto.options - else: - return None - - -def _ToJsonName(name): - """Converts name to Json name and returns it.""" - capitalize_next = False - result = [] - - for c in name: - if c == '_': - capitalize_next = True - elif capitalize_next: - result.append(c.upper()) - capitalize_next = False - else: - result += c - - return ''.join(result) - - -def MakeDescriptor(desc_proto, package='', build_file_if_cpp=True, - syntax=None): - """Make a protobuf Descriptor given a DescriptorProto protobuf. - - Handles nested descriptors. Note that this is limited to the scope of defining - a message inside of another message. Composite fields can currently only be - resolved if the message is defined in the same scope as the field. - - Args: - desc_proto: The descriptor_pb2.DescriptorProto protobuf message. - package: Optional package name for the new message Descriptor (string). - build_file_if_cpp: Update the C++ descriptor pool if api matches. - Set to False on recursion, so no duplicates are created. - syntax: The syntax/semantics that should be used. Set to "proto3" to get - proto3 field presence semantics. - Returns: - A Descriptor for protobuf messages. - """ - if api_implementation.Type() == 'cpp' and build_file_if_cpp: - # The C++ implementation requires all descriptors to be backed by the same - # definition in the C++ descriptor pool. To do this, we build a - # FileDescriptorProto with the same definition as this descriptor and build - # it into the pool. - from google.protobuf import descriptor_pb2 - file_descriptor_proto = descriptor_pb2.FileDescriptorProto() - file_descriptor_proto.message_type.add().MergeFrom(desc_proto) - - # Generate a random name for this proto file to prevent conflicts with any - # imported ones. We need to specify a file name so the descriptor pool - # accepts our FileDescriptorProto, but it is not important what that file - # name is actually set to. - proto_name = binascii.hexlify(os.urandom(16)).decode('ascii') - - if package: - file_descriptor_proto.name = os.path.join(package.replace('.', '/'), - proto_name + '.proto') - file_descriptor_proto.package = package - else: - file_descriptor_proto.name = proto_name + '.proto' - - _message.default_pool.Add(file_descriptor_proto) - result = _message.default_pool.FindFileByName(file_descriptor_proto.name) - - if _USE_C_DESCRIPTORS: - return result.message_types_by_name[desc_proto.name] - - full_message_name = [desc_proto.name] - if package: full_message_name.insert(0, package) - - # Create Descriptors for enum types - enum_types = {} - for enum_proto in desc_proto.enum_type: - full_name = '.'.join(full_message_name + [enum_proto.name]) - enum_desc = EnumDescriptor( - enum_proto.name, full_name, None, [ - EnumValueDescriptor(enum_val.name, ii, enum_val.number, - create_key=_internal_create_key) - for ii, enum_val in enumerate(enum_proto.value)], - create_key=_internal_create_key) - enum_types[full_name] = enum_desc - - # Create Descriptors for nested types - nested_types = {} - for nested_proto in desc_proto.nested_type: - full_name = '.'.join(full_message_name + [nested_proto.name]) - # Nested types are just those defined inside of the message, not all types - # used by fields in the message, so no loops are possible here. - nested_desc = MakeDescriptor(nested_proto, - package='.'.join(full_message_name), - build_file_if_cpp=False, - syntax=syntax) - nested_types[full_name] = nested_desc - - fields = [] - for field_proto in desc_proto.field: - full_name = '.'.join(full_message_name + [field_proto.name]) - enum_desc = None - nested_desc = None - if field_proto.json_name: - json_name = field_proto.json_name - else: - json_name = None - if field_proto.HasField('type_name'): - type_name = field_proto.type_name - full_type_name = '.'.join(full_message_name + - [type_name[type_name.rfind('.')+1:]]) - if full_type_name in nested_types: - nested_desc = nested_types[full_type_name] - elif full_type_name in enum_types: - enum_desc = enum_types[full_type_name] - # Else type_name references a non-local type, which isn't implemented - field = FieldDescriptor( - field_proto.name, full_name, field_proto.number - 1, - field_proto.number, field_proto.type, - FieldDescriptor.ProtoTypeToCppProtoType(field_proto.type), - field_proto.label, None, nested_desc, enum_desc, None, False, None, - options=_OptionsOrNone(field_proto), has_default_value=False, - json_name=json_name, create_key=_internal_create_key) - fields.append(field) - - desc_name = '.'.join(full_message_name) - return Descriptor(desc_proto.name, desc_name, None, None, fields, - list(nested_types.values()), list(enum_types.values()), [], - options=_OptionsOrNone(desc_proto), - create_key=_internal_create_key) diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/descriptor_database.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/descriptor_database.py deleted file mode 100644 index 073eddc711..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/descriptor_database.py +++ /dev/null @@ -1,177 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Provides a container for DescriptorProtos.""" - -__author__ = 'matthewtoia@google.com (Matt Toia)' - -import warnings - - -class Error(Exception): - pass - - -class DescriptorDatabaseConflictingDefinitionError(Error): - """Raised when a proto is added with the same name & different descriptor.""" - - -class DescriptorDatabase(object): - """A container accepting FileDescriptorProtos and maps DescriptorProtos.""" - - def __init__(self): - self._file_desc_protos_by_file = {} - self._file_desc_protos_by_symbol = {} - - def Add(self, file_desc_proto): - """Adds the FileDescriptorProto and its types to this database. - - Args: - file_desc_proto: The FileDescriptorProto to add. - Raises: - DescriptorDatabaseConflictingDefinitionError: if an attempt is made to - add a proto with the same name but different definition than an - existing proto in the database. - """ - proto_name = file_desc_proto.name - if proto_name not in self._file_desc_protos_by_file: - self._file_desc_protos_by_file[proto_name] = file_desc_proto - elif self._file_desc_protos_by_file[proto_name] != file_desc_proto: - raise DescriptorDatabaseConflictingDefinitionError( - '%s already added, but with different descriptor.' % proto_name) - else: - return - - # Add all the top-level descriptors to the index. - package = file_desc_proto.package - for message in file_desc_proto.message_type: - for name in _ExtractSymbols(message, package): - self._AddSymbol(name, file_desc_proto) - for enum in file_desc_proto.enum_type: - self._AddSymbol(('.'.join((package, enum.name))), file_desc_proto) - for enum_value in enum.value: - self._file_desc_protos_by_symbol[ - '.'.join((package, enum_value.name))] = file_desc_proto - for extension in file_desc_proto.extension: - self._AddSymbol(('.'.join((package, extension.name))), file_desc_proto) - for service in file_desc_proto.service: - self._AddSymbol(('.'.join((package, service.name))), file_desc_proto) - - def FindFileByName(self, name): - """Finds the file descriptor proto by file name. - - Typically the file name is a relative path ending to a .proto file. The - proto with the given name will have to have been added to this database - using the Add method or else an error will be raised. - - Args: - name: The file name to find. - - Returns: - The file descriptor proto matching the name. - - Raises: - KeyError if no file by the given name was added. - """ - - return self._file_desc_protos_by_file[name] - - def FindFileContainingSymbol(self, symbol): - """Finds the file descriptor proto containing the specified symbol. - - The symbol should be a fully qualified name including the file descriptor's - package and any containing messages. Some examples: - - 'some.package.name.Message' - 'some.package.name.Message.NestedEnum' - 'some.package.name.Message.some_field' - - The file descriptor proto containing the specified symbol must be added to - this database using the Add method or else an error will be raised. - - Args: - symbol: The fully qualified symbol name. - - Returns: - The file descriptor proto containing the symbol. - - Raises: - KeyError if no file contains the specified symbol. - """ - try: - return self._file_desc_protos_by_symbol[symbol] - except KeyError: - # Fields, enum values, and nested extensions are not in - # _file_desc_protos_by_symbol. Try to find the top level - # descriptor. Non-existent nested symbol under a valid top level - # descriptor can also be found. The behavior is the same with - # protobuf C++. - top_level, _, _ = symbol.rpartition('.') - try: - return self._file_desc_protos_by_symbol[top_level] - except KeyError: - # Raise the original symbol as a KeyError for better diagnostics. - raise KeyError(symbol) - - def FindFileContainingExtension(self, extendee_name, extension_number): - # TODO(jieluo): implement this API. - return None - - def FindAllExtensionNumbers(self, extendee_name): - # TODO(jieluo): implement this API. - return [] - - def _AddSymbol(self, name, file_desc_proto): - if name in self._file_desc_protos_by_symbol: - warn_msg = ('Conflict register for file "' + file_desc_proto.name + - '": ' + name + - ' is already defined in file "' + - self._file_desc_protos_by_symbol[name].name + '"') - warnings.warn(warn_msg, RuntimeWarning) - self._file_desc_protos_by_symbol[name] = file_desc_proto - - -def _ExtractSymbols(desc_proto, package): - """Pulls out all the symbols from a descriptor proto. - - Args: - desc_proto: The proto to extract symbols from. - package: The package containing the descriptor type. - - Yields: - The fully qualified name found in the descriptor. - """ - message_name = package + '.' + desc_proto.name if package else desc_proto.name - yield message_name - for nested_type in desc_proto.nested_type: - for symbol in _ExtractSymbols(nested_type, message_name): - yield symbol - for enum_type in desc_proto.enum_type: - yield '.'.join((message_name, enum_type.name)) diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/descriptor_pb2.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/descriptor_pb2.py deleted file mode 100644 index f570386432..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/descriptor_pb2.py +++ /dev/null @@ -1,1925 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/descriptor.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR = _descriptor.FileDescriptor( - name='google/protobuf/descriptor.proto', - package='google.protobuf', - syntax='proto2', - serialized_options=None, - create_key=_descriptor._internal_create_key, - serialized_pb=b'\n google/protobuf/descriptor.proto\x12\x0fgoogle.protobuf\"G\n\x11\x46ileDescriptorSet\x12\x32\n\x04\x66ile\x18\x01 \x03(\x0b\x32$.google.protobuf.FileDescriptorProto\"\xdb\x03\n\x13\x46ileDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07package\x18\x02 \x01(\t\x12\x12\n\ndependency\x18\x03 \x03(\t\x12\x19\n\x11public_dependency\x18\n \x03(\x05\x12\x17\n\x0fweak_dependency\x18\x0b \x03(\x05\x12\x36\n\x0cmessage_type\x18\x04 \x03(\x0b\x32 .google.protobuf.DescriptorProto\x12\x37\n\tenum_type\x18\x05 \x03(\x0b\x32$.google.protobuf.EnumDescriptorProto\x12\x38\n\x07service\x18\x06 \x03(\x0b\x32\'.google.protobuf.ServiceDescriptorProto\x12\x38\n\textension\x18\x07 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProto\x12-\n\x07options\x18\x08 \x01(\x0b\x32\x1c.google.protobuf.FileOptions\x12\x39\n\x10source_code_info\x18\t \x01(\x0b\x32\x1f.google.protobuf.SourceCodeInfo\x12\x0e\n\x06syntax\x18\x0c \x01(\t\"\xa9\x05\n\x0f\x44\x65scriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x34\n\x05\x66ield\x18\x02 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProto\x12\x38\n\textension\x18\x06 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProto\x12\x35\n\x0bnested_type\x18\x03 \x03(\x0b\x32 .google.protobuf.DescriptorProto\x12\x37\n\tenum_type\x18\x04 \x03(\x0b\x32$.google.protobuf.EnumDescriptorProto\x12H\n\x0f\x65xtension_range\x18\x05 \x03(\x0b\x32/.google.protobuf.DescriptorProto.ExtensionRange\x12\x39\n\noneof_decl\x18\x08 \x03(\x0b\x32%.google.protobuf.OneofDescriptorProto\x12\x30\n\x07options\x18\x07 \x01(\x0b\x32\x1f.google.protobuf.MessageOptions\x12\x46\n\x0ereserved_range\x18\t \x03(\x0b\x32..google.protobuf.DescriptorProto.ReservedRange\x12\x15\n\rreserved_name\x18\n \x03(\t\x1a\x65\n\x0e\x45xtensionRange\x12\r\n\x05start\x18\x01 \x01(\x05\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x05\x12\x37\n\x07options\x18\x03 \x01(\x0b\x32&.google.protobuf.ExtensionRangeOptions\x1a+\n\rReservedRange\x12\r\n\x05start\x18\x01 \x01(\x05\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x05\"g\n\x15\x45xtensionRangeOptions\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xd5\x05\n\x14\x46ieldDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06number\x18\x03 \x01(\x05\x12:\n\x05label\x18\x04 \x01(\x0e\x32+.google.protobuf.FieldDescriptorProto.Label\x12\x38\n\x04type\x18\x05 \x01(\x0e\x32*.google.protobuf.FieldDescriptorProto.Type\x12\x11\n\ttype_name\x18\x06 \x01(\t\x12\x10\n\x08\x65xtendee\x18\x02 \x01(\t\x12\x15\n\rdefault_value\x18\x07 \x01(\t\x12\x13\n\x0boneof_index\x18\t \x01(\x05\x12\x11\n\tjson_name\x18\n \x01(\t\x12.\n\x07options\x18\x08 \x01(\x0b\x32\x1d.google.protobuf.FieldOptions\x12\x17\n\x0fproto3_optional\x18\x11 \x01(\x08\"\xb6\x02\n\x04Type\x12\x0f\n\x0bTYPE_DOUBLE\x10\x01\x12\x0e\n\nTYPE_FLOAT\x10\x02\x12\x0e\n\nTYPE_INT64\x10\x03\x12\x0f\n\x0bTYPE_UINT64\x10\x04\x12\x0e\n\nTYPE_INT32\x10\x05\x12\x10\n\x0cTYPE_FIXED64\x10\x06\x12\x10\n\x0cTYPE_FIXED32\x10\x07\x12\r\n\tTYPE_BOOL\x10\x08\x12\x0f\n\x0bTYPE_STRING\x10\t\x12\x0e\n\nTYPE_GROUP\x10\n\x12\x10\n\x0cTYPE_MESSAGE\x10\x0b\x12\x0e\n\nTYPE_BYTES\x10\x0c\x12\x0f\n\x0bTYPE_UINT32\x10\r\x12\r\n\tTYPE_ENUM\x10\x0e\x12\x11\n\rTYPE_SFIXED32\x10\x0f\x12\x11\n\rTYPE_SFIXED64\x10\x10\x12\x0f\n\x0bTYPE_SINT32\x10\x11\x12\x0f\n\x0bTYPE_SINT64\x10\x12\"C\n\x05Label\x12\x12\n\x0eLABEL_OPTIONAL\x10\x01\x12\x12\n\x0eLABEL_REQUIRED\x10\x02\x12\x12\n\x0eLABEL_REPEATED\x10\x03\"T\n\x14OneofDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12.\n\x07options\x18\x02 \x01(\x0b\x32\x1d.google.protobuf.OneofOptions\"\xa4\x02\n\x13\x45numDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x38\n\x05value\x18\x02 \x03(\x0b\x32).google.protobuf.EnumValueDescriptorProto\x12-\n\x07options\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.EnumOptions\x12N\n\x0ereserved_range\x18\x04 \x03(\x0b\x32\x36.google.protobuf.EnumDescriptorProto.EnumReservedRange\x12\x15\n\rreserved_name\x18\x05 \x03(\t\x1a/\n\x11\x45numReservedRange\x12\r\n\x05start\x18\x01 \x01(\x05\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x05\"l\n\x18\x45numValueDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06number\x18\x02 \x01(\x05\x12\x32\n\x07options\x18\x03 \x01(\x0b\x32!.google.protobuf.EnumValueOptions\"\x90\x01\n\x16ServiceDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x36\n\x06method\x18\x02 \x03(\x0b\x32&.google.protobuf.MethodDescriptorProto\x12\x30\n\x07options\x18\x03 \x01(\x0b\x32\x1f.google.protobuf.ServiceOptions\"\xc1\x01\n\x15MethodDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x12\n\ninput_type\x18\x02 \x01(\t\x12\x13\n\x0boutput_type\x18\x03 \x01(\t\x12/\n\x07options\x18\x04 \x01(\x0b\x32\x1e.google.protobuf.MethodOptions\x12\x1f\n\x10\x63lient_streaming\x18\x05 \x01(\x08:\x05\x66\x61lse\x12\x1f\n\x10server_streaming\x18\x06 \x01(\x08:\x05\x66\x61lse\"\xa5\x06\n\x0b\x46ileOptions\x12\x14\n\x0cjava_package\x18\x01 \x01(\t\x12\x1c\n\x14java_outer_classname\x18\x08 \x01(\t\x12\"\n\x13java_multiple_files\x18\n \x01(\x08:\x05\x66\x61lse\x12)\n\x1djava_generate_equals_and_hash\x18\x14 \x01(\x08\x42\x02\x18\x01\x12%\n\x16java_string_check_utf8\x18\x1b \x01(\x08:\x05\x66\x61lse\x12\x46\n\x0coptimize_for\x18\t \x01(\x0e\x32).google.protobuf.FileOptions.OptimizeMode:\x05SPEED\x12\x12\n\ngo_package\x18\x0b \x01(\t\x12\"\n\x13\x63\x63_generic_services\x18\x10 \x01(\x08:\x05\x66\x61lse\x12$\n\x15java_generic_services\x18\x11 \x01(\x08:\x05\x66\x61lse\x12\"\n\x13py_generic_services\x18\x12 \x01(\x08:\x05\x66\x61lse\x12#\n\x14php_generic_services\x18* \x01(\x08:\x05\x66\x61lse\x12\x19\n\ndeprecated\x18\x17 \x01(\x08:\x05\x66\x61lse\x12\x1e\n\x10\x63\x63_enable_arenas\x18\x1f \x01(\x08:\x04true\x12\x19\n\x11objc_class_prefix\x18$ \x01(\t\x12\x18\n\x10\x63sharp_namespace\x18% \x01(\t\x12\x14\n\x0cswift_prefix\x18\' \x01(\t\x12\x18\n\x10php_class_prefix\x18( \x01(\t\x12\x15\n\rphp_namespace\x18) \x01(\t\x12\x1e\n\x16php_metadata_namespace\x18, \x01(\t\x12\x14\n\x0cruby_package\x18- \x01(\t\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption\":\n\x0cOptimizeMode\x12\t\n\x05SPEED\x10\x01\x12\r\n\tCODE_SIZE\x10\x02\x12\x10\n\x0cLITE_RUNTIME\x10\x03*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08&\x10\'\"\x84\x02\n\x0eMessageOptions\x12&\n\x17message_set_wire_format\x18\x01 \x01(\x08:\x05\x66\x61lse\x12.\n\x1fno_standard_descriptor_accessor\x18\x02 \x01(\x08:\x05\x66\x61lse\x12\x19\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lse\x12\x11\n\tmap_entry\x18\x07 \x01(\x08\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08\x04\x10\x05J\x04\x08\x05\x10\x06J\x04\x08\x06\x10\x07J\x04\x08\x08\x10\tJ\x04\x08\t\x10\n\"\xbe\x03\n\x0c\x46ieldOptions\x12:\n\x05\x63type\x18\x01 \x01(\x0e\x32#.google.protobuf.FieldOptions.CType:\x06STRING\x12\x0e\n\x06packed\x18\x02 \x01(\x08\x12?\n\x06jstype\x18\x06 \x01(\x0e\x32$.google.protobuf.FieldOptions.JSType:\tJS_NORMAL\x12\x13\n\x04lazy\x18\x05 \x01(\x08:\x05\x66\x61lse\x12\x1e\n\x0funverified_lazy\x18\x0f \x01(\x08:\x05\x66\x61lse\x12\x19\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lse\x12\x13\n\x04weak\x18\n \x01(\x08:\x05\x66\x61lse\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption\"/\n\x05\x43Type\x12\n\n\x06STRING\x10\x00\x12\x08\n\x04\x43ORD\x10\x01\x12\x10\n\x0cSTRING_PIECE\x10\x02\"5\n\x06JSType\x12\r\n\tJS_NORMAL\x10\x00\x12\r\n\tJS_STRING\x10\x01\x12\r\n\tJS_NUMBER\x10\x02*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08\x04\x10\x05\"^\n\x0cOneofOptions\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\x93\x01\n\x0b\x45numOptions\x12\x13\n\x0b\x61llow_alias\x18\x02 \x01(\x08\x12\x19\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lse\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08\x05\x10\x06\"}\n\x10\x45numValueOptions\x12\x19\n\ndeprecated\x18\x01 \x01(\x08:\x05\x66\x61lse\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"{\n\x0eServiceOptions\x12\x19\n\ndeprecated\x18! \x01(\x08:\x05\x66\x61lse\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xad\x02\n\rMethodOptions\x12\x19\n\ndeprecated\x18! \x01(\x08:\x05\x66\x61lse\x12_\n\x11idempotency_level\x18\" \x01(\x0e\x32/.google.protobuf.MethodOptions.IdempotencyLevel:\x13IDEMPOTENCY_UNKNOWN\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption\"P\n\x10IdempotencyLevel\x12\x17\n\x13IDEMPOTENCY_UNKNOWN\x10\x00\x12\x13\n\x0fNO_SIDE_EFFECTS\x10\x01\x12\x0e\n\nIDEMPOTENT\x10\x02*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\x9e\x02\n\x13UninterpretedOption\x12;\n\x04name\x18\x02 \x03(\x0b\x32-.google.protobuf.UninterpretedOption.NamePart\x12\x18\n\x10identifier_value\x18\x03 \x01(\t\x12\x1a\n\x12positive_int_value\x18\x04 \x01(\x04\x12\x1a\n\x12negative_int_value\x18\x05 \x01(\x03\x12\x14\n\x0c\x64ouble_value\x18\x06 \x01(\x01\x12\x14\n\x0cstring_value\x18\x07 \x01(\x0c\x12\x17\n\x0f\x61ggregate_value\x18\x08 \x01(\t\x1a\x33\n\x08NamePart\x12\x11\n\tname_part\x18\x01 \x02(\t\x12\x14\n\x0cis_extension\x18\x02 \x02(\x08\"\xd5\x01\n\x0eSourceCodeInfo\x12:\n\x08location\x18\x01 \x03(\x0b\x32(.google.protobuf.SourceCodeInfo.Location\x1a\x86\x01\n\x08Location\x12\x10\n\x04path\x18\x01 \x03(\x05\x42\x02\x10\x01\x12\x10\n\x04span\x18\x02 \x03(\x05\x42\x02\x10\x01\x12\x18\n\x10leading_comments\x18\x03 \x01(\t\x12\x19\n\x11trailing_comments\x18\x04 \x01(\t\x12!\n\x19leading_detached_comments\x18\x06 \x03(\t\"\xa7\x01\n\x11GeneratedCodeInfo\x12\x41\n\nannotation\x18\x01 \x03(\x0b\x32-.google.protobuf.GeneratedCodeInfo.Annotation\x1aO\n\nAnnotation\x12\x10\n\x04path\x18\x01 \x03(\x05\x42\x02\x10\x01\x12\x13\n\x0bsource_file\x18\x02 \x01(\t\x12\r\n\x05\x62\x65gin\x18\x03 \x01(\x05\x12\x0b\n\x03\x65nd\x18\x04 \x01(\x05\x42~\n\x13\x63om.google.protobufB\x10\x44\x65scriptorProtosH\x01Z-google.golang.org/protobuf/types/descriptorpb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1aGoogle.Protobuf.Reflection' - ) -else: - DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n google/protobuf/descriptor.proto\x12\x0fgoogle.protobuf\"G\n\x11\x46ileDescriptorSet\x12\x32\n\x04\x66ile\x18\x01 \x03(\x0b\x32$.google.protobuf.FileDescriptorProto\"\xdb\x03\n\x13\x46ileDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07package\x18\x02 \x01(\t\x12\x12\n\ndependency\x18\x03 \x03(\t\x12\x19\n\x11public_dependency\x18\n \x03(\x05\x12\x17\n\x0fweak_dependency\x18\x0b \x03(\x05\x12\x36\n\x0cmessage_type\x18\x04 \x03(\x0b\x32 .google.protobuf.DescriptorProto\x12\x37\n\tenum_type\x18\x05 \x03(\x0b\x32$.google.protobuf.EnumDescriptorProto\x12\x38\n\x07service\x18\x06 \x03(\x0b\x32\'.google.protobuf.ServiceDescriptorProto\x12\x38\n\textension\x18\x07 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProto\x12-\n\x07options\x18\x08 \x01(\x0b\x32\x1c.google.protobuf.FileOptions\x12\x39\n\x10source_code_info\x18\t \x01(\x0b\x32\x1f.google.protobuf.SourceCodeInfo\x12\x0e\n\x06syntax\x18\x0c \x01(\t\"\xa9\x05\n\x0f\x44\x65scriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x34\n\x05\x66ield\x18\x02 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProto\x12\x38\n\textension\x18\x06 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProto\x12\x35\n\x0bnested_type\x18\x03 \x03(\x0b\x32 .google.protobuf.DescriptorProto\x12\x37\n\tenum_type\x18\x04 \x03(\x0b\x32$.google.protobuf.EnumDescriptorProto\x12H\n\x0f\x65xtension_range\x18\x05 \x03(\x0b\x32/.google.protobuf.DescriptorProto.ExtensionRange\x12\x39\n\noneof_decl\x18\x08 \x03(\x0b\x32%.google.protobuf.OneofDescriptorProto\x12\x30\n\x07options\x18\x07 \x01(\x0b\x32\x1f.google.protobuf.MessageOptions\x12\x46\n\x0ereserved_range\x18\t \x03(\x0b\x32..google.protobuf.DescriptorProto.ReservedRange\x12\x15\n\rreserved_name\x18\n \x03(\t\x1a\x65\n\x0e\x45xtensionRange\x12\r\n\x05start\x18\x01 \x01(\x05\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x05\x12\x37\n\x07options\x18\x03 \x01(\x0b\x32&.google.protobuf.ExtensionRangeOptions\x1a+\n\rReservedRange\x12\r\n\x05start\x18\x01 \x01(\x05\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x05\"g\n\x15\x45xtensionRangeOptions\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xd5\x05\n\x14\x46ieldDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06number\x18\x03 \x01(\x05\x12:\n\x05label\x18\x04 \x01(\x0e\x32+.google.protobuf.FieldDescriptorProto.Label\x12\x38\n\x04type\x18\x05 \x01(\x0e\x32*.google.protobuf.FieldDescriptorProto.Type\x12\x11\n\ttype_name\x18\x06 \x01(\t\x12\x10\n\x08\x65xtendee\x18\x02 \x01(\t\x12\x15\n\rdefault_value\x18\x07 \x01(\t\x12\x13\n\x0boneof_index\x18\t \x01(\x05\x12\x11\n\tjson_name\x18\n \x01(\t\x12.\n\x07options\x18\x08 \x01(\x0b\x32\x1d.google.protobuf.FieldOptions\x12\x17\n\x0fproto3_optional\x18\x11 \x01(\x08\"\xb6\x02\n\x04Type\x12\x0f\n\x0bTYPE_DOUBLE\x10\x01\x12\x0e\n\nTYPE_FLOAT\x10\x02\x12\x0e\n\nTYPE_INT64\x10\x03\x12\x0f\n\x0bTYPE_UINT64\x10\x04\x12\x0e\n\nTYPE_INT32\x10\x05\x12\x10\n\x0cTYPE_FIXED64\x10\x06\x12\x10\n\x0cTYPE_FIXED32\x10\x07\x12\r\n\tTYPE_BOOL\x10\x08\x12\x0f\n\x0bTYPE_STRING\x10\t\x12\x0e\n\nTYPE_GROUP\x10\n\x12\x10\n\x0cTYPE_MESSAGE\x10\x0b\x12\x0e\n\nTYPE_BYTES\x10\x0c\x12\x0f\n\x0bTYPE_UINT32\x10\r\x12\r\n\tTYPE_ENUM\x10\x0e\x12\x11\n\rTYPE_SFIXED32\x10\x0f\x12\x11\n\rTYPE_SFIXED64\x10\x10\x12\x0f\n\x0bTYPE_SINT32\x10\x11\x12\x0f\n\x0bTYPE_SINT64\x10\x12\"C\n\x05Label\x12\x12\n\x0eLABEL_OPTIONAL\x10\x01\x12\x12\n\x0eLABEL_REQUIRED\x10\x02\x12\x12\n\x0eLABEL_REPEATED\x10\x03\"T\n\x14OneofDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12.\n\x07options\x18\x02 \x01(\x0b\x32\x1d.google.protobuf.OneofOptions\"\xa4\x02\n\x13\x45numDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x38\n\x05value\x18\x02 \x03(\x0b\x32).google.protobuf.EnumValueDescriptorProto\x12-\n\x07options\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.EnumOptions\x12N\n\x0ereserved_range\x18\x04 \x03(\x0b\x32\x36.google.protobuf.EnumDescriptorProto.EnumReservedRange\x12\x15\n\rreserved_name\x18\x05 \x03(\t\x1a/\n\x11\x45numReservedRange\x12\r\n\x05start\x18\x01 \x01(\x05\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x05\"l\n\x18\x45numValueDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06number\x18\x02 \x01(\x05\x12\x32\n\x07options\x18\x03 \x01(\x0b\x32!.google.protobuf.EnumValueOptions\"\x90\x01\n\x16ServiceDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x36\n\x06method\x18\x02 \x03(\x0b\x32&.google.protobuf.MethodDescriptorProto\x12\x30\n\x07options\x18\x03 \x01(\x0b\x32\x1f.google.protobuf.ServiceOptions\"\xc1\x01\n\x15MethodDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x12\n\ninput_type\x18\x02 \x01(\t\x12\x13\n\x0boutput_type\x18\x03 \x01(\t\x12/\n\x07options\x18\x04 \x01(\x0b\x32\x1e.google.protobuf.MethodOptions\x12\x1f\n\x10\x63lient_streaming\x18\x05 \x01(\x08:\x05\x66\x61lse\x12\x1f\n\x10server_streaming\x18\x06 \x01(\x08:\x05\x66\x61lse\"\xa5\x06\n\x0b\x46ileOptions\x12\x14\n\x0cjava_package\x18\x01 \x01(\t\x12\x1c\n\x14java_outer_classname\x18\x08 \x01(\t\x12\"\n\x13java_multiple_files\x18\n \x01(\x08:\x05\x66\x61lse\x12)\n\x1djava_generate_equals_and_hash\x18\x14 \x01(\x08\x42\x02\x18\x01\x12%\n\x16java_string_check_utf8\x18\x1b \x01(\x08:\x05\x66\x61lse\x12\x46\n\x0coptimize_for\x18\t \x01(\x0e\x32).google.protobuf.FileOptions.OptimizeMode:\x05SPEED\x12\x12\n\ngo_package\x18\x0b \x01(\t\x12\"\n\x13\x63\x63_generic_services\x18\x10 \x01(\x08:\x05\x66\x61lse\x12$\n\x15java_generic_services\x18\x11 \x01(\x08:\x05\x66\x61lse\x12\"\n\x13py_generic_services\x18\x12 \x01(\x08:\x05\x66\x61lse\x12#\n\x14php_generic_services\x18* \x01(\x08:\x05\x66\x61lse\x12\x19\n\ndeprecated\x18\x17 \x01(\x08:\x05\x66\x61lse\x12\x1e\n\x10\x63\x63_enable_arenas\x18\x1f \x01(\x08:\x04true\x12\x19\n\x11objc_class_prefix\x18$ \x01(\t\x12\x18\n\x10\x63sharp_namespace\x18% \x01(\t\x12\x14\n\x0cswift_prefix\x18\' \x01(\t\x12\x18\n\x10php_class_prefix\x18( \x01(\t\x12\x15\n\rphp_namespace\x18) \x01(\t\x12\x1e\n\x16php_metadata_namespace\x18, \x01(\t\x12\x14\n\x0cruby_package\x18- \x01(\t\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption\":\n\x0cOptimizeMode\x12\t\n\x05SPEED\x10\x01\x12\r\n\tCODE_SIZE\x10\x02\x12\x10\n\x0cLITE_RUNTIME\x10\x03*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08&\x10\'\"\x84\x02\n\x0eMessageOptions\x12&\n\x17message_set_wire_format\x18\x01 \x01(\x08:\x05\x66\x61lse\x12.\n\x1fno_standard_descriptor_accessor\x18\x02 \x01(\x08:\x05\x66\x61lse\x12\x19\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lse\x12\x11\n\tmap_entry\x18\x07 \x01(\x08\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08\x04\x10\x05J\x04\x08\x05\x10\x06J\x04\x08\x06\x10\x07J\x04\x08\x08\x10\tJ\x04\x08\t\x10\n\"\xbe\x03\n\x0c\x46ieldOptions\x12:\n\x05\x63type\x18\x01 \x01(\x0e\x32#.google.protobuf.FieldOptions.CType:\x06STRING\x12\x0e\n\x06packed\x18\x02 \x01(\x08\x12?\n\x06jstype\x18\x06 \x01(\x0e\x32$.google.protobuf.FieldOptions.JSType:\tJS_NORMAL\x12\x13\n\x04lazy\x18\x05 \x01(\x08:\x05\x66\x61lse\x12\x1e\n\x0funverified_lazy\x18\x0f \x01(\x08:\x05\x66\x61lse\x12\x19\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lse\x12\x13\n\x04weak\x18\n \x01(\x08:\x05\x66\x61lse\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption\"/\n\x05\x43Type\x12\n\n\x06STRING\x10\x00\x12\x08\n\x04\x43ORD\x10\x01\x12\x10\n\x0cSTRING_PIECE\x10\x02\"5\n\x06JSType\x12\r\n\tJS_NORMAL\x10\x00\x12\r\n\tJS_STRING\x10\x01\x12\r\n\tJS_NUMBER\x10\x02*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08\x04\x10\x05\"^\n\x0cOneofOptions\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\x93\x01\n\x0b\x45numOptions\x12\x13\n\x0b\x61llow_alias\x18\x02 \x01(\x08\x12\x19\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lse\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08\x05\x10\x06\"}\n\x10\x45numValueOptions\x12\x19\n\ndeprecated\x18\x01 \x01(\x08:\x05\x66\x61lse\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"{\n\x0eServiceOptions\x12\x19\n\ndeprecated\x18! \x01(\x08:\x05\x66\x61lse\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xad\x02\n\rMethodOptions\x12\x19\n\ndeprecated\x18! \x01(\x08:\x05\x66\x61lse\x12_\n\x11idempotency_level\x18\" \x01(\x0e\x32/.google.protobuf.MethodOptions.IdempotencyLevel:\x13IDEMPOTENCY_UNKNOWN\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption\"P\n\x10IdempotencyLevel\x12\x17\n\x13IDEMPOTENCY_UNKNOWN\x10\x00\x12\x13\n\x0fNO_SIDE_EFFECTS\x10\x01\x12\x0e\n\nIDEMPOTENT\x10\x02*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\x9e\x02\n\x13UninterpretedOption\x12;\n\x04name\x18\x02 \x03(\x0b\x32-.google.protobuf.UninterpretedOption.NamePart\x12\x18\n\x10identifier_value\x18\x03 \x01(\t\x12\x1a\n\x12positive_int_value\x18\x04 \x01(\x04\x12\x1a\n\x12negative_int_value\x18\x05 \x01(\x03\x12\x14\n\x0c\x64ouble_value\x18\x06 \x01(\x01\x12\x14\n\x0cstring_value\x18\x07 \x01(\x0c\x12\x17\n\x0f\x61ggregate_value\x18\x08 \x01(\t\x1a\x33\n\x08NamePart\x12\x11\n\tname_part\x18\x01 \x02(\t\x12\x14\n\x0cis_extension\x18\x02 \x02(\x08\"\xd5\x01\n\x0eSourceCodeInfo\x12:\n\x08location\x18\x01 \x03(\x0b\x32(.google.protobuf.SourceCodeInfo.Location\x1a\x86\x01\n\x08Location\x12\x10\n\x04path\x18\x01 \x03(\x05\x42\x02\x10\x01\x12\x10\n\x04span\x18\x02 \x03(\x05\x42\x02\x10\x01\x12\x18\n\x10leading_comments\x18\x03 \x01(\t\x12\x19\n\x11trailing_comments\x18\x04 \x01(\t\x12!\n\x19leading_detached_comments\x18\x06 \x03(\t\"\xa7\x01\n\x11GeneratedCodeInfo\x12\x41\n\nannotation\x18\x01 \x03(\x0b\x32-.google.protobuf.GeneratedCodeInfo.Annotation\x1aO\n\nAnnotation\x12\x10\n\x04path\x18\x01 \x03(\x05\x42\x02\x10\x01\x12\x13\n\x0bsource_file\x18\x02 \x01(\t\x12\r\n\x05\x62\x65gin\x18\x03 \x01(\x05\x12\x0b\n\x03\x65nd\x18\x04 \x01(\x05\x42~\n\x13\x63om.google.protobufB\x10\x44\x65scriptorProtosH\x01Z-google.golang.org/protobuf/types/descriptorpb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1aGoogle.Protobuf.Reflection') - -if _descriptor._USE_C_DESCRIPTORS == False: - _FIELDDESCRIPTORPROTO_TYPE = _descriptor.EnumDescriptor( - name='Type', - full_name='google.protobuf.FieldDescriptorProto.Type', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='TYPE_DOUBLE', index=0, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_FLOAT', index=1, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_INT64', index=2, number=3, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_UINT64', index=3, number=4, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_INT32', index=4, number=5, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_FIXED64', index=5, number=6, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_FIXED32', index=6, number=7, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_BOOL', index=7, number=8, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_STRING', index=8, number=9, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_GROUP', index=9, number=10, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_MESSAGE', index=10, number=11, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_BYTES', index=11, number=12, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_UINT32', index=12, number=13, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_ENUM', index=13, number=14, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_SFIXED32', index=14, number=15, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_SFIXED64', index=15, number=16, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_SINT32', index=16, number=17, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_SINT64', index=17, number=18, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - ) - _sym_db.RegisterEnumDescriptor(_FIELDDESCRIPTORPROTO_TYPE) - - _FIELDDESCRIPTORPROTO_LABEL = _descriptor.EnumDescriptor( - name='Label', - full_name='google.protobuf.FieldDescriptorProto.Label', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='LABEL_OPTIONAL', index=0, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='LABEL_REQUIRED', index=1, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='LABEL_REPEATED', index=2, number=3, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - ) - _sym_db.RegisterEnumDescriptor(_FIELDDESCRIPTORPROTO_LABEL) - - _FILEOPTIONS_OPTIMIZEMODE = _descriptor.EnumDescriptor( - name='OptimizeMode', - full_name='google.protobuf.FileOptions.OptimizeMode', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='SPEED', index=0, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='CODE_SIZE', index=1, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='LITE_RUNTIME', index=2, number=3, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - ) - _sym_db.RegisterEnumDescriptor(_FILEOPTIONS_OPTIMIZEMODE) - - _FIELDOPTIONS_CTYPE = _descriptor.EnumDescriptor( - name='CType', - full_name='google.protobuf.FieldOptions.CType', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='STRING', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='CORD', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='STRING_PIECE', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - ) - _sym_db.RegisterEnumDescriptor(_FIELDOPTIONS_CTYPE) - - _FIELDOPTIONS_JSTYPE = _descriptor.EnumDescriptor( - name='JSType', - full_name='google.protobuf.FieldOptions.JSType', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='JS_NORMAL', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='JS_STRING', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='JS_NUMBER', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - ) - _sym_db.RegisterEnumDescriptor(_FIELDOPTIONS_JSTYPE) - - _METHODOPTIONS_IDEMPOTENCYLEVEL = _descriptor.EnumDescriptor( - name='IdempotencyLevel', - full_name='google.protobuf.MethodOptions.IdempotencyLevel', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='IDEMPOTENCY_UNKNOWN', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='NO_SIDE_EFFECTS', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='IDEMPOTENT', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - ) - _sym_db.RegisterEnumDescriptor(_METHODOPTIONS_IDEMPOTENCYLEVEL) - - - _FILEDESCRIPTORSET = _descriptor.Descriptor( - name='FileDescriptorSet', - full_name='google.protobuf.FileDescriptorSet', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='file', full_name='google.protobuf.FileDescriptorSet.file', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - ) - - - _FILEDESCRIPTORPROTO = _descriptor.Descriptor( - name='FileDescriptorProto', - full_name='google.protobuf.FileDescriptorProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='google.protobuf.FileDescriptorProto.name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='package', full_name='google.protobuf.FileDescriptorProto.package', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='dependency', full_name='google.protobuf.FileDescriptorProto.dependency', index=2, - number=3, type=9, cpp_type=9, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='public_dependency', full_name='google.protobuf.FileDescriptorProto.public_dependency', index=3, - number=10, type=5, cpp_type=1, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='weak_dependency', full_name='google.protobuf.FileDescriptorProto.weak_dependency', index=4, - number=11, type=5, cpp_type=1, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='message_type', full_name='google.protobuf.FileDescriptorProto.message_type', index=5, - number=4, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='enum_type', full_name='google.protobuf.FileDescriptorProto.enum_type', index=6, - number=5, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='service', full_name='google.protobuf.FileDescriptorProto.service', index=7, - number=6, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='extension', full_name='google.protobuf.FileDescriptorProto.extension', index=8, - number=7, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='options', full_name='google.protobuf.FileDescriptorProto.options', index=9, - number=8, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='source_code_info', full_name='google.protobuf.FileDescriptorProto.source_code_info', index=10, - number=9, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='syntax', full_name='google.protobuf.FileDescriptorProto.syntax', index=11, - number=12, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - ) - - - _DESCRIPTORPROTO_EXTENSIONRANGE = _descriptor.Descriptor( - name='ExtensionRange', - full_name='google.protobuf.DescriptorProto.ExtensionRange', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='start', full_name='google.protobuf.DescriptorProto.ExtensionRange.start', index=0, - number=1, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='end', full_name='google.protobuf.DescriptorProto.ExtensionRange.end', index=1, - number=2, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='options', full_name='google.protobuf.DescriptorProto.ExtensionRange.options', index=2, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - ) - - _DESCRIPTORPROTO_RESERVEDRANGE = _descriptor.Descriptor( - name='ReservedRange', - full_name='google.protobuf.DescriptorProto.ReservedRange', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='start', full_name='google.protobuf.DescriptorProto.ReservedRange.start', index=0, - number=1, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='end', full_name='google.protobuf.DescriptorProto.ReservedRange.end', index=1, - number=2, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - ) - - _DESCRIPTORPROTO = _descriptor.Descriptor( - name='DescriptorProto', - full_name='google.protobuf.DescriptorProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='google.protobuf.DescriptorProto.name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='field', full_name='google.protobuf.DescriptorProto.field', index=1, - number=2, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='extension', full_name='google.protobuf.DescriptorProto.extension', index=2, - number=6, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='nested_type', full_name='google.protobuf.DescriptorProto.nested_type', index=3, - number=3, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='enum_type', full_name='google.protobuf.DescriptorProto.enum_type', index=4, - number=4, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='extension_range', full_name='google.protobuf.DescriptorProto.extension_range', index=5, - number=5, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='oneof_decl', full_name='google.protobuf.DescriptorProto.oneof_decl', index=6, - number=8, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='options', full_name='google.protobuf.DescriptorProto.options', index=7, - number=7, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='reserved_range', full_name='google.protobuf.DescriptorProto.reserved_range', index=8, - number=9, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='reserved_name', full_name='google.protobuf.DescriptorProto.reserved_name', index=9, - number=10, type=9, cpp_type=9, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[_DESCRIPTORPROTO_EXTENSIONRANGE, _DESCRIPTORPROTO_RESERVEDRANGE, ], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - ) - - - _EXTENSIONRANGEOPTIONS = _descriptor.Descriptor( - name='ExtensionRangeOptions', - full_name='google.protobuf.ExtensionRangeOptions', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='uninterpreted_option', full_name='google.protobuf.ExtensionRangeOptions.uninterpreted_option', index=0, - number=999, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=True, - syntax='proto2', - extension_ranges=[(1000, 536870912), ], - oneofs=[ - ], - ) - - - _FIELDDESCRIPTORPROTO = _descriptor.Descriptor( - name='FieldDescriptorProto', - full_name='google.protobuf.FieldDescriptorProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='google.protobuf.FieldDescriptorProto.name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='number', full_name='google.protobuf.FieldDescriptorProto.number', index=1, - number=3, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='label', full_name='google.protobuf.FieldDescriptorProto.label', index=2, - number=4, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=1, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='type', full_name='google.protobuf.FieldDescriptorProto.type', index=3, - number=5, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=1, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='type_name', full_name='google.protobuf.FieldDescriptorProto.type_name', index=4, - number=6, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='extendee', full_name='google.protobuf.FieldDescriptorProto.extendee', index=5, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='default_value', full_name='google.protobuf.FieldDescriptorProto.default_value', index=6, - number=7, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='oneof_index', full_name='google.protobuf.FieldDescriptorProto.oneof_index', index=7, - number=9, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='json_name', full_name='google.protobuf.FieldDescriptorProto.json_name', index=8, - number=10, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='options', full_name='google.protobuf.FieldDescriptorProto.options', index=9, - number=8, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='proto3_optional', full_name='google.protobuf.FieldDescriptorProto.proto3_optional', index=10, - number=17, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - _FIELDDESCRIPTORPROTO_TYPE, - _FIELDDESCRIPTORPROTO_LABEL, - ], - serialized_options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - ) - - - _ONEOFDESCRIPTORPROTO = _descriptor.Descriptor( - name='OneofDescriptorProto', - full_name='google.protobuf.OneofDescriptorProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='google.protobuf.OneofDescriptorProto.name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='options', full_name='google.protobuf.OneofDescriptorProto.options', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - ) - - - _ENUMDESCRIPTORPROTO_ENUMRESERVEDRANGE = _descriptor.Descriptor( - name='EnumReservedRange', - full_name='google.protobuf.EnumDescriptorProto.EnumReservedRange', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='start', full_name='google.protobuf.EnumDescriptorProto.EnumReservedRange.start', index=0, - number=1, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='end', full_name='google.protobuf.EnumDescriptorProto.EnumReservedRange.end', index=1, - number=2, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - ) - - _ENUMDESCRIPTORPROTO = _descriptor.Descriptor( - name='EnumDescriptorProto', - full_name='google.protobuf.EnumDescriptorProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='google.protobuf.EnumDescriptorProto.name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='value', full_name='google.protobuf.EnumDescriptorProto.value', index=1, - number=2, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='options', full_name='google.protobuf.EnumDescriptorProto.options', index=2, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='reserved_range', full_name='google.protobuf.EnumDescriptorProto.reserved_range', index=3, - number=4, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='reserved_name', full_name='google.protobuf.EnumDescriptorProto.reserved_name', index=4, - number=5, type=9, cpp_type=9, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[_ENUMDESCRIPTORPROTO_ENUMRESERVEDRANGE, ], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - ) - - - _ENUMVALUEDESCRIPTORPROTO = _descriptor.Descriptor( - name='EnumValueDescriptorProto', - full_name='google.protobuf.EnumValueDescriptorProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='google.protobuf.EnumValueDescriptorProto.name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='number', full_name='google.protobuf.EnumValueDescriptorProto.number', index=1, - number=2, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='options', full_name='google.protobuf.EnumValueDescriptorProto.options', index=2, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - ) - - - _SERVICEDESCRIPTORPROTO = _descriptor.Descriptor( - name='ServiceDescriptorProto', - full_name='google.protobuf.ServiceDescriptorProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='google.protobuf.ServiceDescriptorProto.name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='method', full_name='google.protobuf.ServiceDescriptorProto.method', index=1, - number=2, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='options', full_name='google.protobuf.ServiceDescriptorProto.options', index=2, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - ) - - - _METHODDESCRIPTORPROTO = _descriptor.Descriptor( - name='MethodDescriptorProto', - full_name='google.protobuf.MethodDescriptorProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='google.protobuf.MethodDescriptorProto.name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='input_type', full_name='google.protobuf.MethodDescriptorProto.input_type', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='output_type', full_name='google.protobuf.MethodDescriptorProto.output_type', index=2, - number=3, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='options', full_name='google.protobuf.MethodDescriptorProto.options', index=3, - number=4, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='client_streaming', full_name='google.protobuf.MethodDescriptorProto.client_streaming', index=4, - number=5, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='server_streaming', full_name='google.protobuf.MethodDescriptorProto.server_streaming', index=5, - number=6, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - ) - - - _FILEOPTIONS = _descriptor.Descriptor( - name='FileOptions', - full_name='google.protobuf.FileOptions', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='java_package', full_name='google.protobuf.FileOptions.java_package', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='java_outer_classname', full_name='google.protobuf.FileOptions.java_outer_classname', index=1, - number=8, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='java_multiple_files', full_name='google.protobuf.FileOptions.java_multiple_files', index=2, - number=10, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='java_generate_equals_and_hash', full_name='google.protobuf.FileOptions.java_generate_equals_and_hash', index=3, - number=20, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='java_string_check_utf8', full_name='google.protobuf.FileOptions.java_string_check_utf8', index=4, - number=27, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='optimize_for', full_name='google.protobuf.FileOptions.optimize_for', index=5, - number=9, type=14, cpp_type=8, label=1, - has_default_value=True, default_value=1, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='go_package', full_name='google.protobuf.FileOptions.go_package', index=6, - number=11, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='cc_generic_services', full_name='google.protobuf.FileOptions.cc_generic_services', index=7, - number=16, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='java_generic_services', full_name='google.protobuf.FileOptions.java_generic_services', index=8, - number=17, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='py_generic_services', full_name='google.protobuf.FileOptions.py_generic_services', index=9, - number=18, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='php_generic_services', full_name='google.protobuf.FileOptions.php_generic_services', index=10, - number=42, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='deprecated', full_name='google.protobuf.FileOptions.deprecated', index=11, - number=23, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='cc_enable_arenas', full_name='google.protobuf.FileOptions.cc_enable_arenas', index=12, - number=31, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=True, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='objc_class_prefix', full_name='google.protobuf.FileOptions.objc_class_prefix', index=13, - number=36, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='csharp_namespace', full_name='google.protobuf.FileOptions.csharp_namespace', index=14, - number=37, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='swift_prefix', full_name='google.protobuf.FileOptions.swift_prefix', index=15, - number=39, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='php_class_prefix', full_name='google.protobuf.FileOptions.php_class_prefix', index=16, - number=40, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='php_namespace', full_name='google.protobuf.FileOptions.php_namespace', index=17, - number=41, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='php_metadata_namespace', full_name='google.protobuf.FileOptions.php_metadata_namespace', index=18, - number=44, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='ruby_package', full_name='google.protobuf.FileOptions.ruby_package', index=19, - number=45, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='uninterpreted_option', full_name='google.protobuf.FileOptions.uninterpreted_option', index=20, - number=999, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - _FILEOPTIONS_OPTIMIZEMODE, - ], - serialized_options=None, - is_extendable=True, - syntax='proto2', - extension_ranges=[(1000, 536870912), ], - oneofs=[ - ], - ) - - - _MESSAGEOPTIONS = _descriptor.Descriptor( - name='MessageOptions', - full_name='google.protobuf.MessageOptions', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='message_set_wire_format', full_name='google.protobuf.MessageOptions.message_set_wire_format', index=0, - number=1, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='no_standard_descriptor_accessor', full_name='google.protobuf.MessageOptions.no_standard_descriptor_accessor', index=1, - number=2, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='deprecated', full_name='google.protobuf.MessageOptions.deprecated', index=2, - number=3, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='map_entry', full_name='google.protobuf.MessageOptions.map_entry', index=3, - number=7, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='uninterpreted_option', full_name='google.protobuf.MessageOptions.uninterpreted_option', index=4, - number=999, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=True, - syntax='proto2', - extension_ranges=[(1000, 536870912), ], - oneofs=[ - ], - ) - - - _FIELDOPTIONS = _descriptor.Descriptor( - name='FieldOptions', - full_name='google.protobuf.FieldOptions', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='ctype', full_name='google.protobuf.FieldOptions.ctype', index=0, - number=1, type=14, cpp_type=8, label=1, - has_default_value=True, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='packed', full_name='google.protobuf.FieldOptions.packed', index=1, - number=2, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='jstype', full_name='google.protobuf.FieldOptions.jstype', index=2, - number=6, type=14, cpp_type=8, label=1, - has_default_value=True, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='lazy', full_name='google.protobuf.FieldOptions.lazy', index=3, - number=5, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='unverified_lazy', full_name='google.protobuf.FieldOptions.unverified_lazy', index=4, - number=15, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='deprecated', full_name='google.protobuf.FieldOptions.deprecated', index=5, - number=3, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='weak', full_name='google.protobuf.FieldOptions.weak', index=6, - number=10, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='uninterpreted_option', full_name='google.protobuf.FieldOptions.uninterpreted_option', index=7, - number=999, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - _FIELDOPTIONS_CTYPE, - _FIELDOPTIONS_JSTYPE, - ], - serialized_options=None, - is_extendable=True, - syntax='proto2', - extension_ranges=[(1000, 536870912), ], - oneofs=[ - ], - ) - - - _ONEOFOPTIONS = _descriptor.Descriptor( - name='OneofOptions', - full_name='google.protobuf.OneofOptions', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='uninterpreted_option', full_name='google.protobuf.OneofOptions.uninterpreted_option', index=0, - number=999, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=True, - syntax='proto2', - extension_ranges=[(1000, 536870912), ], - oneofs=[ - ], - ) - - - _ENUMOPTIONS = _descriptor.Descriptor( - name='EnumOptions', - full_name='google.protobuf.EnumOptions', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='allow_alias', full_name='google.protobuf.EnumOptions.allow_alias', index=0, - number=2, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='deprecated', full_name='google.protobuf.EnumOptions.deprecated', index=1, - number=3, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='uninterpreted_option', full_name='google.protobuf.EnumOptions.uninterpreted_option', index=2, - number=999, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=True, - syntax='proto2', - extension_ranges=[(1000, 536870912), ], - oneofs=[ - ], - ) - - - _ENUMVALUEOPTIONS = _descriptor.Descriptor( - name='EnumValueOptions', - full_name='google.protobuf.EnumValueOptions', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='deprecated', full_name='google.protobuf.EnumValueOptions.deprecated', index=0, - number=1, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='uninterpreted_option', full_name='google.protobuf.EnumValueOptions.uninterpreted_option', index=1, - number=999, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=True, - syntax='proto2', - extension_ranges=[(1000, 536870912), ], - oneofs=[ - ], - ) - - - _SERVICEOPTIONS = _descriptor.Descriptor( - name='ServiceOptions', - full_name='google.protobuf.ServiceOptions', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='deprecated', full_name='google.protobuf.ServiceOptions.deprecated', index=0, - number=33, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='uninterpreted_option', full_name='google.protobuf.ServiceOptions.uninterpreted_option', index=1, - number=999, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=True, - syntax='proto2', - extension_ranges=[(1000, 536870912), ], - oneofs=[ - ], - ) - - - _METHODOPTIONS = _descriptor.Descriptor( - name='MethodOptions', - full_name='google.protobuf.MethodOptions', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='deprecated', full_name='google.protobuf.MethodOptions.deprecated', index=0, - number=33, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='idempotency_level', full_name='google.protobuf.MethodOptions.idempotency_level', index=1, - number=34, type=14, cpp_type=8, label=1, - has_default_value=True, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='uninterpreted_option', full_name='google.protobuf.MethodOptions.uninterpreted_option', index=2, - number=999, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - _METHODOPTIONS_IDEMPOTENCYLEVEL, - ], - serialized_options=None, - is_extendable=True, - syntax='proto2', - extension_ranges=[(1000, 536870912), ], - oneofs=[ - ], - ) - - - _UNINTERPRETEDOPTION_NAMEPART = _descriptor.Descriptor( - name='NamePart', - full_name='google.protobuf.UninterpretedOption.NamePart', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='name_part', full_name='google.protobuf.UninterpretedOption.NamePart.name_part', index=0, - number=1, type=9, cpp_type=9, label=2, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='is_extension', full_name='google.protobuf.UninterpretedOption.NamePart.is_extension', index=1, - number=2, type=8, cpp_type=7, label=2, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - ) - - _UNINTERPRETEDOPTION = _descriptor.Descriptor( - name='UninterpretedOption', - full_name='google.protobuf.UninterpretedOption', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='google.protobuf.UninterpretedOption.name', index=0, - number=2, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='identifier_value', full_name='google.protobuf.UninterpretedOption.identifier_value', index=1, - number=3, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='positive_int_value', full_name='google.protobuf.UninterpretedOption.positive_int_value', index=2, - number=4, type=4, cpp_type=4, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='negative_int_value', full_name='google.protobuf.UninterpretedOption.negative_int_value', index=3, - number=5, type=3, cpp_type=2, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='double_value', full_name='google.protobuf.UninterpretedOption.double_value', index=4, - number=6, type=1, cpp_type=5, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='string_value', full_name='google.protobuf.UninterpretedOption.string_value', index=5, - number=7, type=12, cpp_type=9, label=1, - has_default_value=False, default_value=b"", - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='aggregate_value', full_name='google.protobuf.UninterpretedOption.aggregate_value', index=6, - number=8, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[_UNINTERPRETEDOPTION_NAMEPART, ], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - ) - - - _SOURCECODEINFO_LOCATION = _descriptor.Descriptor( - name='Location', - full_name='google.protobuf.SourceCodeInfo.Location', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='path', full_name='google.protobuf.SourceCodeInfo.Location.path', index=0, - number=1, type=5, cpp_type=1, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='span', full_name='google.protobuf.SourceCodeInfo.Location.span', index=1, - number=2, type=5, cpp_type=1, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='leading_comments', full_name='google.protobuf.SourceCodeInfo.Location.leading_comments', index=2, - number=3, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='trailing_comments', full_name='google.protobuf.SourceCodeInfo.Location.trailing_comments', index=3, - number=4, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='leading_detached_comments', full_name='google.protobuf.SourceCodeInfo.Location.leading_detached_comments', index=4, - number=6, type=9, cpp_type=9, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - ) - - _SOURCECODEINFO = _descriptor.Descriptor( - name='SourceCodeInfo', - full_name='google.protobuf.SourceCodeInfo', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='location', full_name='google.protobuf.SourceCodeInfo.location', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[_SOURCECODEINFO_LOCATION, ], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - ) - - - _GENERATEDCODEINFO_ANNOTATION = _descriptor.Descriptor( - name='Annotation', - full_name='google.protobuf.GeneratedCodeInfo.Annotation', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='path', full_name='google.protobuf.GeneratedCodeInfo.Annotation.path', index=0, - number=1, type=5, cpp_type=1, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='source_file', full_name='google.protobuf.GeneratedCodeInfo.Annotation.source_file', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='begin', full_name='google.protobuf.GeneratedCodeInfo.Annotation.begin', index=2, - number=3, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='end', full_name='google.protobuf.GeneratedCodeInfo.Annotation.end', index=3, - number=4, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - ) - - _GENERATEDCODEINFO = _descriptor.Descriptor( - name='GeneratedCodeInfo', - full_name='google.protobuf.GeneratedCodeInfo', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='annotation', full_name='google.protobuf.GeneratedCodeInfo.annotation', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[_GENERATEDCODEINFO_ANNOTATION, ], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - ) - - _FILEDESCRIPTORSET.fields_by_name['file'].message_type = _FILEDESCRIPTORPROTO - _FILEDESCRIPTORPROTO.fields_by_name['message_type'].message_type = _DESCRIPTORPROTO - _FILEDESCRIPTORPROTO.fields_by_name['enum_type'].message_type = _ENUMDESCRIPTORPROTO - _FILEDESCRIPTORPROTO.fields_by_name['service'].message_type = _SERVICEDESCRIPTORPROTO - _FILEDESCRIPTORPROTO.fields_by_name['extension'].message_type = _FIELDDESCRIPTORPROTO - _FILEDESCRIPTORPROTO.fields_by_name['options'].message_type = _FILEOPTIONS - _FILEDESCRIPTORPROTO.fields_by_name['source_code_info'].message_type = _SOURCECODEINFO - _DESCRIPTORPROTO_EXTENSIONRANGE.fields_by_name['options'].message_type = _EXTENSIONRANGEOPTIONS - _DESCRIPTORPROTO_EXTENSIONRANGE.containing_type = _DESCRIPTORPROTO - _DESCRIPTORPROTO_RESERVEDRANGE.containing_type = _DESCRIPTORPROTO - _DESCRIPTORPROTO.fields_by_name['field'].message_type = _FIELDDESCRIPTORPROTO - _DESCRIPTORPROTO.fields_by_name['extension'].message_type = _FIELDDESCRIPTORPROTO - _DESCRIPTORPROTO.fields_by_name['nested_type'].message_type = _DESCRIPTORPROTO - _DESCRIPTORPROTO.fields_by_name['enum_type'].message_type = _ENUMDESCRIPTORPROTO - _DESCRIPTORPROTO.fields_by_name['extension_range'].message_type = _DESCRIPTORPROTO_EXTENSIONRANGE - _DESCRIPTORPROTO.fields_by_name['oneof_decl'].message_type = _ONEOFDESCRIPTORPROTO - _DESCRIPTORPROTO.fields_by_name['options'].message_type = _MESSAGEOPTIONS - _DESCRIPTORPROTO.fields_by_name['reserved_range'].message_type = _DESCRIPTORPROTO_RESERVEDRANGE - _EXTENSIONRANGEOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION - _FIELDDESCRIPTORPROTO.fields_by_name['label'].enum_type = _FIELDDESCRIPTORPROTO_LABEL - _FIELDDESCRIPTORPROTO.fields_by_name['type'].enum_type = _FIELDDESCRIPTORPROTO_TYPE - _FIELDDESCRIPTORPROTO.fields_by_name['options'].message_type = _FIELDOPTIONS - _FIELDDESCRIPTORPROTO_TYPE.containing_type = _FIELDDESCRIPTORPROTO - _FIELDDESCRIPTORPROTO_LABEL.containing_type = _FIELDDESCRIPTORPROTO - _ONEOFDESCRIPTORPROTO.fields_by_name['options'].message_type = _ONEOFOPTIONS - _ENUMDESCRIPTORPROTO_ENUMRESERVEDRANGE.containing_type = _ENUMDESCRIPTORPROTO - _ENUMDESCRIPTORPROTO.fields_by_name['value'].message_type = _ENUMVALUEDESCRIPTORPROTO - _ENUMDESCRIPTORPROTO.fields_by_name['options'].message_type = _ENUMOPTIONS - _ENUMDESCRIPTORPROTO.fields_by_name['reserved_range'].message_type = _ENUMDESCRIPTORPROTO_ENUMRESERVEDRANGE - _ENUMVALUEDESCRIPTORPROTO.fields_by_name['options'].message_type = _ENUMVALUEOPTIONS - _SERVICEDESCRIPTORPROTO.fields_by_name['method'].message_type = _METHODDESCRIPTORPROTO - _SERVICEDESCRIPTORPROTO.fields_by_name['options'].message_type = _SERVICEOPTIONS - _METHODDESCRIPTORPROTO.fields_by_name['options'].message_type = _METHODOPTIONS - _FILEOPTIONS.fields_by_name['optimize_for'].enum_type = _FILEOPTIONS_OPTIMIZEMODE - _FILEOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION - _FILEOPTIONS_OPTIMIZEMODE.containing_type = _FILEOPTIONS - _MESSAGEOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION - _FIELDOPTIONS.fields_by_name['ctype'].enum_type = _FIELDOPTIONS_CTYPE - _FIELDOPTIONS.fields_by_name['jstype'].enum_type = _FIELDOPTIONS_JSTYPE - _FIELDOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION - _FIELDOPTIONS_CTYPE.containing_type = _FIELDOPTIONS - _FIELDOPTIONS_JSTYPE.containing_type = _FIELDOPTIONS - _ONEOFOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION - _ENUMOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION - _ENUMVALUEOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION - _SERVICEOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION - _METHODOPTIONS.fields_by_name['idempotency_level'].enum_type = _METHODOPTIONS_IDEMPOTENCYLEVEL - _METHODOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION - _METHODOPTIONS_IDEMPOTENCYLEVEL.containing_type = _METHODOPTIONS - _UNINTERPRETEDOPTION_NAMEPART.containing_type = _UNINTERPRETEDOPTION - _UNINTERPRETEDOPTION.fields_by_name['name'].message_type = _UNINTERPRETEDOPTION_NAMEPART - _SOURCECODEINFO_LOCATION.containing_type = _SOURCECODEINFO - _SOURCECODEINFO.fields_by_name['location'].message_type = _SOURCECODEINFO_LOCATION - _GENERATEDCODEINFO_ANNOTATION.containing_type = _GENERATEDCODEINFO - _GENERATEDCODEINFO.fields_by_name['annotation'].message_type = _GENERATEDCODEINFO_ANNOTATION - DESCRIPTOR.message_types_by_name['FileDescriptorSet'] = _FILEDESCRIPTORSET - DESCRIPTOR.message_types_by_name['FileDescriptorProto'] = _FILEDESCRIPTORPROTO - DESCRIPTOR.message_types_by_name['DescriptorProto'] = _DESCRIPTORPROTO - DESCRIPTOR.message_types_by_name['ExtensionRangeOptions'] = _EXTENSIONRANGEOPTIONS - DESCRIPTOR.message_types_by_name['FieldDescriptorProto'] = _FIELDDESCRIPTORPROTO - DESCRIPTOR.message_types_by_name['OneofDescriptorProto'] = _ONEOFDESCRIPTORPROTO - DESCRIPTOR.message_types_by_name['EnumDescriptorProto'] = _ENUMDESCRIPTORPROTO - DESCRIPTOR.message_types_by_name['EnumValueDescriptorProto'] = _ENUMVALUEDESCRIPTORPROTO - DESCRIPTOR.message_types_by_name['ServiceDescriptorProto'] = _SERVICEDESCRIPTORPROTO - DESCRIPTOR.message_types_by_name['MethodDescriptorProto'] = _METHODDESCRIPTORPROTO - DESCRIPTOR.message_types_by_name['FileOptions'] = _FILEOPTIONS - DESCRIPTOR.message_types_by_name['MessageOptions'] = _MESSAGEOPTIONS - DESCRIPTOR.message_types_by_name['FieldOptions'] = _FIELDOPTIONS - DESCRIPTOR.message_types_by_name['OneofOptions'] = _ONEOFOPTIONS - DESCRIPTOR.message_types_by_name['EnumOptions'] = _ENUMOPTIONS - DESCRIPTOR.message_types_by_name['EnumValueOptions'] = _ENUMVALUEOPTIONS - DESCRIPTOR.message_types_by_name['ServiceOptions'] = _SERVICEOPTIONS - DESCRIPTOR.message_types_by_name['MethodOptions'] = _METHODOPTIONS - DESCRIPTOR.message_types_by_name['UninterpretedOption'] = _UNINTERPRETEDOPTION - DESCRIPTOR.message_types_by_name['SourceCodeInfo'] = _SOURCECODEINFO - DESCRIPTOR.message_types_by_name['GeneratedCodeInfo'] = _GENERATEDCODEINFO - _sym_db.RegisterFileDescriptor(DESCRIPTOR) - -else: - _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.descriptor_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - _FILEDESCRIPTORSET._serialized_start=53 - _FILEDESCRIPTORSET._serialized_end=124 - _FILEDESCRIPTORPROTO._serialized_start=127 - _FILEDESCRIPTORPROTO._serialized_end=602 - _DESCRIPTORPROTO._serialized_start=605 - _DESCRIPTORPROTO._serialized_end=1286 - _DESCRIPTORPROTO_EXTENSIONRANGE._serialized_start=1140 - _DESCRIPTORPROTO_EXTENSIONRANGE._serialized_end=1241 - _DESCRIPTORPROTO_RESERVEDRANGE._serialized_start=1243 - _DESCRIPTORPROTO_RESERVEDRANGE._serialized_end=1286 - _EXTENSIONRANGEOPTIONS._serialized_start=1288 - _EXTENSIONRANGEOPTIONS._serialized_end=1391 - _FIELDDESCRIPTORPROTO._serialized_start=1394 - _FIELDDESCRIPTORPROTO._serialized_end=2119 - _FIELDDESCRIPTORPROTO_TYPE._serialized_start=1740 - _FIELDDESCRIPTORPROTO_TYPE._serialized_end=2050 - _FIELDDESCRIPTORPROTO_LABEL._serialized_start=2052 - _FIELDDESCRIPTORPROTO_LABEL._serialized_end=2119 - _ONEOFDESCRIPTORPROTO._serialized_start=2121 - _ONEOFDESCRIPTORPROTO._serialized_end=2205 - _ENUMDESCRIPTORPROTO._serialized_start=2208 - _ENUMDESCRIPTORPROTO._serialized_end=2500 - _ENUMDESCRIPTORPROTO_ENUMRESERVEDRANGE._serialized_start=2453 - _ENUMDESCRIPTORPROTO_ENUMRESERVEDRANGE._serialized_end=2500 - _ENUMVALUEDESCRIPTORPROTO._serialized_start=2502 - _ENUMVALUEDESCRIPTORPROTO._serialized_end=2610 - _SERVICEDESCRIPTORPROTO._serialized_start=2613 - _SERVICEDESCRIPTORPROTO._serialized_end=2757 - _METHODDESCRIPTORPROTO._serialized_start=2760 - _METHODDESCRIPTORPROTO._serialized_end=2953 - _FILEOPTIONS._serialized_start=2956 - _FILEOPTIONS._serialized_end=3761 - _FILEOPTIONS_OPTIMIZEMODE._serialized_start=3686 - _FILEOPTIONS_OPTIMIZEMODE._serialized_end=3744 - _MESSAGEOPTIONS._serialized_start=3764 - _MESSAGEOPTIONS._serialized_end=4024 - _FIELDOPTIONS._serialized_start=4027 - _FIELDOPTIONS._serialized_end=4473 - _FIELDOPTIONS_CTYPE._serialized_start=4354 - _FIELDOPTIONS_CTYPE._serialized_end=4401 - _FIELDOPTIONS_JSTYPE._serialized_start=4403 - _FIELDOPTIONS_JSTYPE._serialized_end=4456 - _ONEOFOPTIONS._serialized_start=4475 - _ONEOFOPTIONS._serialized_end=4569 - _ENUMOPTIONS._serialized_start=4572 - _ENUMOPTIONS._serialized_end=4719 - _ENUMVALUEOPTIONS._serialized_start=4721 - _ENUMVALUEOPTIONS._serialized_end=4846 - _SERVICEOPTIONS._serialized_start=4848 - _SERVICEOPTIONS._serialized_end=4971 - _METHODOPTIONS._serialized_start=4974 - _METHODOPTIONS._serialized_end=5275 - _METHODOPTIONS_IDEMPOTENCYLEVEL._serialized_start=5184 - _METHODOPTIONS_IDEMPOTENCYLEVEL._serialized_end=5264 - _UNINTERPRETEDOPTION._serialized_start=5278 - _UNINTERPRETEDOPTION._serialized_end=5564 - _UNINTERPRETEDOPTION_NAMEPART._serialized_start=5513 - _UNINTERPRETEDOPTION_NAMEPART._serialized_end=5564 - _SOURCECODEINFO._serialized_start=5567 - _SOURCECODEINFO._serialized_end=5780 - _SOURCECODEINFO_LOCATION._serialized_start=5646 - _SOURCECODEINFO_LOCATION._serialized_end=5780 - _GENERATEDCODEINFO._serialized_start=5783 - _GENERATEDCODEINFO._serialized_end=5950 - _GENERATEDCODEINFO_ANNOTATION._serialized_start=5871 - _GENERATEDCODEINFO_ANNOTATION._serialized_end=5950 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/descriptor_pool.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/descriptor_pool.py deleted file mode 100644 index 911372a8b0..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/descriptor_pool.py +++ /dev/null @@ -1,1295 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Provides DescriptorPool to use as a container for proto2 descriptors. - -The DescriptorPool is used in conjection with a DescriptorDatabase to maintain -a collection of protocol buffer descriptors for use when dynamically creating -message types at runtime. - -For most applications protocol buffers should be used via modules generated by -the protocol buffer compiler tool. This should only be used when the type of -protocol buffers used in an application or library cannot be predetermined. - -Below is a straightforward example on how to use this class:: - - pool = DescriptorPool() - file_descriptor_protos = [ ... ] - for file_descriptor_proto in file_descriptor_protos: - pool.Add(file_descriptor_proto) - my_message_descriptor = pool.FindMessageTypeByName('some.package.MessageType') - -The message descriptor can be used in conjunction with the message_factory -module in order to create a protocol buffer class that can be encoded and -decoded. - -If you want to get a Python class for the specified proto, use the -helper functions inside google.protobuf.message_factory -directly instead of this class. -""" - -__author__ = 'matthewtoia@google.com (Matt Toia)' - -import collections -import warnings - -from google.protobuf import descriptor -from google.protobuf import descriptor_database -from google.protobuf import text_encoding - - -_USE_C_DESCRIPTORS = descriptor._USE_C_DESCRIPTORS # pylint: disable=protected-access - - -def _Deprecated(func): - """Mark functions as deprecated.""" - - def NewFunc(*args, **kwargs): - warnings.warn( - 'Call to deprecated function %s(). Note: Do add unlinked descriptors ' - 'to descriptor_pool is wrong. Use Add() or AddSerializedFile() ' - 'instead.' % func.__name__, - category=DeprecationWarning) - return func(*args, **kwargs) - NewFunc.__name__ = func.__name__ - NewFunc.__doc__ = func.__doc__ - NewFunc.__dict__.update(func.__dict__) - return NewFunc - - -def _NormalizeFullyQualifiedName(name): - """Remove leading period from fully-qualified type name. - - Due to b/13860351 in descriptor_database.py, types in the root namespace are - generated with a leading period. This function removes that prefix. - - Args: - name (str): The fully-qualified symbol name. - - Returns: - str: The normalized fully-qualified symbol name. - """ - return name.lstrip('.') - - -def _OptionsOrNone(descriptor_proto): - """Returns the value of the field `options`, or None if it is not set.""" - if descriptor_proto.HasField('options'): - return descriptor_proto.options - else: - return None - - -def _IsMessageSetExtension(field): - return (field.is_extension and - field.containing_type.has_options and - field.containing_type.GetOptions().message_set_wire_format and - field.type == descriptor.FieldDescriptor.TYPE_MESSAGE and - field.label == descriptor.FieldDescriptor.LABEL_OPTIONAL) - - -class DescriptorPool(object): - """A collection of protobufs dynamically constructed by descriptor protos.""" - - if _USE_C_DESCRIPTORS: - - def __new__(cls, descriptor_db=None): - # pylint: disable=protected-access - return descriptor._message.DescriptorPool(descriptor_db) - - def __init__(self, descriptor_db=None): - """Initializes a Pool of proto buffs. - - The descriptor_db argument to the constructor is provided to allow - specialized file descriptor proto lookup code to be triggered on demand. An - example would be an implementation which will read and compile a file - specified in a call to FindFileByName() and not require the call to Add() - at all. Results from this database will be cached internally here as well. - - Args: - descriptor_db: A secondary source of file descriptors. - """ - - self._internal_db = descriptor_database.DescriptorDatabase() - self._descriptor_db = descriptor_db - self._descriptors = {} - self._enum_descriptors = {} - self._service_descriptors = {} - self._file_descriptors = {} - self._toplevel_extensions = {} - # TODO(jieluo): Remove _file_desc_by_toplevel_extension after - # maybe year 2020 for compatibility issue (with 3.4.1 only). - self._file_desc_by_toplevel_extension = {} - self._top_enum_values = {} - # We store extensions in two two-level mappings: The first key is the - # descriptor of the message being extended, the second key is the extension - # full name or its tag number. - self._extensions_by_name = collections.defaultdict(dict) - self._extensions_by_number = collections.defaultdict(dict) - - def _CheckConflictRegister(self, desc, desc_name, file_name): - """Check if the descriptor name conflicts with another of the same name. - - Args: - desc: Descriptor of a message, enum, service, extension or enum value. - desc_name (str): the full name of desc. - file_name (str): The file name of descriptor. - """ - for register, descriptor_type in [ - (self._descriptors, descriptor.Descriptor), - (self._enum_descriptors, descriptor.EnumDescriptor), - (self._service_descriptors, descriptor.ServiceDescriptor), - (self._toplevel_extensions, descriptor.FieldDescriptor), - (self._top_enum_values, descriptor.EnumValueDescriptor)]: - if desc_name in register: - old_desc = register[desc_name] - if isinstance(old_desc, descriptor.EnumValueDescriptor): - old_file = old_desc.type.file.name - else: - old_file = old_desc.file.name - - if not isinstance(desc, descriptor_type) or ( - old_file != file_name): - error_msg = ('Conflict register for file "' + file_name + - '": ' + desc_name + - ' is already defined in file "' + - old_file + '". Please fix the conflict by adding ' - 'package name on the proto file, or use different ' - 'name for the duplication.') - if isinstance(desc, descriptor.EnumValueDescriptor): - error_msg += ('\nNote: enum values appear as ' - 'siblings of the enum type instead of ' - 'children of it.') - - raise TypeError(error_msg) - - return - - def Add(self, file_desc_proto): - """Adds the FileDescriptorProto and its types to this pool. - - Args: - file_desc_proto (FileDescriptorProto): The file descriptor to add. - """ - - self._internal_db.Add(file_desc_proto) - - def AddSerializedFile(self, serialized_file_desc_proto): - """Adds the FileDescriptorProto and its types to this pool. - - Args: - serialized_file_desc_proto (bytes): A bytes string, serialization of the - :class:`FileDescriptorProto` to add. - - Returns: - FileDescriptor: Descriptor for the added file. - """ - - # pylint: disable=g-import-not-at-top - from google.protobuf import descriptor_pb2 - file_desc_proto = descriptor_pb2.FileDescriptorProto.FromString( - serialized_file_desc_proto) - file_desc = self._ConvertFileProtoToFileDescriptor(file_desc_proto) - file_desc.serialized_pb = serialized_file_desc_proto - return file_desc - - # Add Descriptor to descriptor pool is dreprecated. Please use Add() - # or AddSerializedFile() to add a FileDescriptorProto instead. - @_Deprecated - def AddDescriptor(self, desc): - self._AddDescriptor(desc) - - # Never call this method. It is for internal usage only. - def _AddDescriptor(self, desc): - """Adds a Descriptor to the pool, non-recursively. - - If the Descriptor contains nested messages or enums, the caller must - explicitly register them. This method also registers the FileDescriptor - associated with the message. - - Args: - desc: A Descriptor. - """ - if not isinstance(desc, descriptor.Descriptor): - raise TypeError('Expected instance of descriptor.Descriptor.') - - self._CheckConflictRegister(desc, desc.full_name, desc.file.name) - - self._descriptors[desc.full_name] = desc - self._AddFileDescriptor(desc.file) - - # Add EnumDescriptor to descriptor pool is dreprecated. Please use Add() - # or AddSerializedFile() to add a FileDescriptorProto instead. - @_Deprecated - def AddEnumDescriptor(self, enum_desc): - self._AddEnumDescriptor(enum_desc) - - # Never call this method. It is for internal usage only. - def _AddEnumDescriptor(self, enum_desc): - """Adds an EnumDescriptor to the pool. - - This method also registers the FileDescriptor associated with the enum. - - Args: - enum_desc: An EnumDescriptor. - """ - - if not isinstance(enum_desc, descriptor.EnumDescriptor): - raise TypeError('Expected instance of descriptor.EnumDescriptor.') - - file_name = enum_desc.file.name - self._CheckConflictRegister(enum_desc, enum_desc.full_name, file_name) - self._enum_descriptors[enum_desc.full_name] = enum_desc - - # Top enum values need to be indexed. - # Count the number of dots to see whether the enum is toplevel or nested - # in a message. We cannot use enum_desc.containing_type at this stage. - if enum_desc.file.package: - top_level = (enum_desc.full_name.count('.') - - enum_desc.file.package.count('.') == 1) - else: - top_level = enum_desc.full_name.count('.') == 0 - if top_level: - file_name = enum_desc.file.name - package = enum_desc.file.package - for enum_value in enum_desc.values: - full_name = _NormalizeFullyQualifiedName( - '.'.join((package, enum_value.name))) - self._CheckConflictRegister(enum_value, full_name, file_name) - self._top_enum_values[full_name] = enum_value - self._AddFileDescriptor(enum_desc.file) - - # Add ServiceDescriptor to descriptor pool is dreprecated. Please use Add() - # or AddSerializedFile() to add a FileDescriptorProto instead. - @_Deprecated - def AddServiceDescriptor(self, service_desc): - self._AddServiceDescriptor(service_desc) - - # Never call this method. It is for internal usage only. - def _AddServiceDescriptor(self, service_desc): - """Adds a ServiceDescriptor to the pool. - - Args: - service_desc: A ServiceDescriptor. - """ - - if not isinstance(service_desc, descriptor.ServiceDescriptor): - raise TypeError('Expected instance of descriptor.ServiceDescriptor.') - - self._CheckConflictRegister(service_desc, service_desc.full_name, - service_desc.file.name) - self._service_descriptors[service_desc.full_name] = service_desc - - # Add ExtensionDescriptor to descriptor pool is dreprecated. Please use Add() - # or AddSerializedFile() to add a FileDescriptorProto instead. - @_Deprecated - def AddExtensionDescriptor(self, extension): - self._AddExtensionDescriptor(extension) - - # Never call this method. It is for internal usage only. - def _AddExtensionDescriptor(self, extension): - """Adds a FieldDescriptor describing an extension to the pool. - - Args: - extension: A FieldDescriptor. - - Raises: - AssertionError: when another extension with the same number extends the - same message. - TypeError: when the specified extension is not a - descriptor.FieldDescriptor. - """ - if not (isinstance(extension, descriptor.FieldDescriptor) and - extension.is_extension): - raise TypeError('Expected an extension descriptor.') - - if extension.extension_scope is None: - self._toplevel_extensions[extension.full_name] = extension - - try: - existing_desc = self._extensions_by_number[ - extension.containing_type][extension.number] - except KeyError: - pass - else: - if extension is not existing_desc: - raise AssertionError( - 'Extensions "%s" and "%s" both try to extend message type "%s" ' - 'with field number %d.' % - (extension.full_name, existing_desc.full_name, - extension.containing_type.full_name, extension.number)) - - self._extensions_by_number[extension.containing_type][ - extension.number] = extension - self._extensions_by_name[extension.containing_type][ - extension.full_name] = extension - - # Also register MessageSet extensions with the type name. - if _IsMessageSetExtension(extension): - self._extensions_by_name[extension.containing_type][ - extension.message_type.full_name] = extension - - @_Deprecated - def AddFileDescriptor(self, file_desc): - self._InternalAddFileDescriptor(file_desc) - - # Never call this method. It is for internal usage only. - def _InternalAddFileDescriptor(self, file_desc): - """Adds a FileDescriptor to the pool, non-recursively. - - If the FileDescriptor contains messages or enums, the caller must explicitly - register them. - - Args: - file_desc: A FileDescriptor. - """ - - self._AddFileDescriptor(file_desc) - # TODO(jieluo): This is a temporary solution for FieldDescriptor.file. - # FieldDescriptor.file is added in code gen. Remove this solution after - # maybe 2020 for compatibility reason (with 3.4.1 only). - for extension in file_desc.extensions_by_name.values(): - self._file_desc_by_toplevel_extension[ - extension.full_name] = file_desc - - def _AddFileDescriptor(self, file_desc): - """Adds a FileDescriptor to the pool, non-recursively. - - If the FileDescriptor contains messages or enums, the caller must explicitly - register them. - - Args: - file_desc: A FileDescriptor. - """ - - if not isinstance(file_desc, descriptor.FileDescriptor): - raise TypeError('Expected instance of descriptor.FileDescriptor.') - self._file_descriptors[file_desc.name] = file_desc - - def FindFileByName(self, file_name): - """Gets a FileDescriptor by file name. - - Args: - file_name (str): The path to the file to get a descriptor for. - - Returns: - FileDescriptor: The descriptor for the named file. - - Raises: - KeyError: if the file cannot be found in the pool. - """ - - try: - return self._file_descriptors[file_name] - except KeyError: - pass - - try: - file_proto = self._internal_db.FindFileByName(file_name) - except KeyError as error: - if self._descriptor_db: - file_proto = self._descriptor_db.FindFileByName(file_name) - else: - raise error - if not file_proto: - raise KeyError('Cannot find a file named %s' % file_name) - return self._ConvertFileProtoToFileDescriptor(file_proto) - - def FindFileContainingSymbol(self, symbol): - """Gets the FileDescriptor for the file containing the specified symbol. - - Args: - symbol (str): The name of the symbol to search for. - - Returns: - FileDescriptor: Descriptor for the file that contains the specified - symbol. - - Raises: - KeyError: if the file cannot be found in the pool. - """ - - symbol = _NormalizeFullyQualifiedName(symbol) - try: - return self._InternalFindFileContainingSymbol(symbol) - except KeyError: - pass - - try: - # Try fallback database. Build and find again if possible. - self._FindFileContainingSymbolInDb(symbol) - return self._InternalFindFileContainingSymbol(symbol) - except KeyError: - raise KeyError('Cannot find a file containing %s' % symbol) - - def _InternalFindFileContainingSymbol(self, symbol): - """Gets the already built FileDescriptor containing the specified symbol. - - Args: - symbol (str): The name of the symbol to search for. - - Returns: - FileDescriptor: Descriptor for the file that contains the specified - symbol. - - Raises: - KeyError: if the file cannot be found in the pool. - """ - try: - return self._descriptors[symbol].file - except KeyError: - pass - - try: - return self._enum_descriptors[symbol].file - except KeyError: - pass - - try: - return self._service_descriptors[symbol].file - except KeyError: - pass - - try: - return self._top_enum_values[symbol].type.file - except KeyError: - pass - - try: - return self._file_desc_by_toplevel_extension[symbol] - except KeyError: - pass - - # Try fields, enum values and nested extensions inside a message. - top_name, _, sub_name = symbol.rpartition('.') - try: - message = self.FindMessageTypeByName(top_name) - assert (sub_name in message.extensions_by_name or - sub_name in message.fields_by_name or - sub_name in message.enum_values_by_name) - return message.file - except (KeyError, AssertionError): - raise KeyError('Cannot find a file containing %s' % symbol) - - def FindMessageTypeByName(self, full_name): - """Loads the named descriptor from the pool. - - Args: - full_name (str): The full name of the descriptor to load. - - Returns: - Descriptor: The descriptor for the named type. - - Raises: - KeyError: if the message cannot be found in the pool. - """ - - full_name = _NormalizeFullyQualifiedName(full_name) - if full_name not in self._descriptors: - self._FindFileContainingSymbolInDb(full_name) - return self._descriptors[full_name] - - def FindEnumTypeByName(self, full_name): - """Loads the named enum descriptor from the pool. - - Args: - full_name (str): The full name of the enum descriptor to load. - - Returns: - EnumDescriptor: The enum descriptor for the named type. - - Raises: - KeyError: if the enum cannot be found in the pool. - """ - - full_name = _NormalizeFullyQualifiedName(full_name) - if full_name not in self._enum_descriptors: - self._FindFileContainingSymbolInDb(full_name) - return self._enum_descriptors[full_name] - - def FindFieldByName(self, full_name): - """Loads the named field descriptor from the pool. - - Args: - full_name (str): The full name of the field descriptor to load. - - Returns: - FieldDescriptor: The field descriptor for the named field. - - Raises: - KeyError: if the field cannot be found in the pool. - """ - full_name = _NormalizeFullyQualifiedName(full_name) - message_name, _, field_name = full_name.rpartition('.') - message_descriptor = self.FindMessageTypeByName(message_name) - return message_descriptor.fields_by_name[field_name] - - def FindOneofByName(self, full_name): - """Loads the named oneof descriptor from the pool. - - Args: - full_name (str): The full name of the oneof descriptor to load. - - Returns: - OneofDescriptor: The oneof descriptor for the named oneof. - - Raises: - KeyError: if the oneof cannot be found in the pool. - """ - full_name = _NormalizeFullyQualifiedName(full_name) - message_name, _, oneof_name = full_name.rpartition('.') - message_descriptor = self.FindMessageTypeByName(message_name) - return message_descriptor.oneofs_by_name[oneof_name] - - def FindExtensionByName(self, full_name): - """Loads the named extension descriptor from the pool. - - Args: - full_name (str): The full name of the extension descriptor to load. - - Returns: - FieldDescriptor: The field descriptor for the named extension. - - Raises: - KeyError: if the extension cannot be found in the pool. - """ - full_name = _NormalizeFullyQualifiedName(full_name) - try: - # The proto compiler does not give any link between the FileDescriptor - # and top-level extensions unless the FileDescriptorProto is added to - # the DescriptorDatabase, but this can impact memory usage. - # So we registered these extensions by name explicitly. - return self._toplevel_extensions[full_name] - except KeyError: - pass - message_name, _, extension_name = full_name.rpartition('.') - try: - # Most extensions are nested inside a message. - scope = self.FindMessageTypeByName(message_name) - except KeyError: - # Some extensions are defined at file scope. - scope = self._FindFileContainingSymbolInDb(full_name) - return scope.extensions_by_name[extension_name] - - def FindExtensionByNumber(self, message_descriptor, number): - """Gets the extension of the specified message with the specified number. - - Extensions have to be registered to this pool by calling :func:`Add` or - :func:`AddExtensionDescriptor`. - - Args: - message_descriptor (Descriptor): descriptor of the extended message. - number (int): Number of the extension field. - - Returns: - FieldDescriptor: The descriptor for the extension. - - Raises: - KeyError: when no extension with the given number is known for the - specified message. - """ - try: - return self._extensions_by_number[message_descriptor][number] - except KeyError: - self._TryLoadExtensionFromDB(message_descriptor, number) - return self._extensions_by_number[message_descriptor][number] - - def FindAllExtensions(self, message_descriptor): - """Gets all the known extensions of a given message. - - Extensions have to be registered to this pool by build related - :func:`Add` or :func:`AddExtensionDescriptor`. - - Args: - message_descriptor (Descriptor): Descriptor of the extended message. - - Returns: - list[FieldDescriptor]: Field descriptors describing the extensions. - """ - # Fallback to descriptor db if FindAllExtensionNumbers is provided. - if self._descriptor_db and hasattr( - self._descriptor_db, 'FindAllExtensionNumbers'): - full_name = message_descriptor.full_name - all_numbers = self._descriptor_db.FindAllExtensionNumbers(full_name) - for number in all_numbers: - if number in self._extensions_by_number[message_descriptor]: - continue - self._TryLoadExtensionFromDB(message_descriptor, number) - - return list(self._extensions_by_number[message_descriptor].values()) - - def _TryLoadExtensionFromDB(self, message_descriptor, number): - """Try to Load extensions from descriptor db. - - Args: - message_descriptor: descriptor of the extended message. - number: the extension number that needs to be loaded. - """ - if not self._descriptor_db: - return - # Only supported when FindFileContainingExtension is provided. - if not hasattr( - self._descriptor_db, 'FindFileContainingExtension'): - return - - full_name = message_descriptor.full_name - file_proto = self._descriptor_db.FindFileContainingExtension( - full_name, number) - - if file_proto is None: - return - - try: - self._ConvertFileProtoToFileDescriptor(file_proto) - except: - warn_msg = ('Unable to load proto file %s for extension number %d.' % - (file_proto.name, number)) - warnings.warn(warn_msg, RuntimeWarning) - - def FindServiceByName(self, full_name): - """Loads the named service descriptor from the pool. - - Args: - full_name (str): The full name of the service descriptor to load. - - Returns: - ServiceDescriptor: The service descriptor for the named service. - - Raises: - KeyError: if the service cannot be found in the pool. - """ - full_name = _NormalizeFullyQualifiedName(full_name) - if full_name not in self._service_descriptors: - self._FindFileContainingSymbolInDb(full_name) - return self._service_descriptors[full_name] - - def FindMethodByName(self, full_name): - """Loads the named service method descriptor from the pool. - - Args: - full_name (str): The full name of the method descriptor to load. - - Returns: - MethodDescriptor: The method descriptor for the service method. - - Raises: - KeyError: if the method cannot be found in the pool. - """ - full_name = _NormalizeFullyQualifiedName(full_name) - service_name, _, method_name = full_name.rpartition('.') - service_descriptor = self.FindServiceByName(service_name) - return service_descriptor.methods_by_name[method_name] - - def _FindFileContainingSymbolInDb(self, symbol): - """Finds the file in descriptor DB containing the specified symbol. - - Args: - symbol (str): The name of the symbol to search for. - - Returns: - FileDescriptor: The file that contains the specified symbol. - - Raises: - KeyError: if the file cannot be found in the descriptor database. - """ - try: - file_proto = self._internal_db.FindFileContainingSymbol(symbol) - except KeyError as error: - if self._descriptor_db: - file_proto = self._descriptor_db.FindFileContainingSymbol(symbol) - else: - raise error - if not file_proto: - raise KeyError('Cannot find a file containing %s' % symbol) - return self._ConvertFileProtoToFileDescriptor(file_proto) - - def _ConvertFileProtoToFileDescriptor(self, file_proto): - """Creates a FileDescriptor from a proto or returns a cached copy. - - This method also has the side effect of loading all the symbols found in - the file into the appropriate dictionaries in the pool. - - Args: - file_proto: The proto to convert. - - Returns: - A FileDescriptor matching the passed in proto. - """ - if file_proto.name not in self._file_descriptors: - built_deps = list(self._GetDeps(file_proto.dependency)) - direct_deps = [self.FindFileByName(n) for n in file_proto.dependency] - public_deps = [direct_deps[i] for i in file_proto.public_dependency] - - file_descriptor = descriptor.FileDescriptor( - pool=self, - name=file_proto.name, - package=file_proto.package, - syntax=file_proto.syntax, - options=_OptionsOrNone(file_proto), - serialized_pb=file_proto.SerializeToString(), - dependencies=direct_deps, - public_dependencies=public_deps, - # pylint: disable=protected-access - create_key=descriptor._internal_create_key) - scope = {} - - # This loop extracts all the message and enum types from all the - # dependencies of the file_proto. This is necessary to create the - # scope of available message types when defining the passed in - # file proto. - for dependency in built_deps: - scope.update(self._ExtractSymbols( - dependency.message_types_by_name.values())) - scope.update((_PrefixWithDot(enum.full_name), enum) - for enum in dependency.enum_types_by_name.values()) - - for message_type in file_proto.message_type: - message_desc = self._ConvertMessageDescriptor( - message_type, file_proto.package, file_descriptor, scope, - file_proto.syntax) - file_descriptor.message_types_by_name[message_desc.name] = ( - message_desc) - - for enum_type in file_proto.enum_type: - file_descriptor.enum_types_by_name[enum_type.name] = ( - self._ConvertEnumDescriptor(enum_type, file_proto.package, - file_descriptor, None, scope, True)) - - for index, extension_proto in enumerate(file_proto.extension): - extension_desc = self._MakeFieldDescriptor( - extension_proto, file_proto.package, index, file_descriptor, - is_extension=True) - extension_desc.containing_type = self._GetTypeFromScope( - file_descriptor.package, extension_proto.extendee, scope) - self._SetFieldType(extension_proto, extension_desc, - file_descriptor.package, scope) - file_descriptor.extensions_by_name[extension_desc.name] = ( - extension_desc) - self._file_desc_by_toplevel_extension[extension_desc.full_name] = ( - file_descriptor) - - for desc_proto in file_proto.message_type: - self._SetAllFieldTypes(file_proto.package, desc_proto, scope) - - if file_proto.package: - desc_proto_prefix = _PrefixWithDot(file_proto.package) - else: - desc_proto_prefix = '' - - for desc_proto in file_proto.message_type: - desc = self._GetTypeFromScope( - desc_proto_prefix, desc_proto.name, scope) - file_descriptor.message_types_by_name[desc_proto.name] = desc - - for index, service_proto in enumerate(file_proto.service): - file_descriptor.services_by_name[service_proto.name] = ( - self._MakeServiceDescriptor(service_proto, index, scope, - file_proto.package, file_descriptor)) - - self._file_descriptors[file_proto.name] = file_descriptor - - # Add extensions to the pool - file_desc = self._file_descriptors[file_proto.name] - for extension in file_desc.extensions_by_name.values(): - self._AddExtensionDescriptor(extension) - for message_type in file_desc.message_types_by_name.values(): - for extension in message_type.extensions: - self._AddExtensionDescriptor(extension) - - return file_desc - - def _ConvertMessageDescriptor(self, desc_proto, package=None, file_desc=None, - scope=None, syntax=None): - """Adds the proto to the pool in the specified package. - - Args: - desc_proto: The descriptor_pb2.DescriptorProto protobuf message. - package: The package the proto should be located in. - file_desc: The file containing this message. - scope: Dict mapping short and full symbols to message and enum types. - syntax: string indicating syntax of the file ("proto2" or "proto3") - - Returns: - The added descriptor. - """ - - if package: - desc_name = '.'.join((package, desc_proto.name)) - else: - desc_name = desc_proto.name - - if file_desc is None: - file_name = None - else: - file_name = file_desc.name - - if scope is None: - scope = {} - - nested = [ - self._ConvertMessageDescriptor( - nested, desc_name, file_desc, scope, syntax) - for nested in desc_proto.nested_type] - enums = [ - self._ConvertEnumDescriptor(enum, desc_name, file_desc, None, - scope, False) - for enum in desc_proto.enum_type] - fields = [self._MakeFieldDescriptor(field, desc_name, index, file_desc) - for index, field in enumerate(desc_proto.field)] - extensions = [ - self._MakeFieldDescriptor(extension, desc_name, index, file_desc, - is_extension=True) - for index, extension in enumerate(desc_proto.extension)] - oneofs = [ - # pylint: disable=g-complex-comprehension - descriptor.OneofDescriptor( - desc.name, - '.'.join((desc_name, desc.name)), - index, - None, - [], - _OptionsOrNone(desc), - # pylint: disable=protected-access - create_key=descriptor._internal_create_key) - for index, desc in enumerate(desc_proto.oneof_decl) - ] - extension_ranges = [(r.start, r.end) for r in desc_proto.extension_range] - if extension_ranges: - is_extendable = True - else: - is_extendable = False - desc = descriptor.Descriptor( - name=desc_proto.name, - full_name=desc_name, - filename=file_name, - containing_type=None, - fields=fields, - oneofs=oneofs, - nested_types=nested, - enum_types=enums, - extensions=extensions, - options=_OptionsOrNone(desc_proto), - is_extendable=is_extendable, - extension_ranges=extension_ranges, - file=file_desc, - serialized_start=None, - serialized_end=None, - syntax=syntax, - # pylint: disable=protected-access - create_key=descriptor._internal_create_key) - for nested in desc.nested_types: - nested.containing_type = desc - for enum in desc.enum_types: - enum.containing_type = desc - for field_index, field_desc in enumerate(desc_proto.field): - if field_desc.HasField('oneof_index'): - oneof_index = field_desc.oneof_index - oneofs[oneof_index].fields.append(fields[field_index]) - fields[field_index].containing_oneof = oneofs[oneof_index] - - scope[_PrefixWithDot(desc_name)] = desc - self._CheckConflictRegister(desc, desc.full_name, desc.file.name) - self._descriptors[desc_name] = desc - return desc - - def _ConvertEnumDescriptor(self, enum_proto, package=None, file_desc=None, - containing_type=None, scope=None, top_level=False): - """Make a protobuf EnumDescriptor given an EnumDescriptorProto protobuf. - - Args: - enum_proto: The descriptor_pb2.EnumDescriptorProto protobuf message. - package: Optional package name for the new message EnumDescriptor. - file_desc: The file containing the enum descriptor. - containing_type: The type containing this enum. - scope: Scope containing available types. - top_level: If True, the enum is a top level symbol. If False, the enum - is defined inside a message. - - Returns: - The added descriptor - """ - - if package: - enum_name = '.'.join((package, enum_proto.name)) - else: - enum_name = enum_proto.name - - if file_desc is None: - file_name = None - else: - file_name = file_desc.name - - values = [self._MakeEnumValueDescriptor(value, index) - for index, value in enumerate(enum_proto.value)] - desc = descriptor.EnumDescriptor(name=enum_proto.name, - full_name=enum_name, - filename=file_name, - file=file_desc, - values=values, - containing_type=containing_type, - options=_OptionsOrNone(enum_proto), - # pylint: disable=protected-access - create_key=descriptor._internal_create_key) - scope['.%s' % enum_name] = desc - self._CheckConflictRegister(desc, desc.full_name, desc.file.name) - self._enum_descriptors[enum_name] = desc - - # Add top level enum values. - if top_level: - for value in values: - full_name = _NormalizeFullyQualifiedName( - '.'.join((package, value.name))) - self._CheckConflictRegister(value, full_name, file_name) - self._top_enum_values[full_name] = value - - return desc - - def _MakeFieldDescriptor(self, field_proto, message_name, index, - file_desc, is_extension=False): - """Creates a field descriptor from a FieldDescriptorProto. - - For message and enum type fields, this method will do a look up - in the pool for the appropriate descriptor for that type. If it - is unavailable, it will fall back to the _source function to - create it. If this type is still unavailable, construction will - fail. - - Args: - field_proto: The proto describing the field. - message_name: The name of the containing message. - index: Index of the field - file_desc: The file containing the field descriptor. - is_extension: Indication that this field is for an extension. - - Returns: - An initialized FieldDescriptor object - """ - - if message_name: - full_name = '.'.join((message_name, field_proto.name)) - else: - full_name = field_proto.name - - if field_proto.json_name: - json_name = field_proto.json_name - else: - json_name = None - - return descriptor.FieldDescriptor( - name=field_proto.name, - full_name=full_name, - index=index, - number=field_proto.number, - type=field_proto.type, - cpp_type=None, - message_type=None, - enum_type=None, - containing_type=None, - label=field_proto.label, - has_default_value=False, - default_value=None, - is_extension=is_extension, - extension_scope=None, - options=_OptionsOrNone(field_proto), - json_name=json_name, - file=file_desc, - # pylint: disable=protected-access - create_key=descriptor._internal_create_key) - - def _SetAllFieldTypes(self, package, desc_proto, scope): - """Sets all the descriptor's fields's types. - - This method also sets the containing types on any extensions. - - Args: - package: The current package of desc_proto. - desc_proto: The message descriptor to update. - scope: Enclosing scope of available types. - """ - - package = _PrefixWithDot(package) - - main_desc = self._GetTypeFromScope(package, desc_proto.name, scope) - - if package == '.': - nested_package = _PrefixWithDot(desc_proto.name) - else: - nested_package = '.'.join([package, desc_proto.name]) - - for field_proto, field_desc in zip(desc_proto.field, main_desc.fields): - self._SetFieldType(field_proto, field_desc, nested_package, scope) - - for extension_proto, extension_desc in ( - zip(desc_proto.extension, main_desc.extensions)): - extension_desc.containing_type = self._GetTypeFromScope( - nested_package, extension_proto.extendee, scope) - self._SetFieldType(extension_proto, extension_desc, nested_package, scope) - - for nested_type in desc_proto.nested_type: - self._SetAllFieldTypes(nested_package, nested_type, scope) - - def _SetFieldType(self, field_proto, field_desc, package, scope): - """Sets the field's type, cpp_type, message_type and enum_type. - - Args: - field_proto: Data about the field in proto format. - field_desc: The descriptor to modify. - package: The package the field's container is in. - scope: Enclosing scope of available types. - """ - if field_proto.type_name: - desc = self._GetTypeFromScope(package, field_proto.type_name, scope) - else: - desc = None - - if not field_proto.HasField('type'): - if isinstance(desc, descriptor.Descriptor): - field_proto.type = descriptor.FieldDescriptor.TYPE_MESSAGE - else: - field_proto.type = descriptor.FieldDescriptor.TYPE_ENUM - - field_desc.cpp_type = descriptor.FieldDescriptor.ProtoTypeToCppProtoType( - field_proto.type) - - if (field_proto.type == descriptor.FieldDescriptor.TYPE_MESSAGE - or field_proto.type == descriptor.FieldDescriptor.TYPE_GROUP): - field_desc.message_type = desc - - if field_proto.type == descriptor.FieldDescriptor.TYPE_ENUM: - field_desc.enum_type = desc - - if field_proto.label == descriptor.FieldDescriptor.LABEL_REPEATED: - field_desc.has_default_value = False - field_desc.default_value = [] - elif field_proto.HasField('default_value'): - field_desc.has_default_value = True - if (field_proto.type == descriptor.FieldDescriptor.TYPE_DOUBLE or - field_proto.type == descriptor.FieldDescriptor.TYPE_FLOAT): - field_desc.default_value = float(field_proto.default_value) - elif field_proto.type == descriptor.FieldDescriptor.TYPE_STRING: - field_desc.default_value = field_proto.default_value - elif field_proto.type == descriptor.FieldDescriptor.TYPE_BOOL: - field_desc.default_value = field_proto.default_value.lower() == 'true' - elif field_proto.type == descriptor.FieldDescriptor.TYPE_ENUM: - field_desc.default_value = field_desc.enum_type.values_by_name[ - field_proto.default_value].number - elif field_proto.type == descriptor.FieldDescriptor.TYPE_BYTES: - field_desc.default_value = text_encoding.CUnescape( - field_proto.default_value) - elif field_proto.type == descriptor.FieldDescriptor.TYPE_MESSAGE: - field_desc.default_value = None - else: - # All other types are of the "int" type. - field_desc.default_value = int(field_proto.default_value) - else: - field_desc.has_default_value = False - if (field_proto.type == descriptor.FieldDescriptor.TYPE_DOUBLE or - field_proto.type == descriptor.FieldDescriptor.TYPE_FLOAT): - field_desc.default_value = 0.0 - elif field_proto.type == descriptor.FieldDescriptor.TYPE_STRING: - field_desc.default_value = u'' - elif field_proto.type == descriptor.FieldDescriptor.TYPE_BOOL: - field_desc.default_value = False - elif field_proto.type == descriptor.FieldDescriptor.TYPE_ENUM: - field_desc.default_value = field_desc.enum_type.values[0].number - elif field_proto.type == descriptor.FieldDescriptor.TYPE_BYTES: - field_desc.default_value = b'' - elif field_proto.type == descriptor.FieldDescriptor.TYPE_MESSAGE: - field_desc.default_value = None - elif field_proto.type == descriptor.FieldDescriptor.TYPE_GROUP: - field_desc.default_value = None - else: - # All other types are of the "int" type. - field_desc.default_value = 0 - - field_desc.type = field_proto.type - - def _MakeEnumValueDescriptor(self, value_proto, index): - """Creates a enum value descriptor object from a enum value proto. - - Args: - value_proto: The proto describing the enum value. - index: The index of the enum value. - - Returns: - An initialized EnumValueDescriptor object. - """ - - return descriptor.EnumValueDescriptor( - name=value_proto.name, - index=index, - number=value_proto.number, - options=_OptionsOrNone(value_proto), - type=None, - # pylint: disable=protected-access - create_key=descriptor._internal_create_key) - - def _MakeServiceDescriptor(self, service_proto, service_index, scope, - package, file_desc): - """Make a protobuf ServiceDescriptor given a ServiceDescriptorProto. - - Args: - service_proto: The descriptor_pb2.ServiceDescriptorProto protobuf message. - service_index: The index of the service in the File. - scope: Dict mapping short and full symbols to message and enum types. - package: Optional package name for the new message EnumDescriptor. - file_desc: The file containing the service descriptor. - - Returns: - The added descriptor. - """ - - if package: - service_name = '.'.join((package, service_proto.name)) - else: - service_name = service_proto.name - - methods = [self._MakeMethodDescriptor(method_proto, service_name, package, - scope, index) - for index, method_proto in enumerate(service_proto.method)] - desc = descriptor.ServiceDescriptor( - name=service_proto.name, - full_name=service_name, - index=service_index, - methods=methods, - options=_OptionsOrNone(service_proto), - file=file_desc, - # pylint: disable=protected-access - create_key=descriptor._internal_create_key) - self._CheckConflictRegister(desc, desc.full_name, desc.file.name) - self._service_descriptors[service_name] = desc - return desc - - def _MakeMethodDescriptor(self, method_proto, service_name, package, scope, - index): - """Creates a method descriptor from a MethodDescriptorProto. - - Args: - method_proto: The proto describing the method. - service_name: The name of the containing service. - package: Optional package name to look up for types. - scope: Scope containing available types. - index: Index of the method in the service. - - Returns: - An initialized MethodDescriptor object. - """ - full_name = '.'.join((service_name, method_proto.name)) - input_type = self._GetTypeFromScope( - package, method_proto.input_type, scope) - output_type = self._GetTypeFromScope( - package, method_proto.output_type, scope) - return descriptor.MethodDescriptor( - name=method_proto.name, - full_name=full_name, - index=index, - containing_service=None, - input_type=input_type, - output_type=output_type, - client_streaming=method_proto.client_streaming, - server_streaming=method_proto.server_streaming, - options=_OptionsOrNone(method_proto), - # pylint: disable=protected-access - create_key=descriptor._internal_create_key) - - def _ExtractSymbols(self, descriptors): - """Pulls out all the symbols from descriptor protos. - - Args: - descriptors: The messages to extract descriptors from. - Yields: - A two element tuple of the type name and descriptor object. - """ - - for desc in descriptors: - yield (_PrefixWithDot(desc.full_name), desc) - for symbol in self._ExtractSymbols(desc.nested_types): - yield symbol - for enum in desc.enum_types: - yield (_PrefixWithDot(enum.full_name), enum) - - def _GetDeps(self, dependencies, visited=None): - """Recursively finds dependencies for file protos. - - Args: - dependencies: The names of the files being depended on. - visited: The names of files already found. - - Yields: - Each direct and indirect dependency. - """ - - visited = visited or set() - for dependency in dependencies: - if dependency not in visited: - visited.add(dependency) - dep_desc = self.FindFileByName(dependency) - yield dep_desc - public_files = [d.name for d in dep_desc.public_dependencies] - yield from self._GetDeps(public_files, visited) - - def _GetTypeFromScope(self, package, type_name, scope): - """Finds a given type name in the current scope. - - Args: - package: The package the proto should be located in. - type_name: The name of the type to be found in the scope. - scope: Dict mapping short and full symbols to message and enum types. - - Returns: - The descriptor for the requested type. - """ - if type_name not in scope: - components = _PrefixWithDot(package).split('.') - while components: - possible_match = '.'.join(components + [type_name]) - if possible_match in scope: - type_name = possible_match - break - else: - components.pop(-1) - return scope[type_name] - - -def _PrefixWithDot(name): - return name if name.startswith('.') else '.%s' % name - - -if _USE_C_DESCRIPTORS: - # TODO(amauryfa): This pool could be constructed from Python code, when we - # support a flag like 'use_cpp_generated_pool=True'. - # pylint: disable=protected-access - _DEFAULT = descriptor._message.default_pool -else: - _DEFAULT = DescriptorPool() - - -def Default(): - return _DEFAULT diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/duration_pb2.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/duration_pb2.py deleted file mode 100644 index a8ecc07bdf..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/duration_pb2.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/duration.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1egoogle/protobuf/duration.proto\x12\x0fgoogle.protobuf\"*\n\x08\x44uration\x12\x0f\n\x07seconds\x18\x01 \x01(\x03\x12\r\n\x05nanos\x18\x02 \x01(\x05\x42\x83\x01\n\x13\x63om.google.protobufB\rDurationProtoP\x01Z1google.golang.org/protobuf/types/known/durationpb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.duration_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.google.protobufB\rDurationProtoP\001Z1google.golang.org/protobuf/types/known/durationpb\370\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' - _DURATION._serialized_start=51 - _DURATION._serialized_end=93 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/empty_pb2.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/empty_pb2.py deleted file mode 100644 index 0b4d554db3..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/empty_pb2.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/empty.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1bgoogle/protobuf/empty.proto\x12\x0fgoogle.protobuf\"\x07\n\x05\x45mptyB}\n\x13\x63om.google.protobufB\nEmptyProtoP\x01Z.google.golang.org/protobuf/types/known/emptypb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.empty_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.google.protobufB\nEmptyProtoP\001Z.google.golang.org/protobuf/types/known/emptypb\370\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' - _EMPTY._serialized_start=48 - _EMPTY._serialized_end=55 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/field_mask_pb2.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/field_mask_pb2.py deleted file mode 100644 index 80a4e96e59..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/field_mask_pb2.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/field_mask.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n google/protobuf/field_mask.proto\x12\x0fgoogle.protobuf\"\x1a\n\tFieldMask\x12\r\n\x05paths\x18\x01 \x03(\tB\x85\x01\n\x13\x63om.google.protobufB\x0e\x46ieldMaskProtoP\x01Z2google.golang.org/protobuf/types/known/fieldmaskpb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.field_mask_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.google.protobufB\016FieldMaskProtoP\001Z2google.golang.org/protobuf/types/known/fieldmaskpb\370\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' - _FIELDMASK._serialized_start=53 - _FIELDMASK._serialized_end=79 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/__init__.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/_parameterized.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/_parameterized.py deleted file mode 100644 index afdbb78c36..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/_parameterized.py +++ /dev/null @@ -1,443 +0,0 @@ -#! /usr/bin/env python -# -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Adds support for parameterized tests to Python's unittest TestCase class. - -A parameterized test is a method in a test case that is invoked with different -argument tuples. - -A simple example: - - class AdditionExample(parameterized.TestCase): - @parameterized.parameters( - (1, 2, 3), - (4, 5, 9), - (1, 1, 3)) - def testAddition(self, op1, op2, result): - self.assertEqual(result, op1 + op2) - - -Each invocation is a separate test case and properly isolated just -like a normal test method, with its own setUp/tearDown cycle. In the -example above, there are three separate testcases, one of which will -fail due to an assertion error (1 + 1 != 3). - -Parameters for individual test cases can be tuples (with positional parameters) -or dictionaries (with named parameters): - - class AdditionExample(parameterized.TestCase): - @parameterized.parameters( - {'op1': 1, 'op2': 2, 'result': 3}, - {'op1': 4, 'op2': 5, 'result': 9}, - ) - def testAddition(self, op1, op2, result): - self.assertEqual(result, op1 + op2) - -If a parameterized test fails, the error message will show the -original test name (which is modified internally) and the arguments -for the specific invocation, which are part of the string returned by -the shortDescription() method on test cases. - -The id method of the test, used internally by the unittest framework, -is also modified to show the arguments. To make sure that test names -stay the same across several invocations, object representations like - - >>> class Foo(object): - ... pass - >>> repr(Foo()) - '<__main__.Foo object at 0x23d8610>' - -are turned into '<__main__.Foo>'. For even more descriptive names, -especially in test logs, you can use the named_parameters decorator. In -this case, only tuples are supported, and the first parameters has to -be a string (or an object that returns an apt name when converted via -str()): - - class NamedExample(parameterized.TestCase): - @parameterized.named_parameters( - ('Normal', 'aa', 'aaa', True), - ('EmptyPrefix', '', 'abc', True), - ('BothEmpty', '', '', True)) - def testStartsWith(self, prefix, string, result): - self.assertEqual(result, strings.startswith(prefix)) - -Named tests also have the benefit that they can be run individually -from the command line: - - $ testmodule.py NamedExample.testStartsWithNormal - . - -------------------------------------------------------------------- - Ran 1 test in 0.000s - - OK - -Parameterized Classes -===================== -If invocation arguments are shared across test methods in a single -TestCase class, instead of decorating all test methods -individually, the class itself can be decorated: - - @parameterized.parameters( - (1, 2, 3) - (4, 5, 9)) - class ArithmeticTest(parameterized.TestCase): - def testAdd(self, arg1, arg2, result): - self.assertEqual(arg1 + arg2, result) - - def testSubtract(self, arg2, arg2, result): - self.assertEqual(result - arg1, arg2) - -Inputs from Iterables -===================== -If parameters should be shared across several test cases, or are dynamically -created from other sources, a single non-tuple iterable can be passed into -the decorator. This iterable will be used to obtain the test cases: - - class AdditionExample(parameterized.TestCase): - @parameterized.parameters( - c.op1, c.op2, c.result for c in testcases - ) - def testAddition(self, op1, op2, result): - self.assertEqual(result, op1 + op2) - - -Single-Argument Test Methods -============================ -If a test method takes only one argument, the single argument does not need to -be wrapped into a tuple: - - class NegativeNumberExample(parameterized.TestCase): - @parameterized.parameters( - -1, -3, -4, -5 - ) - def testIsNegative(self, arg): - self.assertTrue(IsNegative(arg)) -""" - -__author__ = 'tmarek@google.com (Torsten Marek)' - -import functools -import re -import types -import unittest -import uuid - -try: - # Since python 3 - import collections.abc as collections_abc -except ImportError: - # Won't work after python 3.8 - import collections as collections_abc - -ADDR_RE = re.compile(r'\<([a-zA-Z0-9_\-\.]+) object at 0x[a-fA-F0-9]+\>') -_SEPARATOR = uuid.uuid1().hex -_FIRST_ARG = object() -_ARGUMENT_REPR = object() - - -def _CleanRepr(obj): - return ADDR_RE.sub(r'<\1>', repr(obj)) - - -# Helper function formerly from the unittest module, removed from it in -# Python 2.7. -def _StrClass(cls): - return '%s.%s' % (cls.__module__, cls.__name__) - - -def _NonStringIterable(obj): - return (isinstance(obj, collections_abc.Iterable) and - not isinstance(obj, str)) - - -def _FormatParameterList(testcase_params): - if isinstance(testcase_params, collections_abc.Mapping): - return ', '.join('%s=%s' % (argname, _CleanRepr(value)) - for argname, value in testcase_params.items()) - elif _NonStringIterable(testcase_params): - return ', '.join(map(_CleanRepr, testcase_params)) - else: - return _FormatParameterList((testcase_params,)) - - -class _ParameterizedTestIter(object): - """Callable and iterable class for producing new test cases.""" - - def __init__(self, test_method, testcases, naming_type): - """Returns concrete test functions for a test and a list of parameters. - - The naming_type is used to determine the name of the concrete - functions as reported by the unittest framework. If naming_type is - _FIRST_ARG, the testcases must be tuples, and the first element must - have a string representation that is a valid Python identifier. - - Args: - test_method: The decorated test method. - testcases: (list of tuple/dict) A list of parameter - tuples/dicts for individual test invocations. - naming_type: The test naming type, either _NAMED or _ARGUMENT_REPR. - """ - self._test_method = test_method - self.testcases = testcases - self._naming_type = naming_type - - def __call__(self, *args, **kwargs): - raise RuntimeError('You appear to be running a parameterized test case ' - 'without having inherited from parameterized.' - 'TestCase. This is bad because none of ' - 'your test cases are actually being run.') - - def __iter__(self): - test_method = self._test_method - naming_type = self._naming_type - - def MakeBoundParamTest(testcase_params): - @functools.wraps(test_method) - def BoundParamTest(self): - if isinstance(testcase_params, collections_abc.Mapping): - test_method(self, **testcase_params) - elif _NonStringIterable(testcase_params): - test_method(self, *testcase_params) - else: - test_method(self, testcase_params) - - if naming_type is _FIRST_ARG: - # Signal the metaclass that the name of the test function is unique - # and descriptive. - BoundParamTest.__x_use_name__ = True - BoundParamTest.__name__ += str(testcase_params[0]) - testcase_params = testcase_params[1:] - elif naming_type is _ARGUMENT_REPR: - # __x_extra_id__ is used to pass naming information to the __new__ - # method of TestGeneratorMetaclass. - # The metaclass will make sure to create a unique, but nondescriptive - # name for this test. - BoundParamTest.__x_extra_id__ = '(%s)' % ( - _FormatParameterList(testcase_params),) - else: - raise RuntimeError('%s is not a valid naming type.' % (naming_type,)) - - BoundParamTest.__doc__ = '%s(%s)' % ( - BoundParamTest.__name__, _FormatParameterList(testcase_params)) - if test_method.__doc__: - BoundParamTest.__doc__ += '\n%s' % (test_method.__doc__,) - return BoundParamTest - return (MakeBoundParamTest(c) for c in self.testcases) - - -def _IsSingletonList(testcases): - """True iff testcases contains only a single non-tuple element.""" - return len(testcases) == 1 and not isinstance(testcases[0], tuple) - - -def _ModifyClass(class_object, testcases, naming_type): - assert not getattr(class_object, '_id_suffix', None), ( - 'Cannot add parameters to %s,' - ' which already has parameterized methods.' % (class_object,)) - class_object._id_suffix = id_suffix = {} - # We change the size of __dict__ while we iterate over it, - # which Python 3.x will complain about, so use copy(). - for name, obj in class_object.__dict__.copy().items(): - if (name.startswith(unittest.TestLoader.testMethodPrefix) - and isinstance(obj, types.FunctionType)): - delattr(class_object, name) - methods = {} - _UpdateClassDictForParamTestCase( - methods, id_suffix, name, - _ParameterizedTestIter(obj, testcases, naming_type)) - for name, meth in methods.items(): - setattr(class_object, name, meth) - - -def _ParameterDecorator(naming_type, testcases): - """Implementation of the parameterization decorators. - - Args: - naming_type: The naming type. - testcases: Testcase parameters. - - Returns: - A function for modifying the decorated object. - """ - def _Apply(obj): - if isinstance(obj, type): - _ModifyClass( - obj, - list(testcases) if not isinstance(testcases, collections_abc.Sequence) - else testcases, - naming_type) - return obj - else: - return _ParameterizedTestIter(obj, testcases, naming_type) - - if _IsSingletonList(testcases): - assert _NonStringIterable(testcases[0]), ( - 'Single parameter argument must be a non-string iterable') - testcases = testcases[0] - - return _Apply - - -def parameters(*testcases): # pylint: disable=invalid-name - """A decorator for creating parameterized tests. - - See the module docstring for a usage example. - Args: - *testcases: Parameters for the decorated method, either a single - iterable, or a list of tuples/dicts/objects (for tests - with only one argument). - - Returns: - A test generator to be handled by TestGeneratorMetaclass. - """ - return _ParameterDecorator(_ARGUMENT_REPR, testcases) - - -def named_parameters(*testcases): # pylint: disable=invalid-name - """A decorator for creating parameterized tests. - - See the module docstring for a usage example. The first element of - each parameter tuple should be a string and will be appended to the - name of the test method. - - Args: - *testcases: Parameters for the decorated method, either a single - iterable, or a list of tuples. - - Returns: - A test generator to be handled by TestGeneratorMetaclass. - """ - return _ParameterDecorator(_FIRST_ARG, testcases) - - -class TestGeneratorMetaclass(type): - """Metaclass for test cases with test generators. - - A test generator is an iterable in a testcase that produces callables. These - callables must be single-argument methods. These methods are injected into - the class namespace and the original iterable is removed. If the name of the - iterable conforms to the test pattern, the injected methods will be picked - up as tests by the unittest framework. - - In general, it is supposed to be used in conjunction with the - parameters decorator. - """ - - def __new__(mcs, class_name, bases, dct): - dct['_id_suffix'] = id_suffix = {} - for name, obj in dct.copy().items(): - if (name.startswith(unittest.TestLoader.testMethodPrefix) and - _NonStringIterable(obj)): - iterator = iter(obj) - dct.pop(name) - _UpdateClassDictForParamTestCase(dct, id_suffix, name, iterator) - - return type.__new__(mcs, class_name, bases, dct) - - -def _UpdateClassDictForParamTestCase(dct, id_suffix, name, iterator): - """Adds individual test cases to a dictionary. - - Args: - dct: The target dictionary. - id_suffix: The dictionary for mapping names to test IDs. - name: The original name of the test case. - iterator: The iterator generating the individual test cases. - """ - for idx, func in enumerate(iterator): - assert callable(func), 'Test generators must yield callables, got %r' % ( - func,) - if getattr(func, '__x_use_name__', False): - new_name = func.__name__ - else: - new_name = '%s%s%d' % (name, _SEPARATOR, idx) - assert new_name not in dct, ( - 'Name of parameterized test case "%s" not unique' % (new_name,)) - dct[new_name] = func - id_suffix[new_name] = getattr(func, '__x_extra_id__', '') - - -class TestCase(unittest.TestCase, metaclass=TestGeneratorMetaclass): - """Base class for test cases using the parameters decorator.""" - - def _OriginalName(self): - return self._testMethodName.split(_SEPARATOR)[0] - - def __str__(self): - return '%s (%s)' % (self._OriginalName(), _StrClass(self.__class__)) - - def id(self): # pylint: disable=invalid-name - """Returns the descriptive ID of the test. - - This is used internally by the unittesting framework to get a name - for the test to be used in reports. - - Returns: - The test id. - """ - return '%s.%s%s' % (_StrClass(self.__class__), - self._OriginalName(), - self._id_suffix.get(self._testMethodName, '')) - - -def CoopTestCase(other_base_class): - """Returns a new base class with a cooperative metaclass base. - - This enables the TestCase to be used in combination - with other base classes that have custom metaclasses, such as - mox.MoxTestBase. - - Only works with metaclasses that do not override type.__new__. - - Example: - - import google3 - import mox - - from google3.testing.pybase import parameterized - - class ExampleTest(parameterized.CoopTestCase(mox.MoxTestBase)): - ... - - Args: - other_base_class: (class) A test case base class. - - Returns: - A new class object. - """ - metaclass = type( - 'CoopMetaclass', - (other_base_class.__metaclass__, - TestGeneratorMetaclass), {}) - return metaclass( - 'CoopTestCase', - (other_base_class, TestCase), {}) diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/api_implementation.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/api_implementation.py deleted file mode 100644 index 7fef237670..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/api_implementation.py +++ /dev/null @@ -1,112 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Determine which implementation of the protobuf API is used in this process. -""" - -import os -import sys -import warnings - -try: - # pylint: disable=g-import-not-at-top - from google.protobuf.internal import _api_implementation - # The compile-time constants in the _api_implementation module can be used to - # switch to a certain implementation of the Python API at build time. - _api_version = _api_implementation.api_version -except ImportError: - _api_version = -1 # Unspecified by compiler flags. - -if _api_version == 1: - raise ValueError('api_version=1 is no longer supported.') - - -_default_implementation_type = ('cpp' if _api_version > 0 else 'python') - - -# This environment variable can be used to switch to a certain implementation -# of the Python API, overriding the compile-time constants in the -# _api_implementation module. Right now only 'python' and 'cpp' are valid -# values. Any other value will be ignored. -_implementation_type = os.getenv('PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION', - _default_implementation_type) - -if _implementation_type != 'python': - _implementation_type = 'cpp' - -if 'PyPy' in sys.version and _implementation_type == 'cpp': - warnings.warn('PyPy does not work yet with cpp protocol buffers. ' - 'Falling back to the python implementation.') - _implementation_type = 'python' - - -# Detect if serialization should be deterministic by default -try: - # The presence of this module in a build allows the proto implementation to - # be upgraded merely via build deps. - # - # NOTE: Merely importing this automatically enables deterministic proto - # serialization for C++ code, but we still need to export it as a boolean so - # that we can do the same for `_implementation_type == 'python'`. - # - # NOTE2: It is possible for C++ code to enable deterministic serialization by - # default _without_ affecting Python code, if the C++ implementation is not in - # use by this module. That is intended behavior, so we don't actually expose - # this boolean outside of this module. - # - # pylint: disable=g-import-not-at-top,unused-import - from google.protobuf import enable_deterministic_proto_serialization - _python_deterministic_proto_serialization = True -except ImportError: - _python_deterministic_proto_serialization = False - - -# Usage of this function is discouraged. Clients shouldn't care which -# implementation of the API is in use. Note that there is no guarantee -# that differences between APIs will be maintained. -# Please don't use this function if possible. -def Type(): - return _implementation_type - - -def _SetType(implementation_type): - """Never use! Only for protobuf benchmark.""" - global _implementation_type - _implementation_type = implementation_type - - -# See comment on 'Type' above. -def Version(): - return 2 - - -# For internal use only -def IsPythonDefaultSerializationDeterministic(): - return _python_deterministic_proto_serialization diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/builder.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/builder.py deleted file mode 100644 index 64353ee4af..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/builder.py +++ /dev/null @@ -1,130 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Builds descriptors, message classes and services for generated _pb2.py. - -This file is only called in python generated _pb2.py files. It builds -descriptors, message classes and services that users can directly use -in generated code. -""" - -__author__ = 'jieluo@google.com (Jie Luo)' - -from google.protobuf.internal import enum_type_wrapper -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database - -_sym_db = _symbol_database.Default() - - -def BuildMessageAndEnumDescriptors(file_des, module): - """Builds message and enum descriptors. - - Args: - file_des: FileDescriptor of the .proto file - module: Generated _pb2 module - """ - - def BuildNestedDescriptors(msg_des, prefix): - for (name, nested_msg) in msg_des.nested_types_by_name.items(): - module_name = prefix + name.upper() - module[module_name] = nested_msg - BuildNestedDescriptors(nested_msg, module_name + '_') - for enum_des in msg_des.enum_types: - module[prefix + enum_des.name.upper()] = enum_des - - for (name, msg_des) in file_des.message_types_by_name.items(): - module_name = '_' + name.upper() - module[module_name] = msg_des - BuildNestedDescriptors(msg_des, module_name + '_') - - -def BuildTopDescriptorsAndMessages(file_des, module_name, module): - """Builds top level descriptors and message classes. - - Args: - file_des: FileDescriptor of the .proto file - module_name: str, the name of generated _pb2 module - module: Generated _pb2 module - """ - - def BuildMessage(msg_des): - create_dict = {} - for (name, nested_msg) in msg_des.nested_types_by_name.items(): - create_dict[name] = BuildMessage(nested_msg) - create_dict['DESCRIPTOR'] = msg_des - create_dict['__module__'] = module_name - message_class = _reflection.GeneratedProtocolMessageType( - msg_des.name, (_message.Message,), create_dict) - _sym_db.RegisterMessage(message_class) - return message_class - - # top level enums - for (name, enum_des) in file_des.enum_types_by_name.items(): - module['_' + name.upper()] = enum_des - module[name] = enum_type_wrapper.EnumTypeWrapper(enum_des) - for enum_value in enum_des.values: - module[enum_value.name] = enum_value.number - - # top level extensions - for (name, extension_des) in file_des.extensions_by_name.items(): - module[name.upper() + '_FIELD_NUMBER'] = extension_des.number - module[name] = extension_des - - # services - for (name, service) in file_des.services_by_name.items(): - module['_' + name.upper()] = service - - # Build messages. - for (name, msg_des) in file_des.message_types_by_name.items(): - module[name] = BuildMessage(msg_des) - - -def BuildServices(file_des, module_name, module): - """Builds services classes and services stub class. - - Args: - file_des: FileDescriptor of the .proto file - module_name: str, the name of generated _pb2 module - module: Generated _pb2 module - """ - # pylint: disable=g-import-not-at-top - from google.protobuf import service as _service - from google.protobuf import service_reflection - # pylint: enable=g-import-not-at-top - for (name, service) in file_des.services_by_name.items(): - module[name] = service_reflection.GeneratedServiceType( - name, (_service.Service,), - dict(DESCRIPTOR=service, __module__=module_name)) - stub_name = name + '_Stub' - module[stub_name] = service_reflection.GeneratedServiceStubType( - stub_name, (module[name],), - dict(DESCRIPTOR=service, __module__=module_name)) diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/containers.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/containers.py deleted file mode 100644 index 29fbb53d2f..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/containers.py +++ /dev/null @@ -1,710 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Contains container classes to represent different protocol buffer types. - -This file defines container classes which represent categories of protocol -buffer field types which need extra maintenance. Currently these categories -are: - -- Repeated scalar fields - These are all repeated fields which aren't - composite (e.g. they are of simple types like int32, string, etc). -- Repeated composite fields - Repeated fields which are composite. This - includes groups and nested messages. -""" - -import collections.abc -import copy -import pickle -from typing import ( - Any, - Iterable, - Iterator, - List, - MutableMapping, - MutableSequence, - NoReturn, - Optional, - Sequence, - TypeVar, - Union, - overload, -) - - -_T = TypeVar('_T') -_K = TypeVar('_K') -_V = TypeVar('_V') - - -class BaseContainer(Sequence[_T]): - """Base container class.""" - - # Minimizes memory usage and disallows assignment to other attributes. - __slots__ = ['_message_listener', '_values'] - - def __init__(self, message_listener: Any) -> None: - """ - Args: - message_listener: A MessageListener implementation. - The RepeatedScalarFieldContainer will call this object's - Modified() method when it is modified. - """ - self._message_listener = message_listener - self._values = [] - - @overload - def __getitem__(self, key: int) -> _T: - ... - - @overload - def __getitem__(self, key: slice) -> List[_T]: - ... - - def __getitem__(self, key): - """Retrieves item by the specified key.""" - return self._values[key] - - def __len__(self) -> int: - """Returns the number of elements in the container.""" - return len(self._values) - - def __ne__(self, other: Any) -> bool: - """Checks if another instance isn't equal to this one.""" - # The concrete classes should define __eq__. - return not self == other - - __hash__ = None - - def __repr__(self) -> str: - return repr(self._values) - - def sort(self, *args, **kwargs) -> None: - # Continue to support the old sort_function keyword argument. - # This is expected to be a rare occurrence, so use LBYL to avoid - # the overhead of actually catching KeyError. - if 'sort_function' in kwargs: - kwargs['cmp'] = kwargs.pop('sort_function') - self._values.sort(*args, **kwargs) - - def reverse(self) -> None: - self._values.reverse() - - -# TODO(slebedev): Remove this. BaseContainer does *not* conform to -# MutableSequence, only its subclasses do. -collections.abc.MutableSequence.register(BaseContainer) - - -class RepeatedScalarFieldContainer(BaseContainer[_T], MutableSequence[_T]): - """Simple, type-checked, list-like container for holding repeated scalars.""" - - # Disallows assignment to other attributes. - __slots__ = ['_type_checker'] - - def __init__( - self, - message_listener: Any, - type_checker: Any, - ) -> None: - """Args: - - message_listener: A MessageListener implementation. The - RepeatedScalarFieldContainer will call this object's Modified() method - when it is modified. - type_checker: A type_checkers.ValueChecker instance to run on elements - inserted into this container. - """ - super().__init__(message_listener) - self._type_checker = type_checker - - def append(self, value: _T) -> None: - """Appends an item to the list. Similar to list.append().""" - self._values.append(self._type_checker.CheckValue(value)) - if not self._message_listener.dirty: - self._message_listener.Modified() - - def insert(self, key: int, value: _T) -> None: - """Inserts the item at the specified position. Similar to list.insert().""" - self._values.insert(key, self._type_checker.CheckValue(value)) - if not self._message_listener.dirty: - self._message_listener.Modified() - - def extend(self, elem_seq: Iterable[_T]) -> None: - """Extends by appending the given iterable. Similar to list.extend().""" - if elem_seq is None: - return - try: - elem_seq_iter = iter(elem_seq) - except TypeError: - if not elem_seq: - # silently ignore falsy inputs :-/. - # TODO(ptucker): Deprecate this behavior. b/18413862 - return - raise - - new_values = [self._type_checker.CheckValue(elem) for elem in elem_seq_iter] - if new_values: - self._values.extend(new_values) - self._message_listener.Modified() - - def MergeFrom( - self, - other: Union['RepeatedScalarFieldContainer[_T]', Iterable[_T]], - ) -> None: - """Appends the contents of another repeated field of the same type to this - one. We do not check the types of the individual fields. - """ - self._values.extend(other) - self._message_listener.Modified() - - def remove(self, elem: _T): - """Removes an item from the list. Similar to list.remove().""" - self._values.remove(elem) - self._message_listener.Modified() - - def pop(self, key: Optional[int] = -1) -> _T: - """Removes and returns an item at a given index. Similar to list.pop().""" - value = self._values[key] - self.__delitem__(key) - return value - - @overload - def __setitem__(self, key: int, value: _T) -> None: - ... - - @overload - def __setitem__(self, key: slice, value: Iterable[_T]) -> None: - ... - - def __setitem__(self, key, value) -> None: - """Sets the item on the specified position.""" - if isinstance(key, slice): - if key.step is not None: - raise ValueError('Extended slices not supported') - self._values[key] = map(self._type_checker.CheckValue, value) - self._message_listener.Modified() - else: - self._values[key] = self._type_checker.CheckValue(value) - self._message_listener.Modified() - - def __delitem__(self, key: Union[int, slice]) -> None: - """Deletes the item at the specified position.""" - del self._values[key] - self._message_listener.Modified() - - def __eq__(self, other: Any) -> bool: - """Compares the current instance with another one.""" - if self is other: - return True - # Special case for the same type which should be common and fast. - if isinstance(other, self.__class__): - return other._values == self._values - # We are presumably comparing against some other sequence type. - return other == self._values - - def __deepcopy__( - self, - unused_memo: Any = None, - ) -> 'RepeatedScalarFieldContainer[_T]': - clone = RepeatedScalarFieldContainer( - copy.deepcopy(self._message_listener), self._type_checker) - clone.MergeFrom(self) - return clone - - def __reduce__(self, **kwargs) -> NoReturn: - raise pickle.PickleError( - "Can't pickle repeated scalar fields, convert to list first") - - -# TODO(slebedev): Constrain T to be a subtype of Message. -class RepeatedCompositeFieldContainer(BaseContainer[_T], MutableSequence[_T]): - """Simple, list-like container for holding repeated composite fields.""" - - # Disallows assignment to other attributes. - __slots__ = ['_message_descriptor'] - - def __init__(self, message_listener: Any, message_descriptor: Any) -> None: - """ - Note that we pass in a descriptor instead of the generated directly, - since at the time we construct a _RepeatedCompositeFieldContainer we - haven't yet necessarily initialized the type that will be contained in the - container. - - Args: - message_listener: A MessageListener implementation. - The RepeatedCompositeFieldContainer will call this object's - Modified() method when it is modified. - message_descriptor: A Descriptor instance describing the protocol type - that should be present in this container. We'll use the - _concrete_class field of this descriptor when the client calls add(). - """ - super().__init__(message_listener) - self._message_descriptor = message_descriptor - - def add(self, **kwargs: Any) -> _T: - """Adds a new element at the end of the list and returns it. Keyword - arguments may be used to initialize the element. - """ - new_element = self._message_descriptor._concrete_class(**kwargs) - new_element._SetListener(self._message_listener) - self._values.append(new_element) - if not self._message_listener.dirty: - self._message_listener.Modified() - return new_element - - def append(self, value: _T) -> None: - """Appends one element by copying the message.""" - new_element = self._message_descriptor._concrete_class() - new_element._SetListener(self._message_listener) - new_element.CopyFrom(value) - self._values.append(new_element) - if not self._message_listener.dirty: - self._message_listener.Modified() - - def insert(self, key: int, value: _T) -> None: - """Inserts the item at the specified position by copying.""" - new_element = self._message_descriptor._concrete_class() - new_element._SetListener(self._message_listener) - new_element.CopyFrom(value) - self._values.insert(key, new_element) - if not self._message_listener.dirty: - self._message_listener.Modified() - - def extend(self, elem_seq: Iterable[_T]) -> None: - """Extends by appending the given sequence of elements of the same type - - as this one, copying each individual message. - """ - message_class = self._message_descriptor._concrete_class - listener = self._message_listener - values = self._values - for message in elem_seq: - new_element = message_class() - new_element._SetListener(listener) - new_element.MergeFrom(message) - values.append(new_element) - listener.Modified() - - def MergeFrom( - self, - other: Union['RepeatedCompositeFieldContainer[_T]', Iterable[_T]], - ) -> None: - """Appends the contents of another repeated field of the same type to this - one, copying each individual message. - """ - self.extend(other) - - def remove(self, elem: _T) -> None: - """Removes an item from the list. Similar to list.remove().""" - self._values.remove(elem) - self._message_listener.Modified() - - def pop(self, key: Optional[int] = -1) -> _T: - """Removes and returns an item at a given index. Similar to list.pop().""" - value = self._values[key] - self.__delitem__(key) - return value - - @overload - def __setitem__(self, key: int, value: _T) -> None: - ... - - @overload - def __setitem__(self, key: slice, value: Iterable[_T]) -> None: - ... - - def __setitem__(self, key, value): - # This method is implemented to make RepeatedCompositeFieldContainer - # structurally compatible with typing.MutableSequence. It is - # otherwise unsupported and will always raise an error. - raise TypeError( - f'{self.__class__.__name__} object does not support item assignment') - - def __delitem__(self, key: Union[int, slice]) -> None: - """Deletes the item at the specified position.""" - del self._values[key] - self._message_listener.Modified() - - def __eq__(self, other: Any) -> bool: - """Compares the current instance with another one.""" - if self is other: - return True - if not isinstance(other, self.__class__): - raise TypeError('Can only compare repeated composite fields against ' - 'other repeated composite fields.') - return self._values == other._values - - -class ScalarMap(MutableMapping[_K, _V]): - """Simple, type-checked, dict-like container for holding repeated scalars.""" - - # Disallows assignment to other attributes. - __slots__ = ['_key_checker', '_value_checker', '_values', '_message_listener', - '_entry_descriptor'] - - def __init__( - self, - message_listener: Any, - key_checker: Any, - value_checker: Any, - entry_descriptor: Any, - ) -> None: - """ - Args: - message_listener: A MessageListener implementation. - The ScalarMap will call this object's Modified() method when it - is modified. - key_checker: A type_checkers.ValueChecker instance to run on keys - inserted into this container. - value_checker: A type_checkers.ValueChecker instance to run on values - inserted into this container. - entry_descriptor: The MessageDescriptor of a map entry: key and value. - """ - self._message_listener = message_listener - self._key_checker = key_checker - self._value_checker = value_checker - self._entry_descriptor = entry_descriptor - self._values = {} - - def __getitem__(self, key: _K) -> _V: - try: - return self._values[key] - except KeyError: - key = self._key_checker.CheckValue(key) - val = self._value_checker.DefaultValue() - self._values[key] = val - return val - - def __contains__(self, item: _K) -> bool: - # We check the key's type to match the strong-typing flavor of the API. - # Also this makes it easier to match the behavior of the C++ implementation. - self._key_checker.CheckValue(item) - return item in self._values - - @overload - def get(self, key: _K) -> Optional[_V]: - ... - - @overload - def get(self, key: _K, default: _T) -> Union[_V, _T]: - ... - - # We need to override this explicitly, because our defaultdict-like behavior - # will make the default implementation (from our base class) always insert - # the key. - def get(self, key, default=None): - if key in self: - return self[key] - else: - return default - - def __setitem__(self, key: _K, value: _V) -> _T: - checked_key = self._key_checker.CheckValue(key) - checked_value = self._value_checker.CheckValue(value) - self._values[checked_key] = checked_value - self._message_listener.Modified() - - def __delitem__(self, key: _K) -> None: - del self._values[key] - self._message_listener.Modified() - - def __len__(self) -> int: - return len(self._values) - - def __iter__(self) -> Iterator[_K]: - return iter(self._values) - - def __repr__(self) -> str: - return repr(self._values) - - def MergeFrom(self, other: 'ScalarMap[_K, _V]') -> None: - self._values.update(other._values) - self._message_listener.Modified() - - def InvalidateIterators(self) -> None: - # It appears that the only way to reliably invalidate iterators to - # self._values is to ensure that its size changes. - original = self._values - self._values = original.copy() - original[None] = None - - # This is defined in the abstract base, but we can do it much more cheaply. - def clear(self) -> None: - self._values.clear() - self._message_listener.Modified() - - def GetEntryClass(self) -> Any: - return self._entry_descriptor._concrete_class - - -class MessageMap(MutableMapping[_K, _V]): - """Simple, type-checked, dict-like container for with submessage values.""" - - # Disallows assignment to other attributes. - __slots__ = ['_key_checker', '_values', '_message_listener', - '_message_descriptor', '_entry_descriptor'] - - def __init__( - self, - message_listener: Any, - message_descriptor: Any, - key_checker: Any, - entry_descriptor: Any, - ) -> None: - """ - Args: - message_listener: A MessageListener implementation. - The ScalarMap will call this object's Modified() method when it - is modified. - key_checker: A type_checkers.ValueChecker instance to run on keys - inserted into this container. - value_checker: A type_checkers.ValueChecker instance to run on values - inserted into this container. - entry_descriptor: The MessageDescriptor of a map entry: key and value. - """ - self._message_listener = message_listener - self._message_descriptor = message_descriptor - self._key_checker = key_checker - self._entry_descriptor = entry_descriptor - self._values = {} - - def __getitem__(self, key: _K) -> _V: - key = self._key_checker.CheckValue(key) - try: - return self._values[key] - except KeyError: - new_element = self._message_descriptor._concrete_class() - new_element._SetListener(self._message_listener) - self._values[key] = new_element - self._message_listener.Modified() - return new_element - - def get_or_create(self, key: _K) -> _V: - """get_or_create() is an alias for getitem (ie. map[key]). - - Args: - key: The key to get or create in the map. - - This is useful in cases where you want to be explicit that the call is - mutating the map. This can avoid lint errors for statements like this - that otherwise would appear to be pointless statements: - - msg.my_map[key] - """ - return self[key] - - @overload - def get(self, key: _K) -> Optional[_V]: - ... - - @overload - def get(self, key: _K, default: _T) -> Union[_V, _T]: - ... - - # We need to override this explicitly, because our defaultdict-like behavior - # will make the default implementation (from our base class) always insert - # the key. - def get(self, key, default=None): - if key in self: - return self[key] - else: - return default - - def __contains__(self, item: _K) -> bool: - item = self._key_checker.CheckValue(item) - return item in self._values - - def __setitem__(self, key: _K, value: _V) -> NoReturn: - raise ValueError('May not set values directly, call my_map[key].foo = 5') - - def __delitem__(self, key: _K) -> None: - key = self._key_checker.CheckValue(key) - del self._values[key] - self._message_listener.Modified() - - def __len__(self) -> int: - return len(self._values) - - def __iter__(self) -> Iterator[_K]: - return iter(self._values) - - def __repr__(self) -> str: - return repr(self._values) - - def MergeFrom(self, other: 'MessageMap[_K, _V]') -> None: - # pylint: disable=protected-access - for key in other._values: - # According to documentation: "When parsing from the wire or when merging, - # if there are duplicate map keys the last key seen is used". - if key in self: - del self[key] - self[key].CopyFrom(other[key]) - # self._message_listener.Modified() not required here, because - # mutations to submessages already propagate. - - def InvalidateIterators(self) -> None: - # It appears that the only way to reliably invalidate iterators to - # self._values is to ensure that its size changes. - original = self._values - self._values = original.copy() - original[None] = None - - # This is defined in the abstract base, but we can do it much more cheaply. - def clear(self) -> None: - self._values.clear() - self._message_listener.Modified() - - def GetEntryClass(self) -> Any: - return self._entry_descriptor._concrete_class - - -class _UnknownField: - """A parsed unknown field.""" - - # Disallows assignment to other attributes. - __slots__ = ['_field_number', '_wire_type', '_data'] - - def __init__(self, field_number, wire_type, data): - self._field_number = field_number - self._wire_type = wire_type - self._data = data - return - - def __lt__(self, other): - # pylint: disable=protected-access - return self._field_number < other._field_number - - def __eq__(self, other): - if self is other: - return True - # pylint: disable=protected-access - return (self._field_number == other._field_number and - self._wire_type == other._wire_type and - self._data == other._data) - - -class UnknownFieldRef: # pylint: disable=missing-class-docstring - - def __init__(self, parent, index): - self._parent = parent - self._index = index - - def _check_valid(self): - if not self._parent: - raise ValueError('UnknownField does not exist. ' - 'The parent message might be cleared.') - if self._index >= len(self._parent): - raise ValueError('UnknownField does not exist. ' - 'The parent message might be cleared.') - - @property - def field_number(self): - self._check_valid() - # pylint: disable=protected-access - return self._parent._internal_get(self._index)._field_number - - @property - def wire_type(self): - self._check_valid() - # pylint: disable=protected-access - return self._parent._internal_get(self._index)._wire_type - - @property - def data(self): - self._check_valid() - # pylint: disable=protected-access - return self._parent._internal_get(self._index)._data - - -class UnknownFieldSet: - """UnknownField container""" - - # Disallows assignment to other attributes. - __slots__ = ['_values'] - - def __init__(self): - self._values = [] - - def __getitem__(self, index): - if self._values is None: - raise ValueError('UnknownFields does not exist. ' - 'The parent message might be cleared.') - size = len(self._values) - if index < 0: - index += size - if index < 0 or index >= size: - raise IndexError('index %d out of range'.index) - - return UnknownFieldRef(self, index) - - def _internal_get(self, index): - return self._values[index] - - def __len__(self): - if self._values is None: - raise ValueError('UnknownFields does not exist. ' - 'The parent message might be cleared.') - return len(self._values) - - def _add(self, field_number, wire_type, data): - unknown_field = _UnknownField(field_number, wire_type, data) - self._values.append(unknown_field) - return unknown_field - - def __iter__(self): - for i in range(len(self)): - yield UnknownFieldRef(self, i) - - def _extend(self, other): - if other is None: - return - # pylint: disable=protected-access - self._values.extend(other._values) - - def __eq__(self, other): - if self is other: - return True - # Sort unknown fields because their order shouldn't - # affect equality test. - values = list(self._values) - if other is None: - return not values - values.sort() - # pylint: disable=protected-access - other_values = sorted(other._values) - return values == other_values - - def _clear(self): - for value in self._values: - # pylint: disable=protected-access - if isinstance(value._data, UnknownFieldSet): - value._data._clear() # pylint: disable=protected-access - self._values = None diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/decoder.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/decoder.py deleted file mode 100644 index bc1b7b785c..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/decoder.py +++ /dev/null @@ -1,1029 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Code for decoding protocol buffer primitives. - -This code is very similar to encoder.py -- read the docs for that module first. - -A "decoder" is a function with the signature: - Decode(buffer, pos, end, message, field_dict) -The arguments are: - buffer: The string containing the encoded message. - pos: The current position in the string. - end: The position in the string where the current message ends. May be - less than len(buffer) if we're reading a sub-message. - message: The message object into which we're parsing. - field_dict: message._fields (avoids a hashtable lookup). -The decoder reads the field and stores it into field_dict, returning the new -buffer position. A decoder for a repeated field may proactively decode all of -the elements of that field, if they appear consecutively. - -Note that decoders may throw any of the following: - IndexError: Indicates a truncated message. - struct.error: Unpacking of a fixed-width field failed. - message.DecodeError: Other errors. - -Decoders are expected to raise an exception if they are called with pos > end. -This allows callers to be lax about bounds checking: it's fineto read past -"end" as long as you are sure that someone else will notice and throw an -exception later on. - -Something up the call stack is expected to catch IndexError and struct.error -and convert them to message.DecodeError. - -Decoders are constructed using decoder constructors with the signature: - MakeDecoder(field_number, is_repeated, is_packed, key, new_default) -The arguments are: - field_number: The field number of the field we want to decode. - is_repeated: Is the field a repeated field? (bool) - is_packed: Is the field a packed field? (bool) - key: The key to use when looking up the field within field_dict. - (This is actually the FieldDescriptor but nothing in this - file should depend on that.) - new_default: A function which takes a message object as a parameter and - returns a new instance of the default value for this field. - (This is called for repeated fields and sub-messages, when an - instance does not already exist.) - -As with encoders, we define a decoder constructor for every type of field. -Then, for every field of every message class we construct an actual decoder. -That decoder goes into a dict indexed by tag, so when we decode a message -we repeatedly read a tag, look up the corresponding decoder, and invoke it. -""" - -__author__ = 'kenton@google.com (Kenton Varda)' - -import math -import struct - -from google.protobuf.internal import containers -from google.protobuf.internal import encoder -from google.protobuf.internal import wire_format -from google.protobuf import message - - -# This is not for optimization, but rather to avoid conflicts with local -# variables named "message". -_DecodeError = message.DecodeError - - -def _VarintDecoder(mask, result_type): - """Return an encoder for a basic varint value (does not include tag). - - Decoded values will be bitwise-anded with the given mask before being - returned, e.g. to limit them to 32 bits. The returned decoder does not - take the usual "end" parameter -- the caller is expected to do bounds checking - after the fact (often the caller can defer such checking until later). The - decoder returns a (value, new_pos) pair. - """ - - def DecodeVarint(buffer, pos): - result = 0 - shift = 0 - while 1: - b = buffer[pos] - result |= ((b & 0x7f) << shift) - pos += 1 - if not (b & 0x80): - result &= mask - result = result_type(result) - return (result, pos) - shift += 7 - if shift >= 64: - raise _DecodeError('Too many bytes when decoding varint.') - return DecodeVarint - - -def _SignedVarintDecoder(bits, result_type): - """Like _VarintDecoder() but decodes signed values.""" - - signbit = 1 << (bits - 1) - mask = (1 << bits) - 1 - - def DecodeVarint(buffer, pos): - result = 0 - shift = 0 - while 1: - b = buffer[pos] - result |= ((b & 0x7f) << shift) - pos += 1 - if not (b & 0x80): - result &= mask - result = (result ^ signbit) - signbit - result = result_type(result) - return (result, pos) - shift += 7 - if shift >= 64: - raise _DecodeError('Too many bytes when decoding varint.') - return DecodeVarint - -# All 32-bit and 64-bit values are represented as int. -_DecodeVarint = _VarintDecoder((1 << 64) - 1, int) -_DecodeSignedVarint = _SignedVarintDecoder(64, int) - -# Use these versions for values which must be limited to 32 bits. -_DecodeVarint32 = _VarintDecoder((1 << 32) - 1, int) -_DecodeSignedVarint32 = _SignedVarintDecoder(32, int) - - -def ReadTag(buffer, pos): - """Read a tag from the memoryview, and return a (tag_bytes, new_pos) tuple. - - We return the raw bytes of the tag rather than decoding them. The raw - bytes can then be used to look up the proper decoder. This effectively allows - us to trade some work that would be done in pure-python (decoding a varint) - for work that is done in C (searching for a byte string in a hash table). - In a low-level language it would be much cheaper to decode the varint and - use that, but not in Python. - - Args: - buffer: memoryview object of the encoded bytes - pos: int of the current position to start from - - Returns: - Tuple[bytes, int] of the tag data and new position. - """ - start = pos - while buffer[pos] & 0x80: - pos += 1 - pos += 1 - - tag_bytes = buffer[start:pos].tobytes() - return tag_bytes, pos - - -# -------------------------------------------------------------------- - - -def _SimpleDecoder(wire_type, decode_value): - """Return a constructor for a decoder for fields of a particular type. - - Args: - wire_type: The field's wire type. - decode_value: A function which decodes an individual value, e.g. - _DecodeVarint() - """ - - def SpecificDecoder(field_number, is_repeated, is_packed, key, new_default, - clear_if_default=False): - if is_packed: - local_DecodeVarint = _DecodeVarint - def DecodePackedField(buffer, pos, end, message, field_dict): - value = field_dict.get(key) - if value is None: - value = field_dict.setdefault(key, new_default(message)) - (endpoint, pos) = local_DecodeVarint(buffer, pos) - endpoint += pos - if endpoint > end: - raise _DecodeError('Truncated message.') - while pos < endpoint: - (element, pos) = decode_value(buffer, pos) - value.append(element) - if pos > endpoint: - del value[-1] # Discard corrupt value. - raise _DecodeError('Packed element was truncated.') - return pos - return DecodePackedField - elif is_repeated: - tag_bytes = encoder.TagBytes(field_number, wire_type) - tag_len = len(tag_bytes) - def DecodeRepeatedField(buffer, pos, end, message, field_dict): - value = field_dict.get(key) - if value is None: - value = field_dict.setdefault(key, new_default(message)) - while 1: - (element, new_pos) = decode_value(buffer, pos) - value.append(element) - # Predict that the next tag is another copy of the same repeated - # field. - pos = new_pos + tag_len - if buffer[new_pos:pos] != tag_bytes or new_pos >= end: - # Prediction failed. Return. - if new_pos > end: - raise _DecodeError('Truncated message.') - return new_pos - return DecodeRepeatedField - else: - def DecodeField(buffer, pos, end, message, field_dict): - (new_value, pos) = decode_value(buffer, pos) - if pos > end: - raise _DecodeError('Truncated message.') - if clear_if_default and not new_value: - field_dict.pop(key, None) - else: - field_dict[key] = new_value - return pos - return DecodeField - - return SpecificDecoder - - -def _ModifiedDecoder(wire_type, decode_value, modify_value): - """Like SimpleDecoder but additionally invokes modify_value on every value - before storing it. Usually modify_value is ZigZagDecode. - """ - - # Reusing _SimpleDecoder is slightly slower than copying a bunch of code, but - # not enough to make a significant difference. - - def InnerDecode(buffer, pos): - (result, new_pos) = decode_value(buffer, pos) - return (modify_value(result), new_pos) - return _SimpleDecoder(wire_type, InnerDecode) - - -def _StructPackDecoder(wire_type, format): - """Return a constructor for a decoder for a fixed-width field. - - Args: - wire_type: The field's wire type. - format: The format string to pass to struct.unpack(). - """ - - value_size = struct.calcsize(format) - local_unpack = struct.unpack - - # Reusing _SimpleDecoder is slightly slower than copying a bunch of code, but - # not enough to make a significant difference. - - # Note that we expect someone up-stack to catch struct.error and convert - # it to _DecodeError -- this way we don't have to set up exception- - # handling blocks every time we parse one value. - - def InnerDecode(buffer, pos): - new_pos = pos + value_size - result = local_unpack(format, buffer[pos:new_pos])[0] - return (result, new_pos) - return _SimpleDecoder(wire_type, InnerDecode) - - -def _FloatDecoder(): - """Returns a decoder for a float field. - - This code works around a bug in struct.unpack for non-finite 32-bit - floating-point values. - """ - - local_unpack = struct.unpack - - def InnerDecode(buffer, pos): - """Decode serialized float to a float and new position. - - Args: - buffer: memoryview of the serialized bytes - pos: int, position in the memory view to start at. - - Returns: - Tuple[float, int] of the deserialized float value and new position - in the serialized data. - """ - # We expect a 32-bit value in little-endian byte order. Bit 1 is the sign - # bit, bits 2-9 represent the exponent, and bits 10-32 are the significand. - new_pos = pos + 4 - float_bytes = buffer[pos:new_pos].tobytes() - - # If this value has all its exponent bits set, then it's non-finite. - # In Python 2.4, struct.unpack will convert it to a finite 64-bit value. - # To avoid that, we parse it specially. - if (float_bytes[3:4] in b'\x7F\xFF' and float_bytes[2:3] >= b'\x80'): - # If at least one significand bit is set... - if float_bytes[0:3] != b'\x00\x00\x80': - return (math.nan, new_pos) - # If sign bit is set... - if float_bytes[3:4] == b'\xFF': - return (-math.inf, new_pos) - return (math.inf, new_pos) - - # Note that we expect someone up-stack to catch struct.error and convert - # it to _DecodeError -- this way we don't have to set up exception- - # handling blocks every time we parse one value. - result = local_unpack('= b'\xF0') - and (double_bytes[0:7] != b'\x00\x00\x00\x00\x00\x00\xF0')): - return (math.nan, new_pos) - - # Note that we expect someone up-stack to catch struct.error and convert - # it to _DecodeError -- this way we don't have to set up exception- - # handling blocks every time we parse one value. - result = local_unpack(' end: - raise _DecodeError('Truncated message.') - while pos < endpoint: - value_start_pos = pos - (element, pos) = _DecodeSignedVarint32(buffer, pos) - # pylint: disable=protected-access - if element in enum_type.values_by_number: - value.append(element) - else: - if not message._unknown_fields: - message._unknown_fields = [] - tag_bytes = encoder.TagBytes(field_number, - wire_format.WIRETYPE_VARINT) - - message._unknown_fields.append( - (tag_bytes, buffer[value_start_pos:pos].tobytes())) - if message._unknown_field_set is None: - message._unknown_field_set = containers.UnknownFieldSet() - message._unknown_field_set._add( - field_number, wire_format.WIRETYPE_VARINT, element) - # pylint: enable=protected-access - if pos > endpoint: - if element in enum_type.values_by_number: - del value[-1] # Discard corrupt value. - else: - del message._unknown_fields[-1] - # pylint: disable=protected-access - del message._unknown_field_set._values[-1] - # pylint: enable=protected-access - raise _DecodeError('Packed element was truncated.') - return pos - return DecodePackedField - elif is_repeated: - tag_bytes = encoder.TagBytes(field_number, wire_format.WIRETYPE_VARINT) - tag_len = len(tag_bytes) - def DecodeRepeatedField(buffer, pos, end, message, field_dict): - """Decode serialized repeated enum to its value and a new position. - - Args: - buffer: memoryview of the serialized bytes. - pos: int, position in the memory view to start at. - end: int, end position of serialized data - message: Message object to store unknown fields in - field_dict: Map[Descriptor, Any] to store decoded values in. - - Returns: - int, new position in serialized data. - """ - value = field_dict.get(key) - if value is None: - value = field_dict.setdefault(key, new_default(message)) - while 1: - (element, new_pos) = _DecodeSignedVarint32(buffer, pos) - # pylint: disable=protected-access - if element in enum_type.values_by_number: - value.append(element) - else: - if not message._unknown_fields: - message._unknown_fields = [] - message._unknown_fields.append( - (tag_bytes, buffer[pos:new_pos].tobytes())) - if message._unknown_field_set is None: - message._unknown_field_set = containers.UnknownFieldSet() - message._unknown_field_set._add( - field_number, wire_format.WIRETYPE_VARINT, element) - # pylint: enable=protected-access - # Predict that the next tag is another copy of the same repeated - # field. - pos = new_pos + tag_len - if buffer[new_pos:pos] != tag_bytes or new_pos >= end: - # Prediction failed. Return. - if new_pos > end: - raise _DecodeError('Truncated message.') - return new_pos - return DecodeRepeatedField - else: - def DecodeField(buffer, pos, end, message, field_dict): - """Decode serialized repeated enum to its value and a new position. - - Args: - buffer: memoryview of the serialized bytes. - pos: int, position in the memory view to start at. - end: int, end position of serialized data - message: Message object to store unknown fields in - field_dict: Map[Descriptor, Any] to store decoded values in. - - Returns: - int, new position in serialized data. - """ - value_start_pos = pos - (enum_value, pos) = _DecodeSignedVarint32(buffer, pos) - if pos > end: - raise _DecodeError('Truncated message.') - if clear_if_default and not enum_value: - field_dict.pop(key, None) - return pos - # pylint: disable=protected-access - if enum_value in enum_type.values_by_number: - field_dict[key] = enum_value - else: - if not message._unknown_fields: - message._unknown_fields = [] - tag_bytes = encoder.TagBytes(field_number, - wire_format.WIRETYPE_VARINT) - message._unknown_fields.append( - (tag_bytes, buffer[value_start_pos:pos].tobytes())) - if message._unknown_field_set is None: - message._unknown_field_set = containers.UnknownFieldSet() - message._unknown_field_set._add( - field_number, wire_format.WIRETYPE_VARINT, enum_value) - # pylint: enable=protected-access - return pos - return DecodeField - - -# -------------------------------------------------------------------- - - -Int32Decoder = _SimpleDecoder( - wire_format.WIRETYPE_VARINT, _DecodeSignedVarint32) - -Int64Decoder = _SimpleDecoder( - wire_format.WIRETYPE_VARINT, _DecodeSignedVarint) - -UInt32Decoder = _SimpleDecoder(wire_format.WIRETYPE_VARINT, _DecodeVarint32) -UInt64Decoder = _SimpleDecoder(wire_format.WIRETYPE_VARINT, _DecodeVarint) - -SInt32Decoder = _ModifiedDecoder( - wire_format.WIRETYPE_VARINT, _DecodeVarint32, wire_format.ZigZagDecode) -SInt64Decoder = _ModifiedDecoder( - wire_format.WIRETYPE_VARINT, _DecodeVarint, wire_format.ZigZagDecode) - -# Note that Python conveniently guarantees that when using the '<' prefix on -# formats, they will also have the same size across all platforms (as opposed -# to without the prefix, where their sizes depend on the C compiler's basic -# type sizes). -Fixed32Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED32, ' end: - raise _DecodeError('Truncated string.') - value.append(_ConvertToUnicode(buffer[pos:new_pos])) - # Predict that the next tag is another copy of the same repeated field. - pos = new_pos + tag_len - if buffer[new_pos:pos] != tag_bytes or new_pos == end: - # Prediction failed. Return. - return new_pos - return DecodeRepeatedField - else: - def DecodeField(buffer, pos, end, message, field_dict): - (size, pos) = local_DecodeVarint(buffer, pos) - new_pos = pos + size - if new_pos > end: - raise _DecodeError('Truncated string.') - if clear_if_default and not size: - field_dict.pop(key, None) - else: - field_dict[key] = _ConvertToUnicode(buffer[pos:new_pos]) - return new_pos - return DecodeField - - -def BytesDecoder(field_number, is_repeated, is_packed, key, new_default, - clear_if_default=False): - """Returns a decoder for a bytes field.""" - - local_DecodeVarint = _DecodeVarint - - assert not is_packed - if is_repeated: - tag_bytes = encoder.TagBytes(field_number, - wire_format.WIRETYPE_LENGTH_DELIMITED) - tag_len = len(tag_bytes) - def DecodeRepeatedField(buffer, pos, end, message, field_dict): - value = field_dict.get(key) - if value is None: - value = field_dict.setdefault(key, new_default(message)) - while 1: - (size, pos) = local_DecodeVarint(buffer, pos) - new_pos = pos + size - if new_pos > end: - raise _DecodeError('Truncated string.') - value.append(buffer[pos:new_pos].tobytes()) - # Predict that the next tag is another copy of the same repeated field. - pos = new_pos + tag_len - if buffer[new_pos:pos] != tag_bytes or new_pos == end: - # Prediction failed. Return. - return new_pos - return DecodeRepeatedField - else: - def DecodeField(buffer, pos, end, message, field_dict): - (size, pos) = local_DecodeVarint(buffer, pos) - new_pos = pos + size - if new_pos > end: - raise _DecodeError('Truncated string.') - if clear_if_default and not size: - field_dict.pop(key, None) - else: - field_dict[key] = buffer[pos:new_pos].tobytes() - return new_pos - return DecodeField - - -def GroupDecoder(field_number, is_repeated, is_packed, key, new_default): - """Returns a decoder for a group field.""" - - end_tag_bytes = encoder.TagBytes(field_number, - wire_format.WIRETYPE_END_GROUP) - end_tag_len = len(end_tag_bytes) - - assert not is_packed - if is_repeated: - tag_bytes = encoder.TagBytes(field_number, - wire_format.WIRETYPE_START_GROUP) - tag_len = len(tag_bytes) - def DecodeRepeatedField(buffer, pos, end, message, field_dict): - value = field_dict.get(key) - if value is None: - value = field_dict.setdefault(key, new_default(message)) - while 1: - value = field_dict.get(key) - if value is None: - value = field_dict.setdefault(key, new_default(message)) - # Read sub-message. - pos = value.add()._InternalParse(buffer, pos, end) - # Read end tag. - new_pos = pos+end_tag_len - if buffer[pos:new_pos] != end_tag_bytes or new_pos > end: - raise _DecodeError('Missing group end tag.') - # Predict that the next tag is another copy of the same repeated field. - pos = new_pos + tag_len - if buffer[new_pos:pos] != tag_bytes or new_pos == end: - # Prediction failed. Return. - return new_pos - return DecodeRepeatedField - else: - def DecodeField(buffer, pos, end, message, field_dict): - value = field_dict.get(key) - if value is None: - value = field_dict.setdefault(key, new_default(message)) - # Read sub-message. - pos = value._InternalParse(buffer, pos, end) - # Read end tag. - new_pos = pos+end_tag_len - if buffer[pos:new_pos] != end_tag_bytes or new_pos > end: - raise _DecodeError('Missing group end tag.') - return new_pos - return DecodeField - - -def MessageDecoder(field_number, is_repeated, is_packed, key, new_default): - """Returns a decoder for a message field.""" - - local_DecodeVarint = _DecodeVarint - - assert not is_packed - if is_repeated: - tag_bytes = encoder.TagBytes(field_number, - wire_format.WIRETYPE_LENGTH_DELIMITED) - tag_len = len(tag_bytes) - def DecodeRepeatedField(buffer, pos, end, message, field_dict): - value = field_dict.get(key) - if value is None: - value = field_dict.setdefault(key, new_default(message)) - while 1: - # Read length. - (size, pos) = local_DecodeVarint(buffer, pos) - new_pos = pos + size - if new_pos > end: - raise _DecodeError('Truncated message.') - # Read sub-message. - if value.add()._InternalParse(buffer, pos, new_pos) != new_pos: - # The only reason _InternalParse would return early is if it - # encountered an end-group tag. - raise _DecodeError('Unexpected end-group tag.') - # Predict that the next tag is another copy of the same repeated field. - pos = new_pos + tag_len - if buffer[new_pos:pos] != tag_bytes or new_pos == end: - # Prediction failed. Return. - return new_pos - return DecodeRepeatedField - else: - def DecodeField(buffer, pos, end, message, field_dict): - value = field_dict.get(key) - if value is None: - value = field_dict.setdefault(key, new_default(message)) - # Read length. - (size, pos) = local_DecodeVarint(buffer, pos) - new_pos = pos + size - if new_pos > end: - raise _DecodeError('Truncated message.') - # Read sub-message. - if value._InternalParse(buffer, pos, new_pos) != new_pos: - # The only reason _InternalParse would return early is if it encountered - # an end-group tag. - raise _DecodeError('Unexpected end-group tag.') - return new_pos - return DecodeField - - -# -------------------------------------------------------------------- - -MESSAGE_SET_ITEM_TAG = encoder.TagBytes(1, wire_format.WIRETYPE_START_GROUP) - -def MessageSetItemDecoder(descriptor): - """Returns a decoder for a MessageSet item. - - The parameter is the message Descriptor. - - The message set message looks like this: - message MessageSet { - repeated group Item = 1 { - required int32 type_id = 2; - required string message = 3; - } - } - """ - - type_id_tag_bytes = encoder.TagBytes(2, wire_format.WIRETYPE_VARINT) - message_tag_bytes = encoder.TagBytes(3, wire_format.WIRETYPE_LENGTH_DELIMITED) - item_end_tag_bytes = encoder.TagBytes(1, wire_format.WIRETYPE_END_GROUP) - - local_ReadTag = ReadTag - local_DecodeVarint = _DecodeVarint - local_SkipField = SkipField - - def DecodeItem(buffer, pos, end, message, field_dict): - """Decode serialized message set to its value and new position. - - Args: - buffer: memoryview of the serialized bytes. - pos: int, position in the memory view to start at. - end: int, end position of serialized data - message: Message object to store unknown fields in - field_dict: Map[Descriptor, Any] to store decoded values in. - - Returns: - int, new position in serialized data. - """ - message_set_item_start = pos - type_id = -1 - message_start = -1 - message_end = -1 - - # Technically, type_id and message can appear in any order, so we need - # a little loop here. - while 1: - (tag_bytes, pos) = local_ReadTag(buffer, pos) - if tag_bytes == type_id_tag_bytes: - (type_id, pos) = local_DecodeVarint(buffer, pos) - elif tag_bytes == message_tag_bytes: - (size, message_start) = local_DecodeVarint(buffer, pos) - pos = message_end = message_start + size - elif tag_bytes == item_end_tag_bytes: - break - else: - pos = SkipField(buffer, pos, end, tag_bytes) - if pos == -1: - raise _DecodeError('Missing group end tag.') - - if pos > end: - raise _DecodeError('Truncated message.') - - if type_id == -1: - raise _DecodeError('MessageSet item missing type_id.') - if message_start == -1: - raise _DecodeError('MessageSet item missing message.') - - extension = message.Extensions._FindExtensionByNumber(type_id) - # pylint: disable=protected-access - if extension is not None: - value = field_dict.get(extension) - if value is None: - message_type = extension.message_type - if not hasattr(message_type, '_concrete_class'): - # pylint: disable=protected-access - message._FACTORY.GetPrototype(message_type) - value = field_dict.setdefault( - extension, message_type._concrete_class()) - if value._InternalParse(buffer, message_start,message_end) != message_end: - # The only reason _InternalParse would return early is if it encountered - # an end-group tag. - raise _DecodeError('Unexpected end-group tag.') - else: - if not message._unknown_fields: - message._unknown_fields = [] - message._unknown_fields.append( - (MESSAGE_SET_ITEM_TAG, buffer[message_set_item_start:pos].tobytes())) - if message._unknown_field_set is None: - message._unknown_field_set = containers.UnknownFieldSet() - message._unknown_field_set._add( - type_id, - wire_format.WIRETYPE_LENGTH_DELIMITED, - buffer[message_start:message_end].tobytes()) - # pylint: enable=protected-access - - return pos - - return DecodeItem - -# -------------------------------------------------------------------- - -def MapDecoder(field_descriptor, new_default, is_message_map): - """Returns a decoder for a map field.""" - - key = field_descriptor - tag_bytes = encoder.TagBytes(field_descriptor.number, - wire_format.WIRETYPE_LENGTH_DELIMITED) - tag_len = len(tag_bytes) - local_DecodeVarint = _DecodeVarint - # Can't read _concrete_class yet; might not be initialized. - message_type = field_descriptor.message_type - - def DecodeMap(buffer, pos, end, message, field_dict): - submsg = message_type._concrete_class() - value = field_dict.get(key) - if value is None: - value = field_dict.setdefault(key, new_default(message)) - while 1: - # Read length. - (size, pos) = local_DecodeVarint(buffer, pos) - new_pos = pos + size - if new_pos > end: - raise _DecodeError('Truncated message.') - # Read sub-message. - submsg.Clear() - if submsg._InternalParse(buffer, pos, new_pos) != new_pos: - # The only reason _InternalParse would return early is if it - # encountered an end-group tag. - raise _DecodeError('Unexpected end-group tag.') - - if is_message_map: - value[submsg.key].CopyFrom(submsg.value) - else: - value[submsg.key] = submsg.value - - # Predict that the next tag is another copy of the same repeated field. - pos = new_pos + tag_len - if buffer[new_pos:pos] != tag_bytes or new_pos == end: - # Prediction failed. Return. - return new_pos - - return DecodeMap - -# -------------------------------------------------------------------- -# Optimization is not as heavy here because calls to SkipField() are rare, -# except for handling end-group tags. - -def _SkipVarint(buffer, pos, end): - """Skip a varint value. Returns the new position.""" - # Previously ord(buffer[pos]) raised IndexError when pos is out of range. - # With this code, ord(b'') raises TypeError. Both are handled in - # python_message.py to generate a 'Truncated message' error. - while ord(buffer[pos:pos+1].tobytes()) & 0x80: - pos += 1 - pos += 1 - if pos > end: - raise _DecodeError('Truncated message.') - return pos - -def _SkipFixed64(buffer, pos, end): - """Skip a fixed64 value. Returns the new position.""" - - pos += 8 - if pos > end: - raise _DecodeError('Truncated message.') - return pos - - -def _DecodeFixed64(buffer, pos): - """Decode a fixed64.""" - new_pos = pos + 8 - return (struct.unpack(' end: - raise _DecodeError('Truncated message.') - return pos - - -def _SkipGroup(buffer, pos, end): - """Skip sub-group. Returns the new position.""" - - while 1: - (tag_bytes, pos) = ReadTag(buffer, pos) - new_pos = SkipField(buffer, pos, end, tag_bytes) - if new_pos == -1: - return pos - pos = new_pos - - -def _DecodeUnknownFieldSet(buffer, pos, end_pos=None): - """Decode UnknownFieldSet. Returns the UnknownFieldSet and new position.""" - - unknown_field_set = containers.UnknownFieldSet() - while end_pos is None or pos < end_pos: - (tag_bytes, pos) = ReadTag(buffer, pos) - (tag, _) = _DecodeVarint(tag_bytes, 0) - field_number, wire_type = wire_format.UnpackTag(tag) - if wire_type == wire_format.WIRETYPE_END_GROUP: - break - (data, pos) = _DecodeUnknownField(buffer, pos, wire_type) - # pylint: disable=protected-access - unknown_field_set._add(field_number, wire_type, data) - - return (unknown_field_set, pos) - - -def _DecodeUnknownField(buffer, pos, wire_type): - """Decode a unknown field. Returns the UnknownField and new position.""" - - if wire_type == wire_format.WIRETYPE_VARINT: - (data, pos) = _DecodeVarint(buffer, pos) - elif wire_type == wire_format.WIRETYPE_FIXED64: - (data, pos) = _DecodeFixed64(buffer, pos) - elif wire_type == wire_format.WIRETYPE_FIXED32: - (data, pos) = _DecodeFixed32(buffer, pos) - elif wire_type == wire_format.WIRETYPE_LENGTH_DELIMITED: - (size, pos) = _DecodeVarint(buffer, pos) - data = buffer[pos:pos+size].tobytes() - pos += size - elif wire_type == wire_format.WIRETYPE_START_GROUP: - (data, pos) = _DecodeUnknownFieldSet(buffer, pos) - elif wire_type == wire_format.WIRETYPE_END_GROUP: - return (0, -1) - else: - raise _DecodeError('Wrong wire type in tag.') - - return (data, pos) - - -def _EndGroup(buffer, pos, end): - """Skipping an END_GROUP tag returns -1 to tell the parent loop to break.""" - - return -1 - - -def _SkipFixed32(buffer, pos, end): - """Skip a fixed32 value. Returns the new position.""" - - pos += 4 - if pos > end: - raise _DecodeError('Truncated message.') - return pos - - -def _DecodeFixed32(buffer, pos): - """Decode a fixed32.""" - - new_pos = pos + 4 - return (struct.unpack('B').pack - - def EncodeVarint(write, value, unused_deterministic=None): - bits = value & 0x7f - value >>= 7 - while value: - write(local_int2byte(0x80|bits)) - bits = value & 0x7f - value >>= 7 - return write(local_int2byte(bits)) - - return EncodeVarint - - -def _SignedVarintEncoder(): - """Return an encoder for a basic signed varint value (does not include - tag).""" - - local_int2byte = struct.Struct('>B').pack - - def EncodeSignedVarint(write, value, unused_deterministic=None): - if value < 0: - value += (1 << 64) - bits = value & 0x7f - value >>= 7 - while value: - write(local_int2byte(0x80|bits)) - bits = value & 0x7f - value >>= 7 - return write(local_int2byte(bits)) - - return EncodeSignedVarint - - -_EncodeVarint = _VarintEncoder() -_EncodeSignedVarint = _SignedVarintEncoder() - - -def _VarintBytes(value): - """Encode the given integer as a varint and return the bytes. This is only - called at startup time so it doesn't need to be fast.""" - - pieces = [] - _EncodeVarint(pieces.append, value, True) - return b"".join(pieces) - - -def TagBytes(field_number, wire_type): - """Encode the given tag and return the bytes. Only called at startup.""" - - return bytes(_VarintBytes(wire_format.PackTag(field_number, wire_type))) - -# -------------------------------------------------------------------- -# As with sizers (see above), we have a number of common encoder -# implementations. - - -def _SimpleEncoder(wire_type, encode_value, compute_value_size): - """Return a constructor for an encoder for fields of a particular type. - - Args: - wire_type: The field's wire type, for encoding tags. - encode_value: A function which encodes an individual value, e.g. - _EncodeVarint(). - compute_value_size: A function which computes the size of an individual - value, e.g. _VarintSize(). - """ - - def SpecificEncoder(field_number, is_repeated, is_packed): - if is_packed: - tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) - local_EncodeVarint = _EncodeVarint - def EncodePackedField(write, value, deterministic): - write(tag_bytes) - size = 0 - for element in value: - size += compute_value_size(element) - local_EncodeVarint(write, size, deterministic) - for element in value: - encode_value(write, element, deterministic) - return EncodePackedField - elif is_repeated: - tag_bytes = TagBytes(field_number, wire_type) - def EncodeRepeatedField(write, value, deterministic): - for element in value: - write(tag_bytes) - encode_value(write, element, deterministic) - return EncodeRepeatedField - else: - tag_bytes = TagBytes(field_number, wire_type) - def EncodeField(write, value, deterministic): - write(tag_bytes) - return encode_value(write, value, deterministic) - return EncodeField - - return SpecificEncoder - - -def _ModifiedEncoder(wire_type, encode_value, compute_value_size, modify_value): - """Like SimpleEncoder but additionally invokes modify_value on every value - before passing it to encode_value. Usually modify_value is ZigZagEncode.""" - - def SpecificEncoder(field_number, is_repeated, is_packed): - if is_packed: - tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) - local_EncodeVarint = _EncodeVarint - def EncodePackedField(write, value, deterministic): - write(tag_bytes) - size = 0 - for element in value: - size += compute_value_size(modify_value(element)) - local_EncodeVarint(write, size, deterministic) - for element in value: - encode_value(write, modify_value(element), deterministic) - return EncodePackedField - elif is_repeated: - tag_bytes = TagBytes(field_number, wire_type) - def EncodeRepeatedField(write, value, deterministic): - for element in value: - write(tag_bytes) - encode_value(write, modify_value(element), deterministic) - return EncodeRepeatedField - else: - tag_bytes = TagBytes(field_number, wire_type) - def EncodeField(write, value, deterministic): - write(tag_bytes) - return encode_value(write, modify_value(value), deterministic) - return EncodeField - - return SpecificEncoder - - -def _StructPackEncoder(wire_type, format): - """Return a constructor for an encoder for a fixed-width field. - - Args: - wire_type: The field's wire type, for encoding tags. - format: The format string to pass to struct.pack(). - """ - - value_size = struct.calcsize(format) - - def SpecificEncoder(field_number, is_repeated, is_packed): - local_struct_pack = struct.pack - if is_packed: - tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) - local_EncodeVarint = _EncodeVarint - def EncodePackedField(write, value, deterministic): - write(tag_bytes) - local_EncodeVarint(write, len(value) * value_size, deterministic) - for element in value: - write(local_struct_pack(format, element)) - return EncodePackedField - elif is_repeated: - tag_bytes = TagBytes(field_number, wire_type) - def EncodeRepeatedField(write, value, unused_deterministic=None): - for element in value: - write(tag_bytes) - write(local_struct_pack(format, element)) - return EncodeRepeatedField - else: - tag_bytes = TagBytes(field_number, wire_type) - def EncodeField(write, value, unused_deterministic=None): - write(tag_bytes) - return write(local_struct_pack(format, value)) - return EncodeField - - return SpecificEncoder - - -def _FloatingPointEncoder(wire_type, format): - """Return a constructor for an encoder for float fields. - - This is like StructPackEncoder, but catches errors that may be due to - passing non-finite floating-point values to struct.pack, and makes a - second attempt to encode those values. - - Args: - wire_type: The field's wire type, for encoding tags. - format: The format string to pass to struct.pack(). - """ - - value_size = struct.calcsize(format) - if value_size == 4: - def EncodeNonFiniteOrRaise(write, value): - # Remember that the serialized form uses little-endian byte order. - if value == _POS_INF: - write(b'\x00\x00\x80\x7F') - elif value == _NEG_INF: - write(b'\x00\x00\x80\xFF') - elif value != value: # NaN - write(b'\x00\x00\xC0\x7F') - else: - raise - elif value_size == 8: - def EncodeNonFiniteOrRaise(write, value): - if value == _POS_INF: - write(b'\x00\x00\x00\x00\x00\x00\xF0\x7F') - elif value == _NEG_INF: - write(b'\x00\x00\x00\x00\x00\x00\xF0\xFF') - elif value != value: # NaN - write(b'\x00\x00\x00\x00\x00\x00\xF8\x7F') - else: - raise - else: - raise ValueError('Can\'t encode floating-point values that are ' - '%d bytes long (only 4 or 8)' % value_size) - - def SpecificEncoder(field_number, is_repeated, is_packed): - local_struct_pack = struct.pack - if is_packed: - tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) - local_EncodeVarint = _EncodeVarint - def EncodePackedField(write, value, deterministic): - write(tag_bytes) - local_EncodeVarint(write, len(value) * value_size, deterministic) - for element in value: - # This try/except block is going to be faster than any code that - # we could write to check whether element is finite. - try: - write(local_struct_pack(format, element)) - except SystemError: - EncodeNonFiniteOrRaise(write, element) - return EncodePackedField - elif is_repeated: - tag_bytes = TagBytes(field_number, wire_type) - def EncodeRepeatedField(write, value, unused_deterministic=None): - for element in value: - write(tag_bytes) - try: - write(local_struct_pack(format, element)) - except SystemError: - EncodeNonFiniteOrRaise(write, element) - return EncodeRepeatedField - else: - tag_bytes = TagBytes(field_number, wire_type) - def EncodeField(write, value, unused_deterministic=None): - write(tag_bytes) - try: - write(local_struct_pack(format, value)) - except SystemError: - EncodeNonFiniteOrRaise(write, value) - return EncodeField - - return SpecificEncoder - - -# ==================================================================== -# Here we declare an encoder constructor for each field type. These work -# very similarly to sizer constructors, described earlier. - - -Int32Encoder = Int64Encoder = EnumEncoder = _SimpleEncoder( - wire_format.WIRETYPE_VARINT, _EncodeSignedVarint, _SignedVarintSize) - -UInt32Encoder = UInt64Encoder = _SimpleEncoder( - wire_format.WIRETYPE_VARINT, _EncodeVarint, _VarintSize) - -SInt32Encoder = SInt64Encoder = _ModifiedEncoder( - wire_format.WIRETYPE_VARINT, _EncodeVarint, _VarintSize, - wire_format.ZigZagEncode) - -# Note that Python conveniently guarantees that when using the '<' prefix on -# formats, they will also have the same size across all platforms (as opposed -# to without the prefix, where their sizes depend on the C compiler's basic -# type sizes). -Fixed32Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, ' str - ValueType = int - - def __init__(self, enum_type): - """Inits EnumTypeWrapper with an EnumDescriptor.""" - self._enum_type = enum_type - self.DESCRIPTOR = enum_type # pylint: disable=invalid-name - - def Name(self, number): # pylint: disable=invalid-name - """Returns a string containing the name of an enum value.""" - try: - return self._enum_type.values_by_number[number].name - except KeyError: - pass # fall out to break exception chaining - - if not isinstance(number, int): - raise TypeError( - 'Enum value for {} must be an int, but got {} {!r}.'.format( - self._enum_type.name, type(number), number)) - else: - # repr here to handle the odd case when you pass in a boolean. - raise ValueError('Enum {} has no name defined for value {!r}'.format( - self._enum_type.name, number)) - - def Value(self, name): # pylint: disable=invalid-name - """Returns the value corresponding to the given enum name.""" - try: - return self._enum_type.values_by_name[name].number - except KeyError: - pass # fall out to break exception chaining - raise ValueError('Enum {} has no value defined for name {!r}'.format( - self._enum_type.name, name)) - - def keys(self): - """Return a list of the string names in the enum. - - Returns: - A list of strs, in the order they were defined in the .proto file. - """ - - return [value_descriptor.name - for value_descriptor in self._enum_type.values] - - def values(self): - """Return a list of the integer values in the enum. - - Returns: - A list of ints, in the order they were defined in the .proto file. - """ - - return [value_descriptor.number - for value_descriptor in self._enum_type.values] - - def items(self): - """Return a list of the (name, value) pairs of the enum. - - Returns: - A list of (str, int) pairs, in the order they were defined - in the .proto file. - """ - return [(value_descriptor.name, value_descriptor.number) - for value_descriptor in self._enum_type.values] - - def __getattr__(self, name): - """Returns the value corresponding to the given enum name.""" - try: - return super( - EnumTypeWrapper, - self).__getattribute__('_enum_type').values_by_name[name].number - except KeyError: - pass # fall out to break exception chaining - raise AttributeError('Enum {} has no value defined for name {!r}'.format( - self._enum_type.name, name)) diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/extension_dict.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/extension_dict.py deleted file mode 100644 index b346cf283e..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/extension_dict.py +++ /dev/null @@ -1,213 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Contains _ExtensionDict class to represent extensions. -""" - -from google.protobuf.internal import type_checkers -from google.protobuf.descriptor import FieldDescriptor - - -def _VerifyExtensionHandle(message, extension_handle): - """Verify that the given extension handle is valid.""" - - if not isinstance(extension_handle, FieldDescriptor): - raise KeyError('HasExtension() expects an extension handle, got: %s' % - extension_handle) - - if not extension_handle.is_extension: - raise KeyError('"%s" is not an extension.' % extension_handle.full_name) - - if not extension_handle.containing_type: - raise KeyError('"%s" is missing a containing_type.' - % extension_handle.full_name) - - if extension_handle.containing_type is not message.DESCRIPTOR: - raise KeyError('Extension "%s" extends message type "%s", but this ' - 'message is of type "%s".' % - (extension_handle.full_name, - extension_handle.containing_type.full_name, - message.DESCRIPTOR.full_name)) - - -# TODO(robinson): Unify error handling of "unknown extension" crap. -# TODO(robinson): Support iteritems()-style iteration over all -# extensions with the "has" bits turned on? -class _ExtensionDict(object): - - """Dict-like container for Extension fields on proto instances. - - Note that in all cases we expect extension handles to be - FieldDescriptors. - """ - - def __init__(self, extended_message): - """ - Args: - extended_message: Message instance for which we are the Extensions dict. - """ - self._extended_message = extended_message - - def __getitem__(self, extension_handle): - """Returns the current value of the given extension handle.""" - - _VerifyExtensionHandle(self._extended_message, extension_handle) - - result = self._extended_message._fields.get(extension_handle) - if result is not None: - return result - - if extension_handle.label == FieldDescriptor.LABEL_REPEATED: - result = extension_handle._default_constructor(self._extended_message) - elif extension_handle.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE: - message_type = extension_handle.message_type - if not hasattr(message_type, '_concrete_class'): - # pylint: disable=protected-access - self._extended_message._FACTORY.GetPrototype(message_type) - assert getattr(extension_handle.message_type, '_concrete_class', None), ( - 'Uninitialized concrete class found for field %r (message type %r)' - % (extension_handle.full_name, - extension_handle.message_type.full_name)) - result = extension_handle.message_type._concrete_class() - try: - result._SetListener(self._extended_message._listener_for_children) - except ReferenceError: - pass - else: - # Singular scalar -- just return the default without inserting into the - # dict. - return extension_handle.default_value - - # Atomically check if another thread has preempted us and, if not, swap - # in the new object we just created. If someone has preempted us, we - # take that object and discard ours. - # WARNING: We are relying on setdefault() being atomic. This is true - # in CPython but we haven't investigated others. This warning appears - # in several other locations in this file. - result = self._extended_message._fields.setdefault( - extension_handle, result) - - return result - - def __eq__(self, other): - if not isinstance(other, self.__class__): - return False - - my_fields = self._extended_message.ListFields() - other_fields = other._extended_message.ListFields() - - # Get rid of non-extension fields. - my_fields = [field for field in my_fields if field.is_extension] - other_fields = [field for field in other_fields if field.is_extension] - - return my_fields == other_fields - - def __ne__(self, other): - return not self == other - - def __len__(self): - fields = self._extended_message.ListFields() - # Get rid of non-extension fields. - extension_fields = [field for field in fields if field[0].is_extension] - return len(extension_fields) - - def __hash__(self): - raise TypeError('unhashable object') - - # Note that this is only meaningful for non-repeated, scalar extension - # fields. Note also that we may have to call _Modified() when we do - # successfully set a field this way, to set any necessary "has" bits in the - # ancestors of the extended message. - def __setitem__(self, extension_handle, value): - """If extension_handle specifies a non-repeated, scalar extension - field, sets the value of that field. - """ - - _VerifyExtensionHandle(self._extended_message, extension_handle) - - if (extension_handle.label == FieldDescriptor.LABEL_REPEATED or - extension_handle.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE): - raise TypeError( - 'Cannot assign to extension "%s" because it is a repeated or ' - 'composite type.' % extension_handle.full_name) - - # It's slightly wasteful to lookup the type checker each time, - # but we expect this to be a vanishingly uncommon case anyway. - type_checker = type_checkers.GetTypeChecker(extension_handle) - # pylint: disable=protected-access - self._extended_message._fields[extension_handle] = ( - type_checker.CheckValue(value)) - self._extended_message._Modified() - - def __delitem__(self, extension_handle): - self._extended_message.ClearExtension(extension_handle) - - def _FindExtensionByName(self, name): - """Tries to find a known extension with the specified name. - - Args: - name: Extension full name. - - Returns: - Extension field descriptor. - """ - return self._extended_message._extensions_by_name.get(name, None) - - def _FindExtensionByNumber(self, number): - """Tries to find a known extension with the field number. - - Args: - number: Extension field number. - - Returns: - Extension field descriptor. - """ - return self._extended_message._extensions_by_number.get(number, None) - - def __iter__(self): - # Return a generator over the populated extension fields - return (f[0] for f in self._extended_message.ListFields() - if f[0].is_extension) - - def __contains__(self, extension_handle): - _VerifyExtensionHandle(self._extended_message, extension_handle) - - if extension_handle not in self._extended_message._fields: - return False - - if extension_handle.label == FieldDescriptor.LABEL_REPEATED: - return bool(self._extended_message._fields.get(extension_handle)) - - if extension_handle.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE: - value = self._extended_message._fields.get(extension_handle) - # pylint: disable=protected-access - return value is not None and value._is_present_in_parent - - return True diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/message_listener.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/message_listener.py deleted file mode 100644 index 0fc255a774..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/message_listener.py +++ /dev/null @@ -1,78 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Defines a listener interface for observing certain -state transitions on Message objects. - -Also defines a null implementation of this interface. -""" - -__author__ = 'robinson@google.com (Will Robinson)' - - -class MessageListener(object): - - """Listens for modifications made to a message. Meant to be registered via - Message._SetListener(). - - Attributes: - dirty: If True, then calling Modified() would be a no-op. This can be - used to avoid these calls entirely in the common case. - """ - - def Modified(self): - """Called every time the message is modified in such a way that the parent - message may need to be updated. This currently means either: - (a) The message was modified for the first time, so the parent message - should henceforth mark the message as present. - (b) The message's cached byte size became dirty -- i.e. the message was - modified for the first time after a previous call to ByteSize(). - Therefore the parent should also mark its byte size as dirty. - Note that (a) implies (b), since new objects start out with a client cached - size (zero). However, we document (a) explicitly because it is important. - - Modified() will *only* be called in response to one of these two events -- - not every time the sub-message is modified. - - Note that if the listener's |dirty| attribute is true, then calling - Modified at the moment would be a no-op, so it can be skipped. Performance- - sensitive callers should check this attribute directly before calling since - it will be true most of the time. - """ - - raise NotImplementedError - - -class NullMessageListener(object): - - """No-op MessageListener implementation.""" - - def Modified(self): - pass diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/message_set_extensions_pb2.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/message_set_extensions_pb2.py deleted file mode 100644 index 63651a3f19..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/message_set_extensions_pb2.py +++ /dev/null @@ -1,36 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/internal/message_set_extensions.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n5google/protobuf/internal/message_set_extensions.proto\x12\x18google.protobuf.internal\"\x1e\n\x0eTestMessageSet*\x08\x08\x04\x10\xff\xff\xff\xff\x07:\x02\x08\x01\"\xa5\x01\n\x18TestMessageSetExtension1\x12\t\n\x01i\x18\x0f \x01(\x05\x32~\n\x15message_set_extension\x12(.google.protobuf.internal.TestMessageSet\x18\xab\xff\xf6. \x01(\x0b\x32\x32.google.protobuf.internal.TestMessageSetExtension1\"\xa7\x01\n\x18TestMessageSetExtension2\x12\x0b\n\x03str\x18\x19 \x01(\t2~\n\x15message_set_extension\x12(.google.protobuf.internal.TestMessageSet\x18\xca\xff\xf6. \x01(\x0b\x32\x32.google.protobuf.internal.TestMessageSetExtension2\"(\n\x18TestMessageSetExtension3\x12\x0c\n\x04text\x18# \x01(\t:\x7f\n\x16message_set_extension3\x12(.google.protobuf.internal.TestMessageSet\x18\xdf\xff\xf6. \x01(\x0b\x32\x32.google.protobuf.internal.TestMessageSetExtension3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.internal.message_set_extensions_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - TestMessageSet.RegisterExtension(message_set_extension3) - TestMessageSet.RegisterExtension(_TESTMESSAGESETEXTENSION1.extensions_by_name['message_set_extension']) - TestMessageSet.RegisterExtension(_TESTMESSAGESETEXTENSION2.extensions_by_name['message_set_extension']) - - DESCRIPTOR._options = None - _TESTMESSAGESET._options = None - _TESTMESSAGESET._serialized_options = b'\010\001' - _TESTMESSAGESET._serialized_start=83 - _TESTMESSAGESET._serialized_end=113 - _TESTMESSAGESETEXTENSION1._serialized_start=116 - _TESTMESSAGESETEXTENSION1._serialized_end=281 - _TESTMESSAGESETEXTENSION2._serialized_start=284 - _TESTMESSAGESETEXTENSION2._serialized_end=451 - _TESTMESSAGESETEXTENSION3._serialized_start=453 - _TESTMESSAGESETEXTENSION3._serialized_end=493 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/missing_enum_values_pb2.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/missing_enum_values_pb2.py deleted file mode 100644 index 5497083197..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/missing_enum_values_pb2.py +++ /dev/null @@ -1,37 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/internal/missing_enum_values.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n2google/protobuf/internal/missing_enum_values.proto\x12\x1fgoogle.protobuf.python.internal\"\xc1\x02\n\x0eTestEnumValues\x12X\n\x14optional_nested_enum\x18\x01 \x01(\x0e\x32:.google.protobuf.python.internal.TestEnumValues.NestedEnum\x12X\n\x14repeated_nested_enum\x18\x02 \x03(\x0e\x32:.google.protobuf.python.internal.TestEnumValues.NestedEnum\x12Z\n\x12packed_nested_enum\x18\x03 \x03(\x0e\x32:.google.protobuf.python.internal.TestEnumValues.NestedEnumB\x02\x10\x01\"\x1f\n\nNestedEnum\x12\x08\n\x04ZERO\x10\x00\x12\x07\n\x03ONE\x10\x01\"\xd3\x02\n\x15TestMissingEnumValues\x12_\n\x14optional_nested_enum\x18\x01 \x01(\x0e\x32\x41.google.protobuf.python.internal.TestMissingEnumValues.NestedEnum\x12_\n\x14repeated_nested_enum\x18\x02 \x03(\x0e\x32\x41.google.protobuf.python.internal.TestMissingEnumValues.NestedEnum\x12\x61\n\x12packed_nested_enum\x18\x03 \x03(\x0e\x32\x41.google.protobuf.python.internal.TestMissingEnumValues.NestedEnumB\x02\x10\x01\"\x15\n\nNestedEnum\x12\x07\n\x03TWO\x10\x02\"\x1b\n\nJustString\x12\r\n\x05\x64ummy\x18\x01 \x02(\t') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.internal.missing_enum_values_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - _TESTENUMVALUES.fields_by_name['packed_nested_enum']._options = None - _TESTENUMVALUES.fields_by_name['packed_nested_enum']._serialized_options = b'\020\001' - _TESTMISSINGENUMVALUES.fields_by_name['packed_nested_enum']._options = None - _TESTMISSINGENUMVALUES.fields_by_name['packed_nested_enum']._serialized_options = b'\020\001' - _TESTENUMVALUES._serialized_start=88 - _TESTENUMVALUES._serialized_end=409 - _TESTENUMVALUES_NESTEDENUM._serialized_start=378 - _TESTENUMVALUES_NESTEDENUM._serialized_end=409 - _TESTMISSINGENUMVALUES._serialized_start=412 - _TESTMISSINGENUMVALUES._serialized_end=751 - _TESTMISSINGENUMVALUES_NESTEDENUM._serialized_start=730 - _TESTMISSINGENUMVALUES_NESTEDENUM._serialized_end=751 - _JUSTSTRING._serialized_start=753 - _JUSTSTRING._serialized_end=780 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/more_extensions_dynamic_pb2.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/more_extensions_dynamic_pb2.py deleted file mode 100644 index 0953706bac..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/more_extensions_dynamic_pb2.py +++ /dev/null @@ -1,29 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/internal/more_extensions_dynamic.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.protobuf.internal import more_extensions_pb2 as google_dot_protobuf_dot_internal_dot_more__extensions__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n6google/protobuf/internal/more_extensions_dynamic.proto\x12\x18google.protobuf.internal\x1a.google/protobuf/internal/more_extensions.proto\"\x1f\n\x12\x44ynamicMessageType\x12\t\n\x01\x61\x18\x01 \x01(\x05:J\n\x17\x64ynamic_int32_extension\x12).google.protobuf.internal.ExtendedMessage\x18\x64 \x01(\x05:z\n\x19\x64ynamic_message_extension\x12).google.protobuf.internal.ExtendedMessage\x18\x65 \x01(\x0b\x32,.google.protobuf.internal.DynamicMessageType:\x83\x01\n\"repeated_dynamic_message_extension\x12).google.protobuf.internal.ExtendedMessage\x18\x66 \x03(\x0b\x32,.google.protobuf.internal.DynamicMessageType') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.internal.more_extensions_dynamic_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - google_dot_protobuf_dot_internal_dot_more__extensions__pb2.ExtendedMessage.RegisterExtension(dynamic_int32_extension) - google_dot_protobuf_dot_internal_dot_more__extensions__pb2.ExtendedMessage.RegisterExtension(dynamic_message_extension) - google_dot_protobuf_dot_internal_dot_more__extensions__pb2.ExtendedMessage.RegisterExtension(repeated_dynamic_message_extension) - - DESCRIPTOR._options = None - _DYNAMICMESSAGETYPE._serialized_start=132 - _DYNAMICMESSAGETYPE._serialized_end=163 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/more_extensions_pb2.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/more_extensions_pb2.py deleted file mode 100644 index 1cfa1b7c8b..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/more_extensions_pb2.py +++ /dev/null @@ -1,41 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/internal/more_extensions.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n.google/protobuf/internal/more_extensions.proto\x12\x18google.protobuf.internal\"\x99\x01\n\x0fTopLevelMessage\x12\x41\n\nsubmessage\x18\x01 \x01(\x0b\x32).google.protobuf.internal.ExtendedMessageB\x02(\x01\x12\x43\n\x0enested_message\x18\x02 \x01(\x0b\x32\'.google.protobuf.internal.NestedMessageB\x02(\x01\"R\n\rNestedMessage\x12\x41\n\nsubmessage\x18\x01 \x01(\x0b\x32).google.protobuf.internal.ExtendedMessageB\x02(\x01\"K\n\x0f\x45xtendedMessage\x12\x17\n\x0eoptional_int32\x18\xe9\x07 \x01(\x05\x12\x18\n\x0frepeated_string\x18\xea\x07 \x03(\t*\x05\x08\x01\x10\xe8\x07\"-\n\x0e\x46oreignMessage\x12\x1b\n\x13\x66oreign_message_int\x18\x01 \x01(\x05:I\n\x16optional_int_extension\x12).google.protobuf.internal.ExtendedMessage\x18\x01 \x01(\x05:w\n\x1aoptional_message_extension\x12).google.protobuf.internal.ExtendedMessage\x18\x02 \x01(\x0b\x32(.google.protobuf.internal.ForeignMessage:I\n\x16repeated_int_extension\x12).google.protobuf.internal.ExtendedMessage\x18\x03 \x03(\x05:w\n\x1arepeated_message_extension\x12).google.protobuf.internal.ExtendedMessage\x18\x04 \x03(\x0b\x32(.google.protobuf.internal.ForeignMessage') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.internal.more_extensions_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - ExtendedMessage.RegisterExtension(optional_int_extension) - ExtendedMessage.RegisterExtension(optional_message_extension) - ExtendedMessage.RegisterExtension(repeated_int_extension) - ExtendedMessage.RegisterExtension(repeated_message_extension) - - DESCRIPTOR._options = None - _TOPLEVELMESSAGE.fields_by_name['submessage']._options = None - _TOPLEVELMESSAGE.fields_by_name['submessage']._serialized_options = b'(\001' - _TOPLEVELMESSAGE.fields_by_name['nested_message']._options = None - _TOPLEVELMESSAGE.fields_by_name['nested_message']._serialized_options = b'(\001' - _NESTEDMESSAGE.fields_by_name['submessage']._options = None - _NESTEDMESSAGE.fields_by_name['submessage']._serialized_options = b'(\001' - _TOPLEVELMESSAGE._serialized_start=77 - _TOPLEVELMESSAGE._serialized_end=230 - _NESTEDMESSAGE._serialized_start=232 - _NESTEDMESSAGE._serialized_end=314 - _EXTENDEDMESSAGE._serialized_start=316 - _EXTENDEDMESSAGE._serialized_end=391 - _FOREIGNMESSAGE._serialized_start=393 - _FOREIGNMESSAGE._serialized_end=438 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/more_messages_pb2.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/more_messages_pb2.py deleted file mode 100644 index d7f7115609..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/more_messages_pb2.py +++ /dev/null @@ -1,556 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/internal/more_messages.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n,google/protobuf/internal/more_messages.proto\x12\x18google.protobuf.internal\"h\n\x10OutOfOrderFields\x12\x17\n\x0foptional_sint32\x18\x05 \x01(\x11\x12\x17\n\x0foptional_uint32\x18\x03 \x01(\r\x12\x16\n\x0eoptional_int32\x18\x01 \x01(\x05*\x04\x08\x04\x10\x05*\x04\x08\x02\x10\x03\"\xcd\x02\n\x05\x63lass\x12\x1b\n\tint_field\x18\x01 \x01(\x05R\x08json_int\x12\n\n\x02if\x18\x02 \x01(\x05\x12(\n\x02\x61s\x18\x03 \x01(\x0e\x32\x1c.google.protobuf.internal.is\x12\x30\n\nenum_field\x18\x04 \x01(\x0e\x32\x1c.google.protobuf.internal.is\x12>\n\x11nested_enum_field\x18\x05 \x01(\x0e\x32#.google.protobuf.internal.class.for\x12;\n\x0enested_message\x18\x06 \x01(\x0b\x32#.google.protobuf.internal.class.try\x1a\x1c\n\x03try\x12\r\n\x05\x66ield\x18\x01 \x01(\x05*\x06\x08\xe7\x07\x10\x90N\"\x1c\n\x03\x66or\x12\x0b\n\x07\x64\x65\x66\x61ult\x10\x00\x12\x08\n\x04True\x10\x01*\x06\x08\xe7\x07\x10\x90N\"?\n\x0b\x45xtendClass20\n\x06return\x12\x1f.google.protobuf.internal.class\x18\xea\x07 \x01(\x05\"~\n\x0fTestFullKeyword\x12:\n\x06\x66ield1\x18\x01 \x01(\x0b\x32*.google.protobuf.internal.OutOfOrderFields\x12/\n\x06\x66ield2\x18\x02 \x01(\x0b\x32\x1f.google.protobuf.internal.class\"\xa5\x0f\n\x11LotsNestedMessage\x1a\x04\n\x02\x42\x30\x1a\x04\n\x02\x42\x31\x1a\x04\n\x02\x42\x32\x1a\x04\n\x02\x42\x33\x1a\x04\n\x02\x42\x34\x1a\x04\n\x02\x42\x35\x1a\x04\n\x02\x42\x36\x1a\x04\n\x02\x42\x37\x1a\x04\n\x02\x42\x38\x1a\x04\n\x02\x42\x39\x1a\x05\n\x03\x42\x31\x30\x1a\x05\n\x03\x42\x31\x31\x1a\x05\n\x03\x42\x31\x32\x1a\x05\n\x03\x42\x31\x33\x1a\x05\n\x03\x42\x31\x34\x1a\x05\n\x03\x42\x31\x35\x1a\x05\n\x03\x42\x31\x36\x1a\x05\n\x03\x42\x31\x37\x1a\x05\n\x03\x42\x31\x38\x1a\x05\n\x03\x42\x31\x39\x1a\x05\n\x03\x42\x32\x30\x1a\x05\n\x03\x42\x32\x31\x1a\x05\n\x03\x42\x32\x32\x1a\x05\n\x03\x42\x32\x33\x1a\x05\n\x03\x42\x32\x34\x1a\x05\n\x03\x42\x32\x35\x1a\x05\n\x03\x42\x32\x36\x1a\x05\n\x03\x42\x32\x37\x1a\x05\n\x03\x42\x32\x38\x1a\x05\n\x03\x42\x32\x39\x1a\x05\n\x03\x42\x33\x30\x1a\x05\n\x03\x42\x33\x31\x1a\x05\n\x03\x42\x33\x32\x1a\x05\n\x03\x42\x33\x33\x1a\x05\n\x03\x42\x33\x34\x1a\x05\n\x03\x42\x33\x35\x1a\x05\n\x03\x42\x33\x36\x1a\x05\n\x03\x42\x33\x37\x1a\x05\n\x03\x42\x33\x38\x1a\x05\n\x03\x42\x33\x39\x1a\x05\n\x03\x42\x34\x30\x1a\x05\n\x03\x42\x34\x31\x1a\x05\n\x03\x42\x34\x32\x1a\x05\n\x03\x42\x34\x33\x1a\x05\n\x03\x42\x34\x34\x1a\x05\n\x03\x42\x34\x35\x1a\x05\n\x03\x42\x34\x36\x1a\x05\n\x03\x42\x34\x37\x1a\x05\n\x03\x42\x34\x38\x1a\x05\n\x03\x42\x34\x39\x1a\x05\n\x03\x42\x35\x30\x1a\x05\n\x03\x42\x35\x31\x1a\x05\n\x03\x42\x35\x32\x1a\x05\n\x03\x42\x35\x33\x1a\x05\n\x03\x42\x35\x34\x1a\x05\n\x03\x42\x35\x35\x1a\x05\n\x03\x42\x35\x36\x1a\x05\n\x03\x42\x35\x37\x1a\x05\n\x03\x42\x35\x38\x1a\x05\n\x03\x42\x35\x39\x1a\x05\n\x03\x42\x36\x30\x1a\x05\n\x03\x42\x36\x31\x1a\x05\n\x03\x42\x36\x32\x1a\x05\n\x03\x42\x36\x33\x1a\x05\n\x03\x42\x36\x34\x1a\x05\n\x03\x42\x36\x35\x1a\x05\n\x03\x42\x36\x36\x1a\x05\n\x03\x42\x36\x37\x1a\x05\n\x03\x42\x36\x38\x1a\x05\n\x03\x42\x36\x39\x1a\x05\n\x03\x42\x37\x30\x1a\x05\n\x03\x42\x37\x31\x1a\x05\n\x03\x42\x37\x32\x1a\x05\n\x03\x42\x37\x33\x1a\x05\n\x03\x42\x37\x34\x1a\x05\n\x03\x42\x37\x35\x1a\x05\n\x03\x42\x37\x36\x1a\x05\n\x03\x42\x37\x37\x1a\x05\n\x03\x42\x37\x38\x1a\x05\n\x03\x42\x37\x39\x1a\x05\n\x03\x42\x38\x30\x1a\x05\n\x03\x42\x38\x31\x1a\x05\n\x03\x42\x38\x32\x1a\x05\n\x03\x42\x38\x33\x1a\x05\n\x03\x42\x38\x34\x1a\x05\n\x03\x42\x38\x35\x1a\x05\n\x03\x42\x38\x36\x1a\x05\n\x03\x42\x38\x37\x1a\x05\n\x03\x42\x38\x38\x1a\x05\n\x03\x42\x38\x39\x1a\x05\n\x03\x42\x39\x30\x1a\x05\n\x03\x42\x39\x31\x1a\x05\n\x03\x42\x39\x32\x1a\x05\n\x03\x42\x39\x33\x1a\x05\n\x03\x42\x39\x34\x1a\x05\n\x03\x42\x39\x35\x1a\x05\n\x03\x42\x39\x36\x1a\x05\n\x03\x42\x39\x37\x1a\x05\n\x03\x42\x39\x38\x1a\x05\n\x03\x42\x39\x39\x1a\x06\n\x04\x42\x31\x30\x30\x1a\x06\n\x04\x42\x31\x30\x31\x1a\x06\n\x04\x42\x31\x30\x32\x1a\x06\n\x04\x42\x31\x30\x33\x1a\x06\n\x04\x42\x31\x30\x34\x1a\x06\n\x04\x42\x31\x30\x35\x1a\x06\n\x04\x42\x31\x30\x36\x1a\x06\n\x04\x42\x31\x30\x37\x1a\x06\n\x04\x42\x31\x30\x38\x1a\x06\n\x04\x42\x31\x30\x39\x1a\x06\n\x04\x42\x31\x31\x30\x1a\x06\n\x04\x42\x31\x31\x31\x1a\x06\n\x04\x42\x31\x31\x32\x1a\x06\n\x04\x42\x31\x31\x33\x1a\x06\n\x04\x42\x31\x31\x34\x1a\x06\n\x04\x42\x31\x31\x35\x1a\x06\n\x04\x42\x31\x31\x36\x1a\x06\n\x04\x42\x31\x31\x37\x1a\x06\n\x04\x42\x31\x31\x38\x1a\x06\n\x04\x42\x31\x31\x39\x1a\x06\n\x04\x42\x31\x32\x30\x1a\x06\n\x04\x42\x31\x32\x31\x1a\x06\n\x04\x42\x31\x32\x32\x1a\x06\n\x04\x42\x31\x32\x33\x1a\x06\n\x04\x42\x31\x32\x34\x1a\x06\n\x04\x42\x31\x32\x35\x1a\x06\n\x04\x42\x31\x32\x36\x1a\x06\n\x04\x42\x31\x32\x37\x1a\x06\n\x04\x42\x31\x32\x38\x1a\x06\n\x04\x42\x31\x32\x39\x1a\x06\n\x04\x42\x31\x33\x30\x1a\x06\n\x04\x42\x31\x33\x31\x1a\x06\n\x04\x42\x31\x33\x32\x1a\x06\n\x04\x42\x31\x33\x33\x1a\x06\n\x04\x42\x31\x33\x34\x1a\x06\n\x04\x42\x31\x33\x35\x1a\x06\n\x04\x42\x31\x33\x36\x1a\x06\n\x04\x42\x31\x33\x37\x1a\x06\n\x04\x42\x31\x33\x38\x1a\x06\n\x04\x42\x31\x33\x39\x1a\x06\n\x04\x42\x31\x34\x30\x1a\x06\n\x04\x42\x31\x34\x31\x1a\x06\n\x04\x42\x31\x34\x32\x1a\x06\n\x04\x42\x31\x34\x33\x1a\x06\n\x04\x42\x31\x34\x34\x1a\x06\n\x04\x42\x31\x34\x35\x1a\x06\n\x04\x42\x31\x34\x36\x1a\x06\n\x04\x42\x31\x34\x37\x1a\x06\n\x04\x42\x31\x34\x38\x1a\x06\n\x04\x42\x31\x34\x39\x1a\x06\n\x04\x42\x31\x35\x30\x1a\x06\n\x04\x42\x31\x35\x31\x1a\x06\n\x04\x42\x31\x35\x32\x1a\x06\n\x04\x42\x31\x35\x33\x1a\x06\n\x04\x42\x31\x35\x34\x1a\x06\n\x04\x42\x31\x35\x35\x1a\x06\n\x04\x42\x31\x35\x36\x1a\x06\n\x04\x42\x31\x35\x37\x1a\x06\n\x04\x42\x31\x35\x38\x1a\x06\n\x04\x42\x31\x35\x39\x1a\x06\n\x04\x42\x31\x36\x30\x1a\x06\n\x04\x42\x31\x36\x31\x1a\x06\n\x04\x42\x31\x36\x32\x1a\x06\n\x04\x42\x31\x36\x33\x1a\x06\n\x04\x42\x31\x36\x34\x1a\x06\n\x04\x42\x31\x36\x35\x1a\x06\n\x04\x42\x31\x36\x36\x1a\x06\n\x04\x42\x31\x36\x37\x1a\x06\n\x04\x42\x31\x36\x38\x1a\x06\n\x04\x42\x31\x36\x39\x1a\x06\n\x04\x42\x31\x37\x30\x1a\x06\n\x04\x42\x31\x37\x31\x1a\x06\n\x04\x42\x31\x37\x32\x1a\x06\n\x04\x42\x31\x37\x33\x1a\x06\n\x04\x42\x31\x37\x34\x1a\x06\n\x04\x42\x31\x37\x35\x1a\x06\n\x04\x42\x31\x37\x36\x1a\x06\n\x04\x42\x31\x37\x37\x1a\x06\n\x04\x42\x31\x37\x38\x1a\x06\n\x04\x42\x31\x37\x39\x1a\x06\n\x04\x42\x31\x38\x30\x1a\x06\n\x04\x42\x31\x38\x31\x1a\x06\n\x04\x42\x31\x38\x32\x1a\x06\n\x04\x42\x31\x38\x33\x1a\x06\n\x04\x42\x31\x38\x34\x1a\x06\n\x04\x42\x31\x38\x35\x1a\x06\n\x04\x42\x31\x38\x36\x1a\x06\n\x04\x42\x31\x38\x37\x1a\x06\n\x04\x42\x31\x38\x38\x1a\x06\n\x04\x42\x31\x38\x39\x1a\x06\n\x04\x42\x31\x39\x30\x1a\x06\n\x04\x42\x31\x39\x31\x1a\x06\n\x04\x42\x31\x39\x32\x1a\x06\n\x04\x42\x31\x39\x33\x1a\x06\n\x04\x42\x31\x39\x34\x1a\x06\n\x04\x42\x31\x39\x35\x1a\x06\n\x04\x42\x31\x39\x36\x1a\x06\n\x04\x42\x31\x39\x37\x1a\x06\n\x04\x42\x31\x39\x38\x1a\x06\n\x04\x42\x31\x39\x39\x1a\x06\n\x04\x42\x32\x30\x30\x1a\x06\n\x04\x42\x32\x30\x31\x1a\x06\n\x04\x42\x32\x30\x32\x1a\x06\n\x04\x42\x32\x30\x33\x1a\x06\n\x04\x42\x32\x30\x34\x1a\x06\n\x04\x42\x32\x30\x35\x1a\x06\n\x04\x42\x32\x30\x36\x1a\x06\n\x04\x42\x32\x30\x37\x1a\x06\n\x04\x42\x32\x30\x38\x1a\x06\n\x04\x42\x32\x30\x39\x1a\x06\n\x04\x42\x32\x31\x30\x1a\x06\n\x04\x42\x32\x31\x31\x1a\x06\n\x04\x42\x32\x31\x32\x1a\x06\n\x04\x42\x32\x31\x33\x1a\x06\n\x04\x42\x32\x31\x34\x1a\x06\n\x04\x42\x32\x31\x35\x1a\x06\n\x04\x42\x32\x31\x36\x1a\x06\n\x04\x42\x32\x31\x37\x1a\x06\n\x04\x42\x32\x31\x38\x1a\x06\n\x04\x42\x32\x31\x39\x1a\x06\n\x04\x42\x32\x32\x30\x1a\x06\n\x04\x42\x32\x32\x31\x1a\x06\n\x04\x42\x32\x32\x32\x1a\x06\n\x04\x42\x32\x32\x33\x1a\x06\n\x04\x42\x32\x32\x34\x1a\x06\n\x04\x42\x32\x32\x35\x1a\x06\n\x04\x42\x32\x32\x36\x1a\x06\n\x04\x42\x32\x32\x37\x1a\x06\n\x04\x42\x32\x32\x38\x1a\x06\n\x04\x42\x32\x32\x39\x1a\x06\n\x04\x42\x32\x33\x30\x1a\x06\n\x04\x42\x32\x33\x31\x1a\x06\n\x04\x42\x32\x33\x32\x1a\x06\n\x04\x42\x32\x33\x33\x1a\x06\n\x04\x42\x32\x33\x34\x1a\x06\n\x04\x42\x32\x33\x35\x1a\x06\n\x04\x42\x32\x33\x36\x1a\x06\n\x04\x42\x32\x33\x37\x1a\x06\n\x04\x42\x32\x33\x38\x1a\x06\n\x04\x42\x32\x33\x39\x1a\x06\n\x04\x42\x32\x34\x30\x1a\x06\n\x04\x42\x32\x34\x31\x1a\x06\n\x04\x42\x32\x34\x32\x1a\x06\n\x04\x42\x32\x34\x33\x1a\x06\n\x04\x42\x32\x34\x34\x1a\x06\n\x04\x42\x32\x34\x35\x1a\x06\n\x04\x42\x32\x34\x36\x1a\x06\n\x04\x42\x32\x34\x37\x1a\x06\n\x04\x42\x32\x34\x38\x1a\x06\n\x04\x42\x32\x34\x39\x1a\x06\n\x04\x42\x32\x35\x30\x1a\x06\n\x04\x42\x32\x35\x31\x1a\x06\n\x04\x42\x32\x35\x32\x1a\x06\n\x04\x42\x32\x35\x33\x1a\x06\n\x04\x42\x32\x35\x34\x1a\x06\n\x04\x42\x32\x35\x35*\x1b\n\x02is\x12\x0b\n\x07\x64\x65\x66\x61ult\x10\x00\x12\x08\n\x04\x65lse\x10\x01:C\n\x0foptional_uint64\x12*.google.protobuf.internal.OutOfOrderFields\x18\x04 \x01(\x04:B\n\x0eoptional_int64\x12*.google.protobuf.internal.OutOfOrderFields\x18\x02 \x01(\x03:2\n\x08\x63ontinue\x12\x1f.google.protobuf.internal.class\x18\xe9\x07 \x01(\x05:2\n\x04with\x12#.google.protobuf.internal.class.try\x18\xe9\x07 \x01(\x05') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.internal.more_messages_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - OutOfOrderFields.RegisterExtension(optional_uint64) - OutOfOrderFields.RegisterExtension(optional_int64) - globals()['class'].RegisterExtension(globals()['continue']) - getattr(globals()['class'], 'try').RegisterExtension(globals()['with']) - globals()['class'].RegisterExtension(_EXTENDCLASS.extensions_by_name['return']) - - DESCRIPTOR._options = None - _IS._serialized_start=2669 - _IS._serialized_end=2696 - _OUTOFORDERFIELDS._serialized_start=74 - _OUTOFORDERFIELDS._serialized_end=178 - _CLASS._serialized_start=181 - _CLASS._serialized_end=514 - _CLASS_TRY._serialized_start=448 - _CLASS_TRY._serialized_end=476 - _CLASS_FOR._serialized_start=478 - _CLASS_FOR._serialized_end=506 - _EXTENDCLASS._serialized_start=516 - _EXTENDCLASS._serialized_end=579 - _TESTFULLKEYWORD._serialized_start=581 - _TESTFULLKEYWORD._serialized_end=707 - _LOTSNESTEDMESSAGE._serialized_start=710 - _LOTSNESTEDMESSAGE._serialized_end=2667 - _LOTSNESTEDMESSAGE_B0._serialized_start=731 - _LOTSNESTEDMESSAGE_B0._serialized_end=735 - _LOTSNESTEDMESSAGE_B1._serialized_start=737 - _LOTSNESTEDMESSAGE_B1._serialized_end=741 - _LOTSNESTEDMESSAGE_B2._serialized_start=743 - _LOTSNESTEDMESSAGE_B2._serialized_end=747 - _LOTSNESTEDMESSAGE_B3._serialized_start=749 - _LOTSNESTEDMESSAGE_B3._serialized_end=753 - _LOTSNESTEDMESSAGE_B4._serialized_start=755 - _LOTSNESTEDMESSAGE_B4._serialized_end=759 - _LOTSNESTEDMESSAGE_B5._serialized_start=761 - _LOTSNESTEDMESSAGE_B5._serialized_end=765 - _LOTSNESTEDMESSAGE_B6._serialized_start=767 - _LOTSNESTEDMESSAGE_B6._serialized_end=771 - _LOTSNESTEDMESSAGE_B7._serialized_start=773 - _LOTSNESTEDMESSAGE_B7._serialized_end=777 - _LOTSNESTEDMESSAGE_B8._serialized_start=779 - _LOTSNESTEDMESSAGE_B8._serialized_end=783 - _LOTSNESTEDMESSAGE_B9._serialized_start=785 - _LOTSNESTEDMESSAGE_B9._serialized_end=789 - _LOTSNESTEDMESSAGE_B10._serialized_start=791 - _LOTSNESTEDMESSAGE_B10._serialized_end=796 - _LOTSNESTEDMESSAGE_B11._serialized_start=798 - _LOTSNESTEDMESSAGE_B11._serialized_end=803 - _LOTSNESTEDMESSAGE_B12._serialized_start=805 - _LOTSNESTEDMESSAGE_B12._serialized_end=810 - _LOTSNESTEDMESSAGE_B13._serialized_start=812 - _LOTSNESTEDMESSAGE_B13._serialized_end=817 - _LOTSNESTEDMESSAGE_B14._serialized_start=819 - _LOTSNESTEDMESSAGE_B14._serialized_end=824 - _LOTSNESTEDMESSAGE_B15._serialized_start=826 - _LOTSNESTEDMESSAGE_B15._serialized_end=831 - _LOTSNESTEDMESSAGE_B16._serialized_start=833 - _LOTSNESTEDMESSAGE_B16._serialized_end=838 - _LOTSNESTEDMESSAGE_B17._serialized_start=840 - _LOTSNESTEDMESSAGE_B17._serialized_end=845 - _LOTSNESTEDMESSAGE_B18._serialized_start=847 - _LOTSNESTEDMESSAGE_B18._serialized_end=852 - _LOTSNESTEDMESSAGE_B19._serialized_start=854 - _LOTSNESTEDMESSAGE_B19._serialized_end=859 - _LOTSNESTEDMESSAGE_B20._serialized_start=861 - _LOTSNESTEDMESSAGE_B20._serialized_end=866 - _LOTSNESTEDMESSAGE_B21._serialized_start=868 - _LOTSNESTEDMESSAGE_B21._serialized_end=873 - _LOTSNESTEDMESSAGE_B22._serialized_start=875 - _LOTSNESTEDMESSAGE_B22._serialized_end=880 - _LOTSNESTEDMESSAGE_B23._serialized_start=882 - _LOTSNESTEDMESSAGE_B23._serialized_end=887 - _LOTSNESTEDMESSAGE_B24._serialized_start=889 - _LOTSNESTEDMESSAGE_B24._serialized_end=894 - _LOTSNESTEDMESSAGE_B25._serialized_start=896 - _LOTSNESTEDMESSAGE_B25._serialized_end=901 - _LOTSNESTEDMESSAGE_B26._serialized_start=903 - _LOTSNESTEDMESSAGE_B26._serialized_end=908 - _LOTSNESTEDMESSAGE_B27._serialized_start=910 - _LOTSNESTEDMESSAGE_B27._serialized_end=915 - _LOTSNESTEDMESSAGE_B28._serialized_start=917 - _LOTSNESTEDMESSAGE_B28._serialized_end=922 - _LOTSNESTEDMESSAGE_B29._serialized_start=924 - _LOTSNESTEDMESSAGE_B29._serialized_end=929 - _LOTSNESTEDMESSAGE_B30._serialized_start=931 - _LOTSNESTEDMESSAGE_B30._serialized_end=936 - _LOTSNESTEDMESSAGE_B31._serialized_start=938 - _LOTSNESTEDMESSAGE_B31._serialized_end=943 - _LOTSNESTEDMESSAGE_B32._serialized_start=945 - _LOTSNESTEDMESSAGE_B32._serialized_end=950 - _LOTSNESTEDMESSAGE_B33._serialized_start=952 - _LOTSNESTEDMESSAGE_B33._serialized_end=957 - _LOTSNESTEDMESSAGE_B34._serialized_start=959 - _LOTSNESTEDMESSAGE_B34._serialized_end=964 - _LOTSNESTEDMESSAGE_B35._serialized_start=966 - _LOTSNESTEDMESSAGE_B35._serialized_end=971 - _LOTSNESTEDMESSAGE_B36._serialized_start=973 - _LOTSNESTEDMESSAGE_B36._serialized_end=978 - _LOTSNESTEDMESSAGE_B37._serialized_start=980 - _LOTSNESTEDMESSAGE_B37._serialized_end=985 - _LOTSNESTEDMESSAGE_B38._serialized_start=987 - _LOTSNESTEDMESSAGE_B38._serialized_end=992 - _LOTSNESTEDMESSAGE_B39._serialized_start=994 - _LOTSNESTEDMESSAGE_B39._serialized_end=999 - _LOTSNESTEDMESSAGE_B40._serialized_start=1001 - _LOTSNESTEDMESSAGE_B40._serialized_end=1006 - _LOTSNESTEDMESSAGE_B41._serialized_start=1008 - _LOTSNESTEDMESSAGE_B41._serialized_end=1013 - _LOTSNESTEDMESSAGE_B42._serialized_start=1015 - _LOTSNESTEDMESSAGE_B42._serialized_end=1020 - _LOTSNESTEDMESSAGE_B43._serialized_start=1022 - _LOTSNESTEDMESSAGE_B43._serialized_end=1027 - _LOTSNESTEDMESSAGE_B44._serialized_start=1029 - _LOTSNESTEDMESSAGE_B44._serialized_end=1034 - _LOTSNESTEDMESSAGE_B45._serialized_start=1036 - _LOTSNESTEDMESSAGE_B45._serialized_end=1041 - _LOTSNESTEDMESSAGE_B46._serialized_start=1043 - _LOTSNESTEDMESSAGE_B46._serialized_end=1048 - _LOTSNESTEDMESSAGE_B47._serialized_start=1050 - _LOTSNESTEDMESSAGE_B47._serialized_end=1055 - _LOTSNESTEDMESSAGE_B48._serialized_start=1057 - _LOTSNESTEDMESSAGE_B48._serialized_end=1062 - _LOTSNESTEDMESSAGE_B49._serialized_start=1064 - _LOTSNESTEDMESSAGE_B49._serialized_end=1069 - _LOTSNESTEDMESSAGE_B50._serialized_start=1071 - _LOTSNESTEDMESSAGE_B50._serialized_end=1076 - _LOTSNESTEDMESSAGE_B51._serialized_start=1078 - _LOTSNESTEDMESSAGE_B51._serialized_end=1083 - _LOTSNESTEDMESSAGE_B52._serialized_start=1085 - _LOTSNESTEDMESSAGE_B52._serialized_end=1090 - _LOTSNESTEDMESSAGE_B53._serialized_start=1092 - _LOTSNESTEDMESSAGE_B53._serialized_end=1097 - _LOTSNESTEDMESSAGE_B54._serialized_start=1099 - _LOTSNESTEDMESSAGE_B54._serialized_end=1104 - _LOTSNESTEDMESSAGE_B55._serialized_start=1106 - _LOTSNESTEDMESSAGE_B55._serialized_end=1111 - _LOTSNESTEDMESSAGE_B56._serialized_start=1113 - _LOTSNESTEDMESSAGE_B56._serialized_end=1118 - _LOTSNESTEDMESSAGE_B57._serialized_start=1120 - _LOTSNESTEDMESSAGE_B57._serialized_end=1125 - _LOTSNESTEDMESSAGE_B58._serialized_start=1127 - _LOTSNESTEDMESSAGE_B58._serialized_end=1132 - _LOTSNESTEDMESSAGE_B59._serialized_start=1134 - _LOTSNESTEDMESSAGE_B59._serialized_end=1139 - _LOTSNESTEDMESSAGE_B60._serialized_start=1141 - _LOTSNESTEDMESSAGE_B60._serialized_end=1146 - _LOTSNESTEDMESSAGE_B61._serialized_start=1148 - _LOTSNESTEDMESSAGE_B61._serialized_end=1153 - _LOTSNESTEDMESSAGE_B62._serialized_start=1155 - _LOTSNESTEDMESSAGE_B62._serialized_end=1160 - _LOTSNESTEDMESSAGE_B63._serialized_start=1162 - _LOTSNESTEDMESSAGE_B63._serialized_end=1167 - _LOTSNESTEDMESSAGE_B64._serialized_start=1169 - _LOTSNESTEDMESSAGE_B64._serialized_end=1174 - _LOTSNESTEDMESSAGE_B65._serialized_start=1176 - _LOTSNESTEDMESSAGE_B65._serialized_end=1181 - _LOTSNESTEDMESSAGE_B66._serialized_start=1183 - _LOTSNESTEDMESSAGE_B66._serialized_end=1188 - _LOTSNESTEDMESSAGE_B67._serialized_start=1190 - _LOTSNESTEDMESSAGE_B67._serialized_end=1195 - _LOTSNESTEDMESSAGE_B68._serialized_start=1197 - _LOTSNESTEDMESSAGE_B68._serialized_end=1202 - _LOTSNESTEDMESSAGE_B69._serialized_start=1204 - _LOTSNESTEDMESSAGE_B69._serialized_end=1209 - _LOTSNESTEDMESSAGE_B70._serialized_start=1211 - _LOTSNESTEDMESSAGE_B70._serialized_end=1216 - _LOTSNESTEDMESSAGE_B71._serialized_start=1218 - _LOTSNESTEDMESSAGE_B71._serialized_end=1223 - _LOTSNESTEDMESSAGE_B72._serialized_start=1225 - _LOTSNESTEDMESSAGE_B72._serialized_end=1230 - _LOTSNESTEDMESSAGE_B73._serialized_start=1232 - _LOTSNESTEDMESSAGE_B73._serialized_end=1237 - _LOTSNESTEDMESSAGE_B74._serialized_start=1239 - _LOTSNESTEDMESSAGE_B74._serialized_end=1244 - _LOTSNESTEDMESSAGE_B75._serialized_start=1246 - _LOTSNESTEDMESSAGE_B75._serialized_end=1251 - _LOTSNESTEDMESSAGE_B76._serialized_start=1253 - _LOTSNESTEDMESSAGE_B76._serialized_end=1258 - _LOTSNESTEDMESSAGE_B77._serialized_start=1260 - _LOTSNESTEDMESSAGE_B77._serialized_end=1265 - _LOTSNESTEDMESSAGE_B78._serialized_start=1267 - _LOTSNESTEDMESSAGE_B78._serialized_end=1272 - _LOTSNESTEDMESSAGE_B79._serialized_start=1274 - _LOTSNESTEDMESSAGE_B79._serialized_end=1279 - _LOTSNESTEDMESSAGE_B80._serialized_start=1281 - _LOTSNESTEDMESSAGE_B80._serialized_end=1286 - _LOTSNESTEDMESSAGE_B81._serialized_start=1288 - _LOTSNESTEDMESSAGE_B81._serialized_end=1293 - _LOTSNESTEDMESSAGE_B82._serialized_start=1295 - _LOTSNESTEDMESSAGE_B82._serialized_end=1300 - _LOTSNESTEDMESSAGE_B83._serialized_start=1302 - _LOTSNESTEDMESSAGE_B83._serialized_end=1307 - _LOTSNESTEDMESSAGE_B84._serialized_start=1309 - _LOTSNESTEDMESSAGE_B84._serialized_end=1314 - _LOTSNESTEDMESSAGE_B85._serialized_start=1316 - _LOTSNESTEDMESSAGE_B85._serialized_end=1321 - _LOTSNESTEDMESSAGE_B86._serialized_start=1323 - _LOTSNESTEDMESSAGE_B86._serialized_end=1328 - _LOTSNESTEDMESSAGE_B87._serialized_start=1330 - _LOTSNESTEDMESSAGE_B87._serialized_end=1335 - _LOTSNESTEDMESSAGE_B88._serialized_start=1337 - _LOTSNESTEDMESSAGE_B88._serialized_end=1342 - _LOTSNESTEDMESSAGE_B89._serialized_start=1344 - _LOTSNESTEDMESSAGE_B89._serialized_end=1349 - _LOTSNESTEDMESSAGE_B90._serialized_start=1351 - _LOTSNESTEDMESSAGE_B90._serialized_end=1356 - _LOTSNESTEDMESSAGE_B91._serialized_start=1358 - _LOTSNESTEDMESSAGE_B91._serialized_end=1363 - _LOTSNESTEDMESSAGE_B92._serialized_start=1365 - _LOTSNESTEDMESSAGE_B92._serialized_end=1370 - _LOTSNESTEDMESSAGE_B93._serialized_start=1372 - _LOTSNESTEDMESSAGE_B93._serialized_end=1377 - _LOTSNESTEDMESSAGE_B94._serialized_start=1379 - _LOTSNESTEDMESSAGE_B94._serialized_end=1384 - _LOTSNESTEDMESSAGE_B95._serialized_start=1386 - _LOTSNESTEDMESSAGE_B95._serialized_end=1391 - _LOTSNESTEDMESSAGE_B96._serialized_start=1393 - _LOTSNESTEDMESSAGE_B96._serialized_end=1398 - _LOTSNESTEDMESSAGE_B97._serialized_start=1400 - _LOTSNESTEDMESSAGE_B97._serialized_end=1405 - _LOTSNESTEDMESSAGE_B98._serialized_start=1407 - _LOTSNESTEDMESSAGE_B98._serialized_end=1412 - _LOTSNESTEDMESSAGE_B99._serialized_start=1414 - _LOTSNESTEDMESSAGE_B99._serialized_end=1419 - _LOTSNESTEDMESSAGE_B100._serialized_start=1421 - _LOTSNESTEDMESSAGE_B100._serialized_end=1427 - _LOTSNESTEDMESSAGE_B101._serialized_start=1429 - _LOTSNESTEDMESSAGE_B101._serialized_end=1435 - _LOTSNESTEDMESSAGE_B102._serialized_start=1437 - _LOTSNESTEDMESSAGE_B102._serialized_end=1443 - _LOTSNESTEDMESSAGE_B103._serialized_start=1445 - _LOTSNESTEDMESSAGE_B103._serialized_end=1451 - _LOTSNESTEDMESSAGE_B104._serialized_start=1453 - _LOTSNESTEDMESSAGE_B104._serialized_end=1459 - _LOTSNESTEDMESSAGE_B105._serialized_start=1461 - _LOTSNESTEDMESSAGE_B105._serialized_end=1467 - _LOTSNESTEDMESSAGE_B106._serialized_start=1469 - _LOTSNESTEDMESSAGE_B106._serialized_end=1475 - _LOTSNESTEDMESSAGE_B107._serialized_start=1477 - _LOTSNESTEDMESSAGE_B107._serialized_end=1483 - _LOTSNESTEDMESSAGE_B108._serialized_start=1485 - _LOTSNESTEDMESSAGE_B108._serialized_end=1491 - _LOTSNESTEDMESSAGE_B109._serialized_start=1493 - _LOTSNESTEDMESSAGE_B109._serialized_end=1499 - _LOTSNESTEDMESSAGE_B110._serialized_start=1501 - _LOTSNESTEDMESSAGE_B110._serialized_end=1507 - _LOTSNESTEDMESSAGE_B111._serialized_start=1509 - _LOTSNESTEDMESSAGE_B111._serialized_end=1515 - _LOTSNESTEDMESSAGE_B112._serialized_start=1517 - _LOTSNESTEDMESSAGE_B112._serialized_end=1523 - _LOTSNESTEDMESSAGE_B113._serialized_start=1525 - _LOTSNESTEDMESSAGE_B113._serialized_end=1531 - _LOTSNESTEDMESSAGE_B114._serialized_start=1533 - _LOTSNESTEDMESSAGE_B114._serialized_end=1539 - _LOTSNESTEDMESSAGE_B115._serialized_start=1541 - _LOTSNESTEDMESSAGE_B115._serialized_end=1547 - _LOTSNESTEDMESSAGE_B116._serialized_start=1549 - _LOTSNESTEDMESSAGE_B116._serialized_end=1555 - _LOTSNESTEDMESSAGE_B117._serialized_start=1557 - _LOTSNESTEDMESSAGE_B117._serialized_end=1563 - _LOTSNESTEDMESSAGE_B118._serialized_start=1565 - _LOTSNESTEDMESSAGE_B118._serialized_end=1571 - _LOTSNESTEDMESSAGE_B119._serialized_start=1573 - _LOTSNESTEDMESSAGE_B119._serialized_end=1579 - _LOTSNESTEDMESSAGE_B120._serialized_start=1581 - _LOTSNESTEDMESSAGE_B120._serialized_end=1587 - _LOTSNESTEDMESSAGE_B121._serialized_start=1589 - _LOTSNESTEDMESSAGE_B121._serialized_end=1595 - _LOTSNESTEDMESSAGE_B122._serialized_start=1597 - _LOTSNESTEDMESSAGE_B122._serialized_end=1603 - _LOTSNESTEDMESSAGE_B123._serialized_start=1605 - _LOTSNESTEDMESSAGE_B123._serialized_end=1611 - _LOTSNESTEDMESSAGE_B124._serialized_start=1613 - _LOTSNESTEDMESSAGE_B124._serialized_end=1619 - _LOTSNESTEDMESSAGE_B125._serialized_start=1621 - _LOTSNESTEDMESSAGE_B125._serialized_end=1627 - _LOTSNESTEDMESSAGE_B126._serialized_start=1629 - _LOTSNESTEDMESSAGE_B126._serialized_end=1635 - _LOTSNESTEDMESSAGE_B127._serialized_start=1637 - _LOTSNESTEDMESSAGE_B127._serialized_end=1643 - _LOTSNESTEDMESSAGE_B128._serialized_start=1645 - _LOTSNESTEDMESSAGE_B128._serialized_end=1651 - _LOTSNESTEDMESSAGE_B129._serialized_start=1653 - _LOTSNESTEDMESSAGE_B129._serialized_end=1659 - _LOTSNESTEDMESSAGE_B130._serialized_start=1661 - _LOTSNESTEDMESSAGE_B130._serialized_end=1667 - _LOTSNESTEDMESSAGE_B131._serialized_start=1669 - _LOTSNESTEDMESSAGE_B131._serialized_end=1675 - _LOTSNESTEDMESSAGE_B132._serialized_start=1677 - _LOTSNESTEDMESSAGE_B132._serialized_end=1683 - _LOTSNESTEDMESSAGE_B133._serialized_start=1685 - _LOTSNESTEDMESSAGE_B133._serialized_end=1691 - _LOTSNESTEDMESSAGE_B134._serialized_start=1693 - _LOTSNESTEDMESSAGE_B134._serialized_end=1699 - _LOTSNESTEDMESSAGE_B135._serialized_start=1701 - _LOTSNESTEDMESSAGE_B135._serialized_end=1707 - _LOTSNESTEDMESSAGE_B136._serialized_start=1709 - _LOTSNESTEDMESSAGE_B136._serialized_end=1715 - _LOTSNESTEDMESSAGE_B137._serialized_start=1717 - _LOTSNESTEDMESSAGE_B137._serialized_end=1723 - _LOTSNESTEDMESSAGE_B138._serialized_start=1725 - _LOTSNESTEDMESSAGE_B138._serialized_end=1731 - _LOTSNESTEDMESSAGE_B139._serialized_start=1733 - _LOTSNESTEDMESSAGE_B139._serialized_end=1739 - _LOTSNESTEDMESSAGE_B140._serialized_start=1741 - _LOTSNESTEDMESSAGE_B140._serialized_end=1747 - _LOTSNESTEDMESSAGE_B141._serialized_start=1749 - _LOTSNESTEDMESSAGE_B141._serialized_end=1755 - _LOTSNESTEDMESSAGE_B142._serialized_start=1757 - _LOTSNESTEDMESSAGE_B142._serialized_end=1763 - _LOTSNESTEDMESSAGE_B143._serialized_start=1765 - _LOTSNESTEDMESSAGE_B143._serialized_end=1771 - _LOTSNESTEDMESSAGE_B144._serialized_start=1773 - _LOTSNESTEDMESSAGE_B144._serialized_end=1779 - _LOTSNESTEDMESSAGE_B145._serialized_start=1781 - _LOTSNESTEDMESSAGE_B145._serialized_end=1787 - _LOTSNESTEDMESSAGE_B146._serialized_start=1789 - _LOTSNESTEDMESSAGE_B146._serialized_end=1795 - _LOTSNESTEDMESSAGE_B147._serialized_start=1797 - _LOTSNESTEDMESSAGE_B147._serialized_end=1803 - _LOTSNESTEDMESSAGE_B148._serialized_start=1805 - _LOTSNESTEDMESSAGE_B148._serialized_end=1811 - _LOTSNESTEDMESSAGE_B149._serialized_start=1813 - _LOTSNESTEDMESSAGE_B149._serialized_end=1819 - _LOTSNESTEDMESSAGE_B150._serialized_start=1821 - _LOTSNESTEDMESSAGE_B150._serialized_end=1827 - _LOTSNESTEDMESSAGE_B151._serialized_start=1829 - _LOTSNESTEDMESSAGE_B151._serialized_end=1835 - _LOTSNESTEDMESSAGE_B152._serialized_start=1837 - _LOTSNESTEDMESSAGE_B152._serialized_end=1843 - _LOTSNESTEDMESSAGE_B153._serialized_start=1845 - _LOTSNESTEDMESSAGE_B153._serialized_end=1851 - _LOTSNESTEDMESSAGE_B154._serialized_start=1853 - _LOTSNESTEDMESSAGE_B154._serialized_end=1859 - _LOTSNESTEDMESSAGE_B155._serialized_start=1861 - _LOTSNESTEDMESSAGE_B155._serialized_end=1867 - _LOTSNESTEDMESSAGE_B156._serialized_start=1869 - _LOTSNESTEDMESSAGE_B156._serialized_end=1875 - _LOTSNESTEDMESSAGE_B157._serialized_start=1877 - _LOTSNESTEDMESSAGE_B157._serialized_end=1883 - _LOTSNESTEDMESSAGE_B158._serialized_start=1885 - _LOTSNESTEDMESSAGE_B158._serialized_end=1891 - _LOTSNESTEDMESSAGE_B159._serialized_start=1893 - _LOTSNESTEDMESSAGE_B159._serialized_end=1899 - _LOTSNESTEDMESSAGE_B160._serialized_start=1901 - _LOTSNESTEDMESSAGE_B160._serialized_end=1907 - _LOTSNESTEDMESSAGE_B161._serialized_start=1909 - _LOTSNESTEDMESSAGE_B161._serialized_end=1915 - _LOTSNESTEDMESSAGE_B162._serialized_start=1917 - _LOTSNESTEDMESSAGE_B162._serialized_end=1923 - _LOTSNESTEDMESSAGE_B163._serialized_start=1925 - _LOTSNESTEDMESSAGE_B163._serialized_end=1931 - _LOTSNESTEDMESSAGE_B164._serialized_start=1933 - _LOTSNESTEDMESSAGE_B164._serialized_end=1939 - _LOTSNESTEDMESSAGE_B165._serialized_start=1941 - _LOTSNESTEDMESSAGE_B165._serialized_end=1947 - _LOTSNESTEDMESSAGE_B166._serialized_start=1949 - _LOTSNESTEDMESSAGE_B166._serialized_end=1955 - _LOTSNESTEDMESSAGE_B167._serialized_start=1957 - _LOTSNESTEDMESSAGE_B167._serialized_end=1963 - _LOTSNESTEDMESSAGE_B168._serialized_start=1965 - _LOTSNESTEDMESSAGE_B168._serialized_end=1971 - _LOTSNESTEDMESSAGE_B169._serialized_start=1973 - _LOTSNESTEDMESSAGE_B169._serialized_end=1979 - _LOTSNESTEDMESSAGE_B170._serialized_start=1981 - _LOTSNESTEDMESSAGE_B170._serialized_end=1987 - _LOTSNESTEDMESSAGE_B171._serialized_start=1989 - _LOTSNESTEDMESSAGE_B171._serialized_end=1995 - _LOTSNESTEDMESSAGE_B172._serialized_start=1997 - _LOTSNESTEDMESSAGE_B172._serialized_end=2003 - _LOTSNESTEDMESSAGE_B173._serialized_start=2005 - _LOTSNESTEDMESSAGE_B173._serialized_end=2011 - _LOTSNESTEDMESSAGE_B174._serialized_start=2013 - _LOTSNESTEDMESSAGE_B174._serialized_end=2019 - _LOTSNESTEDMESSAGE_B175._serialized_start=2021 - _LOTSNESTEDMESSAGE_B175._serialized_end=2027 - _LOTSNESTEDMESSAGE_B176._serialized_start=2029 - _LOTSNESTEDMESSAGE_B176._serialized_end=2035 - _LOTSNESTEDMESSAGE_B177._serialized_start=2037 - _LOTSNESTEDMESSAGE_B177._serialized_end=2043 - _LOTSNESTEDMESSAGE_B178._serialized_start=2045 - _LOTSNESTEDMESSAGE_B178._serialized_end=2051 - _LOTSNESTEDMESSAGE_B179._serialized_start=2053 - _LOTSNESTEDMESSAGE_B179._serialized_end=2059 - _LOTSNESTEDMESSAGE_B180._serialized_start=2061 - _LOTSNESTEDMESSAGE_B180._serialized_end=2067 - _LOTSNESTEDMESSAGE_B181._serialized_start=2069 - _LOTSNESTEDMESSAGE_B181._serialized_end=2075 - _LOTSNESTEDMESSAGE_B182._serialized_start=2077 - _LOTSNESTEDMESSAGE_B182._serialized_end=2083 - _LOTSNESTEDMESSAGE_B183._serialized_start=2085 - _LOTSNESTEDMESSAGE_B183._serialized_end=2091 - _LOTSNESTEDMESSAGE_B184._serialized_start=2093 - _LOTSNESTEDMESSAGE_B184._serialized_end=2099 - _LOTSNESTEDMESSAGE_B185._serialized_start=2101 - _LOTSNESTEDMESSAGE_B185._serialized_end=2107 - _LOTSNESTEDMESSAGE_B186._serialized_start=2109 - _LOTSNESTEDMESSAGE_B186._serialized_end=2115 - _LOTSNESTEDMESSAGE_B187._serialized_start=2117 - _LOTSNESTEDMESSAGE_B187._serialized_end=2123 - _LOTSNESTEDMESSAGE_B188._serialized_start=2125 - _LOTSNESTEDMESSAGE_B188._serialized_end=2131 - _LOTSNESTEDMESSAGE_B189._serialized_start=2133 - _LOTSNESTEDMESSAGE_B189._serialized_end=2139 - _LOTSNESTEDMESSAGE_B190._serialized_start=2141 - _LOTSNESTEDMESSAGE_B190._serialized_end=2147 - _LOTSNESTEDMESSAGE_B191._serialized_start=2149 - _LOTSNESTEDMESSAGE_B191._serialized_end=2155 - _LOTSNESTEDMESSAGE_B192._serialized_start=2157 - _LOTSNESTEDMESSAGE_B192._serialized_end=2163 - _LOTSNESTEDMESSAGE_B193._serialized_start=2165 - _LOTSNESTEDMESSAGE_B193._serialized_end=2171 - _LOTSNESTEDMESSAGE_B194._serialized_start=2173 - _LOTSNESTEDMESSAGE_B194._serialized_end=2179 - _LOTSNESTEDMESSAGE_B195._serialized_start=2181 - _LOTSNESTEDMESSAGE_B195._serialized_end=2187 - _LOTSNESTEDMESSAGE_B196._serialized_start=2189 - _LOTSNESTEDMESSAGE_B196._serialized_end=2195 - _LOTSNESTEDMESSAGE_B197._serialized_start=2197 - _LOTSNESTEDMESSAGE_B197._serialized_end=2203 - _LOTSNESTEDMESSAGE_B198._serialized_start=2205 - _LOTSNESTEDMESSAGE_B198._serialized_end=2211 - _LOTSNESTEDMESSAGE_B199._serialized_start=2213 - _LOTSNESTEDMESSAGE_B199._serialized_end=2219 - _LOTSNESTEDMESSAGE_B200._serialized_start=2221 - _LOTSNESTEDMESSAGE_B200._serialized_end=2227 - _LOTSNESTEDMESSAGE_B201._serialized_start=2229 - _LOTSNESTEDMESSAGE_B201._serialized_end=2235 - _LOTSNESTEDMESSAGE_B202._serialized_start=2237 - _LOTSNESTEDMESSAGE_B202._serialized_end=2243 - _LOTSNESTEDMESSAGE_B203._serialized_start=2245 - _LOTSNESTEDMESSAGE_B203._serialized_end=2251 - _LOTSNESTEDMESSAGE_B204._serialized_start=2253 - _LOTSNESTEDMESSAGE_B204._serialized_end=2259 - _LOTSNESTEDMESSAGE_B205._serialized_start=2261 - _LOTSNESTEDMESSAGE_B205._serialized_end=2267 - _LOTSNESTEDMESSAGE_B206._serialized_start=2269 - _LOTSNESTEDMESSAGE_B206._serialized_end=2275 - _LOTSNESTEDMESSAGE_B207._serialized_start=2277 - _LOTSNESTEDMESSAGE_B207._serialized_end=2283 - _LOTSNESTEDMESSAGE_B208._serialized_start=2285 - _LOTSNESTEDMESSAGE_B208._serialized_end=2291 - _LOTSNESTEDMESSAGE_B209._serialized_start=2293 - _LOTSNESTEDMESSAGE_B209._serialized_end=2299 - _LOTSNESTEDMESSAGE_B210._serialized_start=2301 - _LOTSNESTEDMESSAGE_B210._serialized_end=2307 - _LOTSNESTEDMESSAGE_B211._serialized_start=2309 - _LOTSNESTEDMESSAGE_B211._serialized_end=2315 - _LOTSNESTEDMESSAGE_B212._serialized_start=2317 - _LOTSNESTEDMESSAGE_B212._serialized_end=2323 - _LOTSNESTEDMESSAGE_B213._serialized_start=2325 - _LOTSNESTEDMESSAGE_B213._serialized_end=2331 - _LOTSNESTEDMESSAGE_B214._serialized_start=2333 - _LOTSNESTEDMESSAGE_B214._serialized_end=2339 - _LOTSNESTEDMESSAGE_B215._serialized_start=2341 - _LOTSNESTEDMESSAGE_B215._serialized_end=2347 - _LOTSNESTEDMESSAGE_B216._serialized_start=2349 - _LOTSNESTEDMESSAGE_B216._serialized_end=2355 - _LOTSNESTEDMESSAGE_B217._serialized_start=2357 - _LOTSNESTEDMESSAGE_B217._serialized_end=2363 - _LOTSNESTEDMESSAGE_B218._serialized_start=2365 - _LOTSNESTEDMESSAGE_B218._serialized_end=2371 - _LOTSNESTEDMESSAGE_B219._serialized_start=2373 - _LOTSNESTEDMESSAGE_B219._serialized_end=2379 - _LOTSNESTEDMESSAGE_B220._serialized_start=2381 - _LOTSNESTEDMESSAGE_B220._serialized_end=2387 - _LOTSNESTEDMESSAGE_B221._serialized_start=2389 - _LOTSNESTEDMESSAGE_B221._serialized_end=2395 - _LOTSNESTEDMESSAGE_B222._serialized_start=2397 - _LOTSNESTEDMESSAGE_B222._serialized_end=2403 - _LOTSNESTEDMESSAGE_B223._serialized_start=2405 - _LOTSNESTEDMESSAGE_B223._serialized_end=2411 - _LOTSNESTEDMESSAGE_B224._serialized_start=2413 - _LOTSNESTEDMESSAGE_B224._serialized_end=2419 - _LOTSNESTEDMESSAGE_B225._serialized_start=2421 - _LOTSNESTEDMESSAGE_B225._serialized_end=2427 - _LOTSNESTEDMESSAGE_B226._serialized_start=2429 - _LOTSNESTEDMESSAGE_B226._serialized_end=2435 - _LOTSNESTEDMESSAGE_B227._serialized_start=2437 - _LOTSNESTEDMESSAGE_B227._serialized_end=2443 - _LOTSNESTEDMESSAGE_B228._serialized_start=2445 - _LOTSNESTEDMESSAGE_B228._serialized_end=2451 - _LOTSNESTEDMESSAGE_B229._serialized_start=2453 - _LOTSNESTEDMESSAGE_B229._serialized_end=2459 - _LOTSNESTEDMESSAGE_B230._serialized_start=2461 - _LOTSNESTEDMESSAGE_B230._serialized_end=2467 - _LOTSNESTEDMESSAGE_B231._serialized_start=2469 - _LOTSNESTEDMESSAGE_B231._serialized_end=2475 - _LOTSNESTEDMESSAGE_B232._serialized_start=2477 - _LOTSNESTEDMESSAGE_B232._serialized_end=2483 - _LOTSNESTEDMESSAGE_B233._serialized_start=2485 - _LOTSNESTEDMESSAGE_B233._serialized_end=2491 - _LOTSNESTEDMESSAGE_B234._serialized_start=2493 - _LOTSNESTEDMESSAGE_B234._serialized_end=2499 - _LOTSNESTEDMESSAGE_B235._serialized_start=2501 - _LOTSNESTEDMESSAGE_B235._serialized_end=2507 - _LOTSNESTEDMESSAGE_B236._serialized_start=2509 - _LOTSNESTEDMESSAGE_B236._serialized_end=2515 - _LOTSNESTEDMESSAGE_B237._serialized_start=2517 - _LOTSNESTEDMESSAGE_B237._serialized_end=2523 - _LOTSNESTEDMESSAGE_B238._serialized_start=2525 - _LOTSNESTEDMESSAGE_B238._serialized_end=2531 - _LOTSNESTEDMESSAGE_B239._serialized_start=2533 - _LOTSNESTEDMESSAGE_B239._serialized_end=2539 - _LOTSNESTEDMESSAGE_B240._serialized_start=2541 - _LOTSNESTEDMESSAGE_B240._serialized_end=2547 - _LOTSNESTEDMESSAGE_B241._serialized_start=2549 - _LOTSNESTEDMESSAGE_B241._serialized_end=2555 - _LOTSNESTEDMESSAGE_B242._serialized_start=2557 - _LOTSNESTEDMESSAGE_B242._serialized_end=2563 - _LOTSNESTEDMESSAGE_B243._serialized_start=2565 - _LOTSNESTEDMESSAGE_B243._serialized_end=2571 - _LOTSNESTEDMESSAGE_B244._serialized_start=2573 - _LOTSNESTEDMESSAGE_B244._serialized_end=2579 - _LOTSNESTEDMESSAGE_B245._serialized_start=2581 - _LOTSNESTEDMESSAGE_B245._serialized_end=2587 - _LOTSNESTEDMESSAGE_B246._serialized_start=2589 - _LOTSNESTEDMESSAGE_B246._serialized_end=2595 - _LOTSNESTEDMESSAGE_B247._serialized_start=2597 - _LOTSNESTEDMESSAGE_B247._serialized_end=2603 - _LOTSNESTEDMESSAGE_B248._serialized_start=2605 - _LOTSNESTEDMESSAGE_B248._serialized_end=2611 - _LOTSNESTEDMESSAGE_B249._serialized_start=2613 - _LOTSNESTEDMESSAGE_B249._serialized_end=2619 - _LOTSNESTEDMESSAGE_B250._serialized_start=2621 - _LOTSNESTEDMESSAGE_B250._serialized_end=2627 - _LOTSNESTEDMESSAGE_B251._serialized_start=2629 - _LOTSNESTEDMESSAGE_B251._serialized_end=2635 - _LOTSNESTEDMESSAGE_B252._serialized_start=2637 - _LOTSNESTEDMESSAGE_B252._serialized_end=2643 - _LOTSNESTEDMESSAGE_B253._serialized_start=2645 - _LOTSNESTEDMESSAGE_B253._serialized_end=2651 - _LOTSNESTEDMESSAGE_B254._serialized_start=2653 - _LOTSNESTEDMESSAGE_B254._serialized_end=2659 - _LOTSNESTEDMESSAGE_B255._serialized_start=2661 - _LOTSNESTEDMESSAGE_B255._serialized_end=2667 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/no_package_pb2.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/no_package_pb2.py deleted file mode 100644 index d46dee080a..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/no_package_pb2.py +++ /dev/null @@ -1,27 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/internal/no_package.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n)google/protobuf/internal/no_package.proto\";\n\x10NoPackageMessage\x12\'\n\x0fno_package_enum\x18\x01 \x01(\x0e\x32\x0e.NoPackageEnum*?\n\rNoPackageEnum\x12\x16\n\x12NO_PACKAGE_VALUE_0\x10\x00\x12\x16\n\x12NO_PACKAGE_VALUE_1\x10\x01') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.internal.no_package_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - _NOPACKAGEENUM._serialized_start=106 - _NOPACKAGEENUM._serialized_end=169 - _NOPACKAGEMESSAGE._serialized_start=45 - _NOPACKAGEMESSAGE._serialized_end=104 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/python_message.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/python_message.py deleted file mode 100644 index 2921d5cb6e..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/python_message.py +++ /dev/null @@ -1,1539 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -# This code is meant to work on Python 2.4 and above only. -# -# TODO(robinson): Helpers for verbose, common checks like seeing if a -# descriptor's cpp_type is CPPTYPE_MESSAGE. - -"""Contains a metaclass and helper functions used to create -protocol message classes from Descriptor objects at runtime. - -Recall that a metaclass is the "type" of a class. -(A class is to a metaclass what an instance is to a class.) - -In this case, we use the GeneratedProtocolMessageType metaclass -to inject all the useful functionality into the classes -output by the protocol compiler at compile-time. - -The upshot of all this is that the real implementation -details for ALL pure-Python protocol buffers are *here in -this file*. -""" - -__author__ = 'robinson@google.com (Will Robinson)' - -from io import BytesIO -import struct -import sys -import weakref - -# We use "as" to avoid name collisions with variables. -from google.protobuf.internal import api_implementation -from google.protobuf.internal import containers -from google.protobuf.internal import decoder -from google.protobuf.internal import encoder -from google.protobuf.internal import enum_type_wrapper -from google.protobuf.internal import extension_dict -from google.protobuf.internal import message_listener as message_listener_mod -from google.protobuf.internal import type_checkers -from google.protobuf.internal import well_known_types -from google.protobuf.internal import wire_format -from google.protobuf import descriptor as descriptor_mod -from google.protobuf import message as message_mod -from google.protobuf import text_format - -_FieldDescriptor = descriptor_mod.FieldDescriptor -_AnyFullTypeName = 'google.protobuf.Any' -_ExtensionDict = extension_dict._ExtensionDict - -class GeneratedProtocolMessageType(type): - - """Metaclass for protocol message classes created at runtime from Descriptors. - - We add implementations for all methods described in the Message class. We - also create properties to allow getting/setting all fields in the protocol - message. Finally, we create slots to prevent users from accidentally - "setting" nonexistent fields in the protocol message, which then wouldn't get - serialized / deserialized properly. - - The protocol compiler currently uses this metaclass to create protocol - message classes at runtime. Clients can also manually create their own - classes at runtime, as in this example: - - mydescriptor = Descriptor(.....) - factory = symbol_database.Default() - factory.pool.AddDescriptor(mydescriptor) - MyProtoClass = factory.GetPrototype(mydescriptor) - myproto_instance = MyProtoClass() - myproto.foo_field = 23 - ... - """ - - # Must be consistent with the protocol-compiler code in - # proto2/compiler/internal/generator.*. - _DESCRIPTOR_KEY = 'DESCRIPTOR' - - def __new__(cls, name, bases, dictionary): - """Custom allocation for runtime-generated class types. - - We override __new__ because this is apparently the only place - where we can meaningfully set __slots__ on the class we're creating(?). - (The interplay between metaclasses and slots is not very well-documented). - - Args: - name: Name of the class (ignored, but required by the - metaclass protocol). - bases: Base classes of the class we're constructing. - (Should be message.Message). We ignore this field, but - it's required by the metaclass protocol - dictionary: The class dictionary of the class we're - constructing. dictionary[_DESCRIPTOR_KEY] must contain - a Descriptor object describing this protocol message - type. - - Returns: - Newly-allocated class. - - Raises: - RuntimeError: Generated code only work with python cpp extension. - """ - descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY] - - if isinstance(descriptor, str): - raise RuntimeError('The generated code only work with python cpp ' - 'extension, but it is using pure python runtime.') - - # If a concrete class already exists for this descriptor, don't try to - # create another. Doing so will break any messages that already exist with - # the existing class. - # - # The C++ implementation appears to have its own internal `PyMessageFactory` - # to achieve similar results. - # - # This most commonly happens in `text_format.py` when using descriptors from - # a custom pool; it calls symbol_database.Global().getPrototype() on a - # descriptor which already has an existing concrete class. - new_class = getattr(descriptor, '_concrete_class', None) - if new_class: - return new_class - - if descriptor.full_name in well_known_types.WKTBASES: - bases += (well_known_types.WKTBASES[descriptor.full_name],) - _AddClassAttributesForNestedExtensions(descriptor, dictionary) - _AddSlots(descriptor, dictionary) - - superclass = super(GeneratedProtocolMessageType, cls) - new_class = superclass.__new__(cls, name, bases, dictionary) - return new_class - - def __init__(cls, name, bases, dictionary): - """Here we perform the majority of our work on the class. - We add enum getters, an __init__ method, implementations - of all Message methods, and properties for all fields - in the protocol type. - - Args: - name: Name of the class (ignored, but required by the - metaclass protocol). - bases: Base classes of the class we're constructing. - (Should be message.Message). We ignore this field, but - it's required by the metaclass protocol - dictionary: The class dictionary of the class we're - constructing. dictionary[_DESCRIPTOR_KEY] must contain - a Descriptor object describing this protocol message - type. - """ - descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY] - - # If this is an _existing_ class looked up via `_concrete_class` in the - # __new__ method above, then we don't need to re-initialize anything. - existing_class = getattr(descriptor, '_concrete_class', None) - if existing_class: - assert existing_class is cls, ( - 'Duplicate `GeneratedProtocolMessageType` created for descriptor %r' - % (descriptor.full_name)) - return - - cls._decoders_by_tag = {} - if (descriptor.has_options and - descriptor.GetOptions().message_set_wire_format): - cls._decoders_by_tag[decoder.MESSAGE_SET_ITEM_TAG] = ( - decoder.MessageSetItemDecoder(descriptor), None) - - # Attach stuff to each FieldDescriptor for quick lookup later on. - for field in descriptor.fields: - _AttachFieldHelpers(cls, field) - - descriptor._concrete_class = cls # pylint: disable=protected-access - _AddEnumValues(descriptor, cls) - _AddInitMethod(descriptor, cls) - _AddPropertiesForFields(descriptor, cls) - _AddPropertiesForExtensions(descriptor, cls) - _AddStaticMethods(cls) - _AddMessageMethods(descriptor, cls) - _AddPrivateHelperMethods(descriptor, cls) - - superclass = super(GeneratedProtocolMessageType, cls) - superclass.__init__(name, bases, dictionary) - - -# Stateless helpers for GeneratedProtocolMessageType below. -# Outside clients should not access these directly. -# -# I opted not to make any of these methods on the metaclass, to make it more -# clear that I'm not really using any state there and to keep clients from -# thinking that they have direct access to these construction helpers. - - -def _PropertyName(proto_field_name): - """Returns the name of the public property attribute which - clients can use to get and (in some cases) set the value - of a protocol message field. - - Args: - proto_field_name: The protocol message field name, exactly - as it appears (or would appear) in a .proto file. - """ - # TODO(robinson): Escape Python keywords (e.g., yield), and test this support. - # nnorwitz makes my day by writing: - # """ - # FYI. See the keyword module in the stdlib. This could be as simple as: - # - # if keyword.iskeyword(proto_field_name): - # return proto_field_name + "_" - # return proto_field_name - # """ - # Kenton says: The above is a BAD IDEA. People rely on being able to use - # getattr() and setattr() to reflectively manipulate field values. If we - # rename the properties, then every such user has to also make sure to apply - # the same transformation. Note that currently if you name a field "yield", - # you can still access it just fine using getattr/setattr -- it's not even - # that cumbersome to do so. - # TODO(kenton): Remove this method entirely if/when everyone agrees with my - # position. - return proto_field_name - - -def _AddSlots(message_descriptor, dictionary): - """Adds a __slots__ entry to dictionary, containing the names of all valid - attributes for this message type. - - Args: - message_descriptor: A Descriptor instance describing this message type. - dictionary: Class dictionary to which we'll add a '__slots__' entry. - """ - dictionary['__slots__'] = ['_cached_byte_size', - '_cached_byte_size_dirty', - '_fields', - '_unknown_fields', - '_unknown_field_set', - '_is_present_in_parent', - '_listener', - '_listener_for_children', - '__weakref__', - '_oneofs'] - - -def _IsMessageSetExtension(field): - return (field.is_extension and - field.containing_type.has_options and - field.containing_type.GetOptions().message_set_wire_format and - field.type == _FieldDescriptor.TYPE_MESSAGE and - field.label == _FieldDescriptor.LABEL_OPTIONAL) - - -def _IsMapField(field): - return (field.type == _FieldDescriptor.TYPE_MESSAGE and - field.message_type.has_options and - field.message_type.GetOptions().map_entry) - - -def _IsMessageMapField(field): - value_type = field.message_type.fields_by_name['value'] - return value_type.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE - - -def _AttachFieldHelpers(cls, field_descriptor): - is_repeated = (field_descriptor.label == _FieldDescriptor.LABEL_REPEATED) - is_packable = (is_repeated and - wire_format.IsTypePackable(field_descriptor.type)) - is_proto3 = field_descriptor.containing_type.syntax == 'proto3' - if not is_packable: - is_packed = False - elif field_descriptor.containing_type.syntax == 'proto2': - is_packed = (field_descriptor.has_options and - field_descriptor.GetOptions().packed) - else: - has_packed_false = (field_descriptor.has_options and - field_descriptor.GetOptions().HasField('packed') and - field_descriptor.GetOptions().packed == False) - is_packed = not has_packed_false - is_map_entry = _IsMapField(field_descriptor) - - if is_map_entry: - field_encoder = encoder.MapEncoder(field_descriptor) - sizer = encoder.MapSizer(field_descriptor, - _IsMessageMapField(field_descriptor)) - elif _IsMessageSetExtension(field_descriptor): - field_encoder = encoder.MessageSetItemEncoder(field_descriptor.number) - sizer = encoder.MessageSetItemSizer(field_descriptor.number) - else: - field_encoder = type_checkers.TYPE_TO_ENCODER[field_descriptor.type]( - field_descriptor.number, is_repeated, is_packed) - sizer = type_checkers.TYPE_TO_SIZER[field_descriptor.type]( - field_descriptor.number, is_repeated, is_packed) - - field_descriptor._encoder = field_encoder - field_descriptor._sizer = sizer - field_descriptor._default_constructor = _DefaultValueConstructorForField( - field_descriptor) - - def AddDecoder(wiretype, is_packed): - tag_bytes = encoder.TagBytes(field_descriptor.number, wiretype) - decode_type = field_descriptor.type - if (decode_type == _FieldDescriptor.TYPE_ENUM and - type_checkers.SupportsOpenEnums(field_descriptor)): - decode_type = _FieldDescriptor.TYPE_INT32 - - oneof_descriptor = None - clear_if_default = False - if field_descriptor.containing_oneof is not None: - oneof_descriptor = field_descriptor - elif (is_proto3 and not is_repeated and - field_descriptor.cpp_type != _FieldDescriptor.CPPTYPE_MESSAGE): - clear_if_default = True - - if is_map_entry: - is_message_map = _IsMessageMapField(field_descriptor) - - field_decoder = decoder.MapDecoder( - field_descriptor, _GetInitializeDefaultForMap(field_descriptor), - is_message_map) - elif decode_type == _FieldDescriptor.TYPE_STRING: - field_decoder = decoder.StringDecoder( - field_descriptor.number, is_repeated, is_packed, - field_descriptor, field_descriptor._default_constructor, - clear_if_default) - elif field_descriptor.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - field_decoder = type_checkers.TYPE_TO_DECODER[decode_type]( - field_descriptor.number, is_repeated, is_packed, - field_descriptor, field_descriptor._default_constructor) - else: - field_decoder = type_checkers.TYPE_TO_DECODER[decode_type]( - field_descriptor.number, is_repeated, is_packed, - # pylint: disable=protected-access - field_descriptor, field_descriptor._default_constructor, - clear_if_default) - - cls._decoders_by_tag[tag_bytes] = (field_decoder, oneof_descriptor) - - AddDecoder(type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field_descriptor.type], - False) - - if is_repeated and wire_format.IsTypePackable(field_descriptor.type): - # To support wire compatibility of adding packed = true, add a decoder for - # packed values regardless of the field's options. - AddDecoder(wire_format.WIRETYPE_LENGTH_DELIMITED, True) - - -def _AddClassAttributesForNestedExtensions(descriptor, dictionary): - extensions = descriptor.extensions_by_name - for extension_name, extension_field in extensions.items(): - assert extension_name not in dictionary - dictionary[extension_name] = extension_field - - -def _AddEnumValues(descriptor, cls): - """Sets class-level attributes for all enum fields defined in this message. - - Also exporting a class-level object that can name enum values. - - Args: - descriptor: Descriptor object for this message type. - cls: Class we're constructing for this message type. - """ - for enum_type in descriptor.enum_types: - setattr(cls, enum_type.name, enum_type_wrapper.EnumTypeWrapper(enum_type)) - for enum_value in enum_type.values: - setattr(cls, enum_value.name, enum_value.number) - - -def _GetInitializeDefaultForMap(field): - if field.label != _FieldDescriptor.LABEL_REPEATED: - raise ValueError('map_entry set on non-repeated field %s' % ( - field.name)) - fields_by_name = field.message_type.fields_by_name - key_checker = type_checkers.GetTypeChecker(fields_by_name['key']) - - value_field = fields_by_name['value'] - if _IsMessageMapField(field): - def MakeMessageMapDefault(message): - return containers.MessageMap( - message._listener_for_children, value_field.message_type, key_checker, - field.message_type) - return MakeMessageMapDefault - else: - value_checker = type_checkers.GetTypeChecker(value_field) - def MakePrimitiveMapDefault(message): - return containers.ScalarMap( - message._listener_for_children, key_checker, value_checker, - field.message_type) - return MakePrimitiveMapDefault - -def _DefaultValueConstructorForField(field): - """Returns a function which returns a default value for a field. - - Args: - field: FieldDescriptor object for this field. - - The returned function has one argument: - message: Message instance containing this field, or a weakref proxy - of same. - - That function in turn returns a default value for this field. The default - value may refer back to |message| via a weak reference. - """ - - if _IsMapField(field): - return _GetInitializeDefaultForMap(field) - - if field.label == _FieldDescriptor.LABEL_REPEATED: - if field.has_default_value and field.default_value != []: - raise ValueError('Repeated field default value not empty list: %s' % ( - field.default_value)) - if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - # We can't look at _concrete_class yet since it might not have - # been set. (Depends on order in which we initialize the classes). - message_type = field.message_type - def MakeRepeatedMessageDefault(message): - return containers.RepeatedCompositeFieldContainer( - message._listener_for_children, field.message_type) - return MakeRepeatedMessageDefault - else: - type_checker = type_checkers.GetTypeChecker(field) - def MakeRepeatedScalarDefault(message): - return containers.RepeatedScalarFieldContainer( - message._listener_for_children, type_checker) - return MakeRepeatedScalarDefault - - if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - # _concrete_class may not yet be initialized. - message_type = field.message_type - def MakeSubMessageDefault(message): - assert getattr(message_type, '_concrete_class', None), ( - 'Uninitialized concrete class found for field %r (message type %r)' - % (field.full_name, message_type.full_name)) - result = message_type._concrete_class() - result._SetListener( - _OneofListener(message, field) - if field.containing_oneof is not None - else message._listener_for_children) - return result - return MakeSubMessageDefault - - def MakeScalarDefault(message): - # TODO(protobuf-team): This may be broken since there may not be - # default_value. Combine with has_default_value somehow. - return field.default_value - return MakeScalarDefault - - -def _ReraiseTypeErrorWithFieldName(message_name, field_name): - """Re-raise the currently-handled TypeError with the field name added.""" - exc = sys.exc_info()[1] - if len(exc.args) == 1 and type(exc) is TypeError: - # simple TypeError; add field name to exception message - exc = TypeError('%s for field %s.%s' % (str(exc), message_name, field_name)) - - # re-raise possibly-amended exception with original traceback: - raise exc.with_traceback(sys.exc_info()[2]) - - -def _AddInitMethod(message_descriptor, cls): - """Adds an __init__ method to cls.""" - - def _GetIntegerEnumValue(enum_type, value): - """Convert a string or integer enum value to an integer. - - If the value is a string, it is converted to the enum value in - enum_type with the same name. If the value is not a string, it's - returned as-is. (No conversion or bounds-checking is done.) - """ - if isinstance(value, str): - try: - return enum_type.values_by_name[value].number - except KeyError: - raise ValueError('Enum type %s: unknown label "%s"' % ( - enum_type.full_name, value)) - return value - - def init(self, **kwargs): - self._cached_byte_size = 0 - self._cached_byte_size_dirty = len(kwargs) > 0 - self._fields = {} - # Contains a mapping from oneof field descriptors to the descriptor - # of the currently set field in that oneof field. - self._oneofs = {} - - # _unknown_fields is () when empty for efficiency, and will be turned into - # a list if fields are added. - self._unknown_fields = () - # _unknown_field_set is None when empty for efficiency, and will be - # turned into UnknownFieldSet struct if fields are added. - self._unknown_field_set = None # pylint: disable=protected-access - self._is_present_in_parent = False - self._listener = message_listener_mod.NullMessageListener() - self._listener_for_children = _Listener(self) - for field_name, field_value in kwargs.items(): - field = _GetFieldByName(message_descriptor, field_name) - if field is None: - raise TypeError('%s() got an unexpected keyword argument "%s"' % - (message_descriptor.name, field_name)) - if field_value is None: - # field=None is the same as no field at all. - continue - if field.label == _FieldDescriptor.LABEL_REPEATED: - copy = field._default_constructor(self) - if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: # Composite - if _IsMapField(field): - if _IsMessageMapField(field): - for key in field_value: - copy[key].MergeFrom(field_value[key]) - else: - copy.update(field_value) - else: - for val in field_value: - if isinstance(val, dict): - copy.add(**val) - else: - copy.add().MergeFrom(val) - else: # Scalar - if field.cpp_type == _FieldDescriptor.CPPTYPE_ENUM: - field_value = [_GetIntegerEnumValue(field.enum_type, val) - for val in field_value] - copy.extend(field_value) - self._fields[field] = copy - elif field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - copy = field._default_constructor(self) - new_val = field_value - if isinstance(field_value, dict): - new_val = field.message_type._concrete_class(**field_value) - try: - copy.MergeFrom(new_val) - except TypeError: - _ReraiseTypeErrorWithFieldName(message_descriptor.name, field_name) - self._fields[field] = copy - else: - if field.cpp_type == _FieldDescriptor.CPPTYPE_ENUM: - field_value = _GetIntegerEnumValue(field.enum_type, field_value) - try: - setattr(self, field_name, field_value) - except TypeError: - _ReraiseTypeErrorWithFieldName(message_descriptor.name, field_name) - - init.__module__ = None - init.__doc__ = None - cls.__init__ = init - - -def _GetFieldByName(message_descriptor, field_name): - """Returns a field descriptor by field name. - - Args: - message_descriptor: A Descriptor describing all fields in message. - field_name: The name of the field to retrieve. - Returns: - The field descriptor associated with the field name. - """ - try: - return message_descriptor.fields_by_name[field_name] - except KeyError: - raise ValueError('Protocol message %s has no "%s" field.' % - (message_descriptor.name, field_name)) - - -def _AddPropertiesForFields(descriptor, cls): - """Adds properties for all fields in this protocol message type.""" - for field in descriptor.fields: - _AddPropertiesForField(field, cls) - - if descriptor.is_extendable: - # _ExtensionDict is just an adaptor with no state so we allocate a new one - # every time it is accessed. - cls.Extensions = property(lambda self: _ExtensionDict(self)) - - -def _AddPropertiesForField(field, cls): - """Adds a public property for a protocol message field. - Clients can use this property to get and (in the case - of non-repeated scalar fields) directly set the value - of a protocol message field. - - Args: - field: A FieldDescriptor for this field. - cls: The class we're constructing. - """ - # Catch it if we add other types that we should - # handle specially here. - assert _FieldDescriptor.MAX_CPPTYPE == 10 - - constant_name = field.name.upper() + '_FIELD_NUMBER' - setattr(cls, constant_name, field.number) - - if field.label == _FieldDescriptor.LABEL_REPEATED: - _AddPropertiesForRepeatedField(field, cls) - elif field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - _AddPropertiesForNonRepeatedCompositeField(field, cls) - else: - _AddPropertiesForNonRepeatedScalarField(field, cls) - - -class _FieldProperty(property): - __slots__ = ('DESCRIPTOR',) - - def __init__(self, descriptor, getter, setter, doc): - property.__init__(self, getter, setter, doc=doc) - self.DESCRIPTOR = descriptor - - -def _AddPropertiesForRepeatedField(field, cls): - """Adds a public property for a "repeated" protocol message field. Clients - can use this property to get the value of the field, which will be either a - RepeatedScalarFieldContainer or RepeatedCompositeFieldContainer (see - below). - - Note that when clients add values to these containers, we perform - type-checking in the case of repeated scalar fields, and we also set any - necessary "has" bits as a side-effect. - - Args: - field: A FieldDescriptor for this field. - cls: The class we're constructing. - """ - proto_field_name = field.name - property_name = _PropertyName(proto_field_name) - - def getter(self): - field_value = self._fields.get(field) - if field_value is None: - # Construct a new object to represent this field. - field_value = field._default_constructor(self) - - # Atomically check if another thread has preempted us and, if not, swap - # in the new object we just created. If someone has preempted us, we - # take that object and discard ours. - # WARNING: We are relying on setdefault() being atomic. This is true - # in CPython but we haven't investigated others. This warning appears - # in several other locations in this file. - field_value = self._fields.setdefault(field, field_value) - return field_value - getter.__module__ = None - getter.__doc__ = 'Getter for %s.' % proto_field_name - - # We define a setter just so we can throw an exception with a more - # helpful error message. - def setter(self, new_value): - raise AttributeError('Assignment not allowed to repeated field ' - '"%s" in protocol message object.' % proto_field_name) - - doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name - setattr(cls, property_name, _FieldProperty(field, getter, setter, doc=doc)) - - -def _AddPropertiesForNonRepeatedScalarField(field, cls): - """Adds a public property for a nonrepeated, scalar protocol message field. - Clients can use this property to get and directly set the value of the field. - Note that when the client sets the value of a field by using this property, - all necessary "has" bits are set as a side-effect, and we also perform - type-checking. - - Args: - field: A FieldDescriptor for this field. - cls: The class we're constructing. - """ - proto_field_name = field.name - property_name = _PropertyName(proto_field_name) - type_checker = type_checkers.GetTypeChecker(field) - default_value = field.default_value - is_proto3 = field.containing_type.syntax == 'proto3' - - def getter(self): - # TODO(protobuf-team): This may be broken since there may not be - # default_value. Combine with has_default_value somehow. - return self._fields.get(field, default_value) - getter.__module__ = None - getter.__doc__ = 'Getter for %s.' % proto_field_name - - clear_when_set_to_default = is_proto3 and not field.containing_oneof - - def field_setter(self, new_value): - # pylint: disable=protected-access - # Testing the value for truthiness captures all of the proto3 defaults - # (0, 0.0, enum 0, and False). - try: - new_value = type_checker.CheckValue(new_value) - except TypeError as e: - raise TypeError( - 'Cannot set %s to %.1024r: %s' % (field.full_name, new_value, e)) - if clear_when_set_to_default and not new_value: - self._fields.pop(field, None) - else: - self._fields[field] = new_value - # Check _cached_byte_size_dirty inline to improve performance, since scalar - # setters are called frequently. - if not self._cached_byte_size_dirty: - self._Modified() - - if field.containing_oneof: - def setter(self, new_value): - field_setter(self, new_value) - self._UpdateOneofState(field) - else: - setter = field_setter - - setter.__module__ = None - setter.__doc__ = 'Setter for %s.' % proto_field_name - - # Add a property to encapsulate the getter/setter. - doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name - setattr(cls, property_name, _FieldProperty(field, getter, setter, doc=doc)) - - -def _AddPropertiesForNonRepeatedCompositeField(field, cls): - """Adds a public property for a nonrepeated, composite protocol message field. - A composite field is a "group" or "message" field. - - Clients can use this property to get the value of the field, but cannot - assign to the property directly. - - Args: - field: A FieldDescriptor for this field. - cls: The class we're constructing. - """ - # TODO(robinson): Remove duplication with similar method - # for non-repeated scalars. - proto_field_name = field.name - property_name = _PropertyName(proto_field_name) - - def getter(self): - field_value = self._fields.get(field) - if field_value is None: - # Construct a new object to represent this field. - field_value = field._default_constructor(self) - - # Atomically check if another thread has preempted us and, if not, swap - # in the new object we just created. If someone has preempted us, we - # take that object and discard ours. - # WARNING: We are relying on setdefault() being atomic. This is true - # in CPython but we haven't investigated others. This warning appears - # in several other locations in this file. - field_value = self._fields.setdefault(field, field_value) - return field_value - getter.__module__ = None - getter.__doc__ = 'Getter for %s.' % proto_field_name - - # We define a setter just so we can throw an exception with a more - # helpful error message. - def setter(self, new_value): - raise AttributeError('Assignment not allowed to composite field ' - '"%s" in protocol message object.' % proto_field_name) - - # Add a property to encapsulate the getter. - doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name - setattr(cls, property_name, _FieldProperty(field, getter, setter, doc=doc)) - - -def _AddPropertiesForExtensions(descriptor, cls): - """Adds properties for all fields in this protocol message type.""" - extensions = descriptor.extensions_by_name - for extension_name, extension_field in extensions.items(): - constant_name = extension_name.upper() + '_FIELD_NUMBER' - setattr(cls, constant_name, extension_field.number) - - # TODO(amauryfa): Migrate all users of these attributes to functions like - # pool.FindExtensionByNumber(descriptor). - if descriptor.file is not None: - # TODO(amauryfa): Use cls.MESSAGE_FACTORY.pool when available. - pool = descriptor.file.pool - cls._extensions_by_number = pool._extensions_by_number[descriptor] - cls._extensions_by_name = pool._extensions_by_name[descriptor] - -def _AddStaticMethods(cls): - # TODO(robinson): This probably needs to be thread-safe(?) - def RegisterExtension(extension_handle): - extension_handle.containing_type = cls.DESCRIPTOR - # TODO(amauryfa): Use cls.MESSAGE_FACTORY.pool when available. - # pylint: disable=protected-access - cls.DESCRIPTOR.file.pool._AddExtensionDescriptor(extension_handle) - _AttachFieldHelpers(cls, extension_handle) - cls.RegisterExtension = staticmethod(RegisterExtension) - - def FromString(s): - message = cls() - message.MergeFromString(s) - return message - cls.FromString = staticmethod(FromString) - - -def _IsPresent(item): - """Given a (FieldDescriptor, value) tuple from _fields, return true if the - value should be included in the list returned by ListFields().""" - - if item[0].label == _FieldDescriptor.LABEL_REPEATED: - return bool(item[1]) - elif item[0].cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - return item[1]._is_present_in_parent - else: - return True - - -def _AddListFieldsMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - - def ListFields(self): - all_fields = [item for item in self._fields.items() if _IsPresent(item)] - all_fields.sort(key = lambda item: item[0].number) - return all_fields - - cls.ListFields = ListFields - -_PROTO3_ERROR_TEMPLATE = \ - ('Protocol message %s has no non-repeated submessage field "%s" ' - 'nor marked as optional') -_PROTO2_ERROR_TEMPLATE = 'Protocol message %s has no non-repeated field "%s"' - -def _AddHasFieldMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - - is_proto3 = (message_descriptor.syntax == "proto3") - error_msg = _PROTO3_ERROR_TEMPLATE if is_proto3 else _PROTO2_ERROR_TEMPLATE - - hassable_fields = {} - for field in message_descriptor.fields: - if field.label == _FieldDescriptor.LABEL_REPEATED: - continue - # For proto3, only submessages and fields inside a oneof have presence. - if (is_proto3 and field.cpp_type != _FieldDescriptor.CPPTYPE_MESSAGE and - not field.containing_oneof): - continue - hassable_fields[field.name] = field - - # Has methods are supported for oneof descriptors. - for oneof in message_descriptor.oneofs: - hassable_fields[oneof.name] = oneof - - def HasField(self, field_name): - try: - field = hassable_fields[field_name] - except KeyError: - raise ValueError(error_msg % (message_descriptor.full_name, field_name)) - - if isinstance(field, descriptor_mod.OneofDescriptor): - try: - return HasField(self, self._oneofs[field].name) - except KeyError: - return False - else: - if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - value = self._fields.get(field) - return value is not None and value._is_present_in_parent - else: - return field in self._fields - - cls.HasField = HasField - - -def _AddClearFieldMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - def ClearField(self, field_name): - try: - field = message_descriptor.fields_by_name[field_name] - except KeyError: - try: - field = message_descriptor.oneofs_by_name[field_name] - if field in self._oneofs: - field = self._oneofs[field] - else: - return - except KeyError: - raise ValueError('Protocol message %s has no "%s" field.' % - (message_descriptor.name, field_name)) - - if field in self._fields: - # To match the C++ implementation, we need to invalidate iterators - # for map fields when ClearField() happens. - if hasattr(self._fields[field], 'InvalidateIterators'): - self._fields[field].InvalidateIterators() - - # Note: If the field is a sub-message, its listener will still point - # at us. That's fine, because the worst than can happen is that it - # will call _Modified() and invalidate our byte size. Big deal. - del self._fields[field] - - if self._oneofs.get(field.containing_oneof, None) is field: - del self._oneofs[field.containing_oneof] - - # Always call _Modified() -- even if nothing was changed, this is - # a mutating method, and thus calling it should cause the field to become - # present in the parent message. - self._Modified() - - cls.ClearField = ClearField - - -def _AddClearExtensionMethod(cls): - """Helper for _AddMessageMethods().""" - def ClearExtension(self, extension_handle): - extension_dict._VerifyExtensionHandle(self, extension_handle) - - # Similar to ClearField(), above. - if extension_handle in self._fields: - del self._fields[extension_handle] - self._Modified() - cls.ClearExtension = ClearExtension - - -def _AddHasExtensionMethod(cls): - """Helper for _AddMessageMethods().""" - def HasExtension(self, extension_handle): - extension_dict._VerifyExtensionHandle(self, extension_handle) - if extension_handle.label == _FieldDescriptor.LABEL_REPEATED: - raise KeyError('"%s" is repeated.' % extension_handle.full_name) - - if extension_handle.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - value = self._fields.get(extension_handle) - return value is not None and value._is_present_in_parent - else: - return extension_handle in self._fields - cls.HasExtension = HasExtension - -def _InternalUnpackAny(msg): - """Unpacks Any message and returns the unpacked message. - - This internal method is different from public Any Unpack method which takes - the target message as argument. _InternalUnpackAny method does not have - target message type and need to find the message type in descriptor pool. - - Args: - msg: An Any message to be unpacked. - - Returns: - The unpacked message. - """ - # TODO(amauryfa): Don't use the factory of generated messages. - # To make Any work with custom factories, use the message factory of the - # parent message. - # pylint: disable=g-import-not-at-top - from google.protobuf import symbol_database - factory = symbol_database.Default() - - type_url = msg.type_url - - if not type_url: - return None - - # TODO(haberman): For now we just strip the hostname. Better logic will be - # required. - type_name = type_url.split('/')[-1] - descriptor = factory.pool.FindMessageTypeByName(type_name) - - if descriptor is None: - return None - - message_class = factory.GetPrototype(descriptor) - message = message_class() - - message.ParseFromString(msg.value) - return message - - -def _AddEqualsMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - def __eq__(self, other): - if (not isinstance(other, message_mod.Message) or - other.DESCRIPTOR != self.DESCRIPTOR): - return False - - if self is other: - return True - - if self.DESCRIPTOR.full_name == _AnyFullTypeName: - any_a = _InternalUnpackAny(self) - any_b = _InternalUnpackAny(other) - if any_a and any_b: - return any_a == any_b - - if not self.ListFields() == other.ListFields(): - return False - - # TODO(jieluo): Fix UnknownFieldSet to consider MessageSet extensions, - # then use it for the comparison. - unknown_fields = list(self._unknown_fields) - unknown_fields.sort() - other_unknown_fields = list(other._unknown_fields) - other_unknown_fields.sort() - return unknown_fields == other_unknown_fields - - cls.__eq__ = __eq__ - - -def _AddStrMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - def __str__(self): - return text_format.MessageToString(self) - cls.__str__ = __str__ - - -def _AddReprMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - def __repr__(self): - return text_format.MessageToString(self) - cls.__repr__ = __repr__ - - -def _AddUnicodeMethod(unused_message_descriptor, cls): - """Helper for _AddMessageMethods().""" - - def __unicode__(self): - return text_format.MessageToString(self, as_utf8=True).decode('utf-8') - cls.__unicode__ = __unicode__ - - -def _BytesForNonRepeatedElement(value, field_number, field_type): - """Returns the number of bytes needed to serialize a non-repeated element. - The returned byte count includes space for tag information and any - other additional space associated with serializing value. - - Args: - value: Value we're serializing. - field_number: Field number of this value. (Since the field number - is stored as part of a varint-encoded tag, this has an impact - on the total bytes required to serialize the value). - field_type: The type of the field. One of the TYPE_* constants - within FieldDescriptor. - """ - try: - fn = type_checkers.TYPE_TO_BYTE_SIZE_FN[field_type] - return fn(field_number, value) - except KeyError: - raise message_mod.EncodeError('Unrecognized field type: %d' % field_type) - - -def _AddByteSizeMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - - def ByteSize(self): - if not self._cached_byte_size_dirty: - return self._cached_byte_size - - size = 0 - descriptor = self.DESCRIPTOR - if descriptor.GetOptions().map_entry: - # Fields of map entry should always be serialized. - size = descriptor.fields_by_name['key']._sizer(self.key) - size += descriptor.fields_by_name['value']._sizer(self.value) - else: - for field_descriptor, field_value in self.ListFields(): - size += field_descriptor._sizer(field_value) - for tag_bytes, value_bytes in self._unknown_fields: - size += len(tag_bytes) + len(value_bytes) - - self._cached_byte_size = size - self._cached_byte_size_dirty = False - self._listener_for_children.dirty = False - return size - - cls.ByteSize = ByteSize - - -def _AddSerializeToStringMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - - def SerializeToString(self, **kwargs): - # Check if the message has all of its required fields set. - if not self.IsInitialized(): - raise message_mod.EncodeError( - 'Message %s is missing required fields: %s' % ( - self.DESCRIPTOR.full_name, ','.join(self.FindInitializationErrors()))) - return self.SerializePartialToString(**kwargs) - cls.SerializeToString = SerializeToString - - -def _AddSerializePartialToStringMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - - def SerializePartialToString(self, **kwargs): - out = BytesIO() - self._InternalSerialize(out.write, **kwargs) - return out.getvalue() - cls.SerializePartialToString = SerializePartialToString - - def InternalSerialize(self, write_bytes, deterministic=None): - if deterministic is None: - deterministic = ( - api_implementation.IsPythonDefaultSerializationDeterministic()) - else: - deterministic = bool(deterministic) - - descriptor = self.DESCRIPTOR - if descriptor.GetOptions().map_entry: - # Fields of map entry should always be serialized. - descriptor.fields_by_name['key']._encoder( - write_bytes, self.key, deterministic) - descriptor.fields_by_name['value']._encoder( - write_bytes, self.value, deterministic) - else: - for field_descriptor, field_value in self.ListFields(): - field_descriptor._encoder(write_bytes, field_value, deterministic) - for tag_bytes, value_bytes in self._unknown_fields: - write_bytes(tag_bytes) - write_bytes(value_bytes) - cls._InternalSerialize = InternalSerialize - - -def _AddMergeFromStringMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - def MergeFromString(self, serialized): - serialized = memoryview(serialized) - length = len(serialized) - try: - if self._InternalParse(serialized, 0, length) != length: - # The only reason _InternalParse would return early is if it - # encountered an end-group tag. - raise message_mod.DecodeError('Unexpected end-group tag.') - except (IndexError, TypeError): - # Now ord(buf[p:p+1]) == ord('') gets TypeError. - raise message_mod.DecodeError('Truncated message.') - except struct.error as e: - raise message_mod.DecodeError(e) - return length # Return this for legacy reasons. - cls.MergeFromString = MergeFromString - - local_ReadTag = decoder.ReadTag - local_SkipField = decoder.SkipField - decoders_by_tag = cls._decoders_by_tag - - def InternalParse(self, buffer, pos, end): - """Create a message from serialized bytes. - - Args: - self: Message, instance of the proto message object. - buffer: memoryview of the serialized data. - pos: int, position to start in the serialized data. - end: int, end position of the serialized data. - - Returns: - Message object. - """ - # Guard against internal misuse, since this function is called internally - # quite extensively, and its easy to accidentally pass bytes. - assert isinstance(buffer, memoryview) - self._Modified() - field_dict = self._fields - # pylint: disable=protected-access - unknown_field_set = self._unknown_field_set - while pos != end: - (tag_bytes, new_pos) = local_ReadTag(buffer, pos) - field_decoder, field_desc = decoders_by_tag.get(tag_bytes, (None, None)) - if field_decoder is None: - if not self._unknown_fields: # pylint: disable=protected-access - self._unknown_fields = [] # pylint: disable=protected-access - if unknown_field_set is None: - # pylint: disable=protected-access - self._unknown_field_set = containers.UnknownFieldSet() - # pylint: disable=protected-access - unknown_field_set = self._unknown_field_set - # pylint: disable=protected-access - (tag, _) = decoder._DecodeVarint(tag_bytes, 0) - field_number, wire_type = wire_format.UnpackTag(tag) - if field_number == 0: - raise message_mod.DecodeError('Field number 0 is illegal.') - # TODO(jieluo): remove old_pos. - old_pos = new_pos - (data, new_pos) = decoder._DecodeUnknownField( - buffer, new_pos, wire_type) # pylint: disable=protected-access - if new_pos == -1: - return pos - # pylint: disable=protected-access - unknown_field_set._add(field_number, wire_type, data) - # TODO(jieluo): remove _unknown_fields. - new_pos = local_SkipField(buffer, old_pos, end, tag_bytes) - if new_pos == -1: - return pos - self._unknown_fields.append( - (tag_bytes, buffer[old_pos:new_pos].tobytes())) - pos = new_pos - else: - pos = field_decoder(buffer, new_pos, end, self, field_dict) - if field_desc: - self._UpdateOneofState(field_desc) - return pos - cls._InternalParse = InternalParse - - -def _AddIsInitializedMethod(message_descriptor, cls): - """Adds the IsInitialized and FindInitializationError methods to the - protocol message class.""" - - required_fields = [field for field in message_descriptor.fields - if field.label == _FieldDescriptor.LABEL_REQUIRED] - - def IsInitialized(self, errors=None): - """Checks if all required fields of a message are set. - - Args: - errors: A list which, if provided, will be populated with the field - paths of all missing required fields. - - Returns: - True iff the specified message has all required fields set. - """ - - # Performance is critical so we avoid HasField() and ListFields(). - - for field in required_fields: - if (field not in self._fields or - (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and - not self._fields[field]._is_present_in_parent)): - if errors is not None: - errors.extend(self.FindInitializationErrors()) - return False - - for field, value in list(self._fields.items()): # dict can change size! - if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - if field.label == _FieldDescriptor.LABEL_REPEATED: - if (field.message_type.has_options and - field.message_type.GetOptions().map_entry): - continue - for element in value: - if not element.IsInitialized(): - if errors is not None: - errors.extend(self.FindInitializationErrors()) - return False - elif value._is_present_in_parent and not value.IsInitialized(): - if errors is not None: - errors.extend(self.FindInitializationErrors()) - return False - - return True - - cls.IsInitialized = IsInitialized - - def FindInitializationErrors(self): - """Finds required fields which are not initialized. - - Returns: - A list of strings. Each string is a path to an uninitialized field from - the top-level message, e.g. "foo.bar[5].baz". - """ - - errors = [] # simplify things - - for field in required_fields: - if not self.HasField(field.name): - errors.append(field.name) - - for field, value in self.ListFields(): - if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - if field.is_extension: - name = '(%s)' % field.full_name - else: - name = field.name - - if _IsMapField(field): - if _IsMessageMapField(field): - for key in value: - element = value[key] - prefix = '%s[%s].' % (name, key) - sub_errors = element.FindInitializationErrors() - errors += [prefix + error for error in sub_errors] - else: - # ScalarMaps can't have any initialization errors. - pass - elif field.label == _FieldDescriptor.LABEL_REPEATED: - for i in range(len(value)): - element = value[i] - prefix = '%s[%d].' % (name, i) - sub_errors = element.FindInitializationErrors() - errors += [prefix + error for error in sub_errors] - else: - prefix = name + '.' - sub_errors = value.FindInitializationErrors() - errors += [prefix + error for error in sub_errors] - - return errors - - cls.FindInitializationErrors = FindInitializationErrors - - -def _FullyQualifiedClassName(klass): - module = klass.__module__ - name = getattr(klass, '__qualname__', klass.__name__) - if module in (None, 'builtins', '__builtin__'): - return name - return module + '.' + name - - -def _AddMergeFromMethod(cls): - LABEL_REPEATED = _FieldDescriptor.LABEL_REPEATED - CPPTYPE_MESSAGE = _FieldDescriptor.CPPTYPE_MESSAGE - - def MergeFrom(self, msg): - if not isinstance(msg, cls): - raise TypeError( - 'Parameter to MergeFrom() must be instance of same class: ' - 'expected %s got %s.' % (_FullyQualifiedClassName(cls), - _FullyQualifiedClassName(msg.__class__))) - - assert msg is not self - self._Modified() - - fields = self._fields - - for field, value in msg._fields.items(): - if field.label == LABEL_REPEATED: - field_value = fields.get(field) - if field_value is None: - # Construct a new object to represent this field. - field_value = field._default_constructor(self) - fields[field] = field_value - field_value.MergeFrom(value) - elif field.cpp_type == CPPTYPE_MESSAGE: - if value._is_present_in_parent: - field_value = fields.get(field) - if field_value is None: - # Construct a new object to represent this field. - field_value = field._default_constructor(self) - fields[field] = field_value - field_value.MergeFrom(value) - else: - self._fields[field] = value - if field.containing_oneof: - self._UpdateOneofState(field) - - if msg._unknown_fields: - if not self._unknown_fields: - self._unknown_fields = [] - self._unknown_fields.extend(msg._unknown_fields) - # pylint: disable=protected-access - if self._unknown_field_set is None: - self._unknown_field_set = containers.UnknownFieldSet() - self._unknown_field_set._extend(msg._unknown_field_set) - - cls.MergeFrom = MergeFrom - - -def _AddWhichOneofMethod(message_descriptor, cls): - def WhichOneof(self, oneof_name): - """Returns the name of the currently set field inside a oneof, or None.""" - try: - field = message_descriptor.oneofs_by_name[oneof_name] - except KeyError: - raise ValueError( - 'Protocol message has no oneof "%s" field.' % oneof_name) - - nested_field = self._oneofs.get(field, None) - if nested_field is not None and self.HasField(nested_field.name): - return nested_field.name - else: - return None - - cls.WhichOneof = WhichOneof - - -def _Clear(self): - # Clear fields. - self._fields = {} - self._unknown_fields = () - # pylint: disable=protected-access - if self._unknown_field_set is not None: - self._unknown_field_set._clear() - self._unknown_field_set = None - - self._oneofs = {} - self._Modified() - - -def _UnknownFields(self): - if self._unknown_field_set is None: # pylint: disable=protected-access - # pylint: disable=protected-access - self._unknown_field_set = containers.UnknownFieldSet() - return self._unknown_field_set # pylint: disable=protected-access - - -def _DiscardUnknownFields(self): - self._unknown_fields = [] - self._unknown_field_set = None # pylint: disable=protected-access - for field, value in self.ListFields(): - if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - if _IsMapField(field): - if _IsMessageMapField(field): - for key in value: - value[key].DiscardUnknownFields() - elif field.label == _FieldDescriptor.LABEL_REPEATED: - for sub_message in value: - sub_message.DiscardUnknownFields() - else: - value.DiscardUnknownFields() - - -def _SetListener(self, listener): - if listener is None: - self._listener = message_listener_mod.NullMessageListener() - else: - self._listener = listener - - -def _AddMessageMethods(message_descriptor, cls): - """Adds implementations of all Message methods to cls.""" - _AddListFieldsMethod(message_descriptor, cls) - _AddHasFieldMethod(message_descriptor, cls) - _AddClearFieldMethod(message_descriptor, cls) - if message_descriptor.is_extendable: - _AddClearExtensionMethod(cls) - _AddHasExtensionMethod(cls) - _AddEqualsMethod(message_descriptor, cls) - _AddStrMethod(message_descriptor, cls) - _AddReprMethod(message_descriptor, cls) - _AddUnicodeMethod(message_descriptor, cls) - _AddByteSizeMethod(message_descriptor, cls) - _AddSerializeToStringMethod(message_descriptor, cls) - _AddSerializePartialToStringMethod(message_descriptor, cls) - _AddMergeFromStringMethod(message_descriptor, cls) - _AddIsInitializedMethod(message_descriptor, cls) - _AddMergeFromMethod(cls) - _AddWhichOneofMethod(message_descriptor, cls) - # Adds methods which do not depend on cls. - cls.Clear = _Clear - cls.UnknownFields = _UnknownFields - cls.DiscardUnknownFields = _DiscardUnknownFields - cls._SetListener = _SetListener - - -def _AddPrivateHelperMethods(message_descriptor, cls): - """Adds implementation of private helper methods to cls.""" - - def Modified(self): - """Sets the _cached_byte_size_dirty bit to true, - and propagates this to our listener iff this was a state change. - """ - - # Note: Some callers check _cached_byte_size_dirty before calling - # _Modified() as an extra optimization. So, if this method is ever - # changed such that it does stuff even when _cached_byte_size_dirty is - # already true, the callers need to be updated. - if not self._cached_byte_size_dirty: - self._cached_byte_size_dirty = True - self._listener_for_children.dirty = True - self._is_present_in_parent = True - self._listener.Modified() - - def _UpdateOneofState(self, field): - """Sets field as the active field in its containing oneof. - - Will also delete currently active field in the oneof, if it is different - from the argument. Does not mark the message as modified. - """ - other_field = self._oneofs.setdefault(field.containing_oneof, field) - if other_field is not field: - del self._fields[other_field] - self._oneofs[field.containing_oneof] = field - - cls._Modified = Modified - cls.SetInParent = Modified - cls._UpdateOneofState = _UpdateOneofState - - -class _Listener(object): - - """MessageListener implementation that a parent message registers with its - child message. - - In order to support semantics like: - - foo.bar.baz.qux = 23 - assert foo.HasField('bar') - - ...child objects must have back references to their parents. - This helper class is at the heart of this support. - """ - - def __init__(self, parent_message): - """Args: - parent_message: The message whose _Modified() method we should call when - we receive Modified() messages. - """ - # This listener establishes a back reference from a child (contained) object - # to its parent (containing) object. We make this a weak reference to avoid - # creating cyclic garbage when the client finishes with the 'parent' object - # in the tree. - if isinstance(parent_message, weakref.ProxyType): - self._parent_message_weakref = parent_message - else: - self._parent_message_weakref = weakref.proxy(parent_message) - - # As an optimization, we also indicate directly on the listener whether - # or not the parent message is dirty. This way we can avoid traversing - # up the tree in the common case. - self.dirty = False - - def Modified(self): - if self.dirty: - return - try: - # Propagate the signal to our parents iff this is the first field set. - self._parent_message_weakref._Modified() - except ReferenceError: - # We can get here if a client has kept a reference to a child object, - # and is now setting a field on it, but the child's parent has been - # garbage-collected. This is not an error. - pass - - -class _OneofListener(_Listener): - """Special listener implementation for setting composite oneof fields.""" - - def __init__(self, parent_message, field): - """Args: - parent_message: The message whose _Modified() method we should call when - we receive Modified() messages. - field: The descriptor of the field being set in the parent message. - """ - super(_OneofListener, self).__init__(parent_message) - self._field = field - - def Modified(self): - """Also updates the state of the containing oneof in the parent message.""" - try: - self._parent_message_weakref._UpdateOneofState(self._field) - super(_OneofListener, self).Modified() - except ReferenceError: - pass diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/type_checkers.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/type_checkers.py deleted file mode 100644 index a53e71fe8e..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/type_checkers.py +++ /dev/null @@ -1,435 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Provides type checking routines. - -This module defines type checking utilities in the forms of dictionaries: - -VALUE_CHECKERS: A dictionary of field types and a value validation object. -TYPE_TO_BYTE_SIZE_FN: A dictionary with field types and a size computing - function. -TYPE_TO_SERIALIZE_METHOD: A dictionary with field types and serialization - function. -FIELD_TYPE_TO_WIRE_TYPE: A dictionary with field typed and their - corresponding wire types. -TYPE_TO_DESERIALIZE_METHOD: A dictionary with field types and deserialization - function. -""" - -__author__ = 'robinson@google.com (Will Robinson)' - -import ctypes -import numbers - -from google.protobuf.internal import decoder -from google.protobuf.internal import encoder -from google.protobuf.internal import wire_format -from google.protobuf import descriptor - -_FieldDescriptor = descriptor.FieldDescriptor - - -def TruncateToFourByteFloat(original): - return ctypes.c_float(original).value - - -def ToShortestFloat(original): - """Returns the shortest float that has same value in wire.""" - # All 4 byte floats have between 6 and 9 significant digits, so we - # start with 6 as the lower bound. - # It has to be iterative because use '.9g' directly can not get rid - # of the noises for most values. For example if set a float_field=0.9 - # use '.9g' will print 0.899999976. - precision = 6 - rounded = float('{0:.{1}g}'.format(original, precision)) - while TruncateToFourByteFloat(rounded) != original: - precision += 1 - rounded = float('{0:.{1}g}'.format(original, precision)) - return rounded - - -def SupportsOpenEnums(field_descriptor): - return field_descriptor.containing_type.syntax == 'proto3' - - -def GetTypeChecker(field): - """Returns a type checker for a message field of the specified types. - - Args: - field: FieldDescriptor object for this field. - - Returns: - An instance of TypeChecker which can be used to verify the types - of values assigned to a field of the specified type. - """ - if (field.cpp_type == _FieldDescriptor.CPPTYPE_STRING and - field.type == _FieldDescriptor.TYPE_STRING): - return UnicodeValueChecker() - if field.cpp_type == _FieldDescriptor.CPPTYPE_ENUM: - if SupportsOpenEnums(field): - # When open enums are supported, any int32 can be assigned. - return _VALUE_CHECKERS[_FieldDescriptor.CPPTYPE_INT32] - else: - return EnumValueChecker(field.enum_type) - return _VALUE_CHECKERS[field.cpp_type] - - -# None of the typecheckers below make any attempt to guard against people -# subclassing builtin types and doing weird things. We're not trying to -# protect against malicious clients here, just people accidentally shooting -# themselves in the foot in obvious ways. -class TypeChecker(object): - - """Type checker used to catch type errors as early as possible - when the client is setting scalar fields in protocol messages. - """ - - def __init__(self, *acceptable_types): - self._acceptable_types = acceptable_types - - def CheckValue(self, proposed_value): - """Type check the provided value and return it. - - The returned value might have been normalized to another type. - """ - if not isinstance(proposed_value, self._acceptable_types): - message = ('%.1024r has type %s, but expected one of: %s' % - (proposed_value, type(proposed_value), self._acceptable_types)) - raise TypeError(message) - return proposed_value - - -class TypeCheckerWithDefault(TypeChecker): - - def __init__(self, default_value, *acceptable_types): - TypeChecker.__init__(self, *acceptable_types) - self._default_value = default_value - - def DefaultValue(self): - return self._default_value - - -class BoolValueChecker(object): - """Type checker used for bool fields.""" - - def CheckValue(self, proposed_value): - if not hasattr(proposed_value, '__index__') or ( - type(proposed_value).__module__ == 'numpy' and - type(proposed_value).__name__ == 'ndarray'): - message = ('%.1024r has type %s, but expected one of: %s' % - (proposed_value, type(proposed_value), (bool, int))) - raise TypeError(message) - return bool(proposed_value) - - def DefaultValue(self): - return False - - -# IntValueChecker and its subclasses perform integer type-checks -# and bounds-checks. -class IntValueChecker(object): - - """Checker used for integer fields. Performs type-check and range check.""" - - def CheckValue(self, proposed_value): - if not hasattr(proposed_value, '__index__') or ( - type(proposed_value).__module__ == 'numpy' and - type(proposed_value).__name__ == 'ndarray'): - message = ('%.1024r has type %s, but expected one of: %s' % - (proposed_value, type(proposed_value), (int,))) - raise TypeError(message) - - if not self._MIN <= int(proposed_value) <= self._MAX: - raise ValueError('Value out of range: %d' % proposed_value) - # We force all values to int to make alternate implementations where the - # distinction is more significant (e.g. the C++ implementation) simpler. - proposed_value = int(proposed_value) - return proposed_value - - def DefaultValue(self): - return 0 - - -class EnumValueChecker(object): - - """Checker used for enum fields. Performs type-check and range check.""" - - def __init__(self, enum_type): - self._enum_type = enum_type - - def CheckValue(self, proposed_value): - if not isinstance(proposed_value, numbers.Integral): - message = ('%.1024r has type %s, but expected one of: %s' % - (proposed_value, type(proposed_value), (int,))) - raise TypeError(message) - if int(proposed_value) not in self._enum_type.values_by_number: - raise ValueError('Unknown enum value: %d' % proposed_value) - return proposed_value - - def DefaultValue(self): - return self._enum_type.values[0].number - - -class UnicodeValueChecker(object): - - """Checker used for string fields. - - Always returns a unicode value, even if the input is of type str. - """ - - def CheckValue(self, proposed_value): - if not isinstance(proposed_value, (bytes, str)): - message = ('%.1024r has type %s, but expected one of: %s' % - (proposed_value, type(proposed_value), (bytes, str))) - raise TypeError(message) - - # If the value is of type 'bytes' make sure that it is valid UTF-8 data. - if isinstance(proposed_value, bytes): - try: - proposed_value = proposed_value.decode('utf-8') - except UnicodeDecodeError: - raise ValueError('%.1024r has type bytes, but isn\'t valid UTF-8 ' - 'encoding. Non-UTF-8 strings must be converted to ' - 'unicode objects before being added.' % - (proposed_value)) - else: - try: - proposed_value.encode('utf8') - except UnicodeEncodeError: - raise ValueError('%.1024r isn\'t a valid unicode string and ' - 'can\'t be encoded in UTF-8.'% - (proposed_value)) - - return proposed_value - - def DefaultValue(self): - return u"" - - -class Int32ValueChecker(IntValueChecker): - # We're sure to use ints instead of longs here since comparison may be more - # efficient. - _MIN = -2147483648 - _MAX = 2147483647 - - -class Uint32ValueChecker(IntValueChecker): - _MIN = 0 - _MAX = (1 << 32) - 1 - - -class Int64ValueChecker(IntValueChecker): - _MIN = -(1 << 63) - _MAX = (1 << 63) - 1 - - -class Uint64ValueChecker(IntValueChecker): - _MIN = 0 - _MAX = (1 << 64) - 1 - - -# The max 4 bytes float is about 3.4028234663852886e+38 -_FLOAT_MAX = float.fromhex('0x1.fffffep+127') -_FLOAT_MIN = -_FLOAT_MAX -_INF = float('inf') -_NEG_INF = float('-inf') - - -class DoubleValueChecker(object): - """Checker used for double fields. - - Performs type-check and range check. - """ - - def CheckValue(self, proposed_value): - """Check and convert proposed_value to float.""" - if (not hasattr(proposed_value, '__float__') and - not hasattr(proposed_value, '__index__')) or ( - type(proposed_value).__module__ == 'numpy' and - type(proposed_value).__name__ == 'ndarray'): - message = ('%.1024r has type %s, but expected one of: int, float' % - (proposed_value, type(proposed_value))) - raise TypeError(message) - return float(proposed_value) - - def DefaultValue(self): - return 0.0 - - -class FloatValueChecker(DoubleValueChecker): - """Checker used for float fields. - - Performs type-check and range check. - - Values exceeding a 32-bit float will be converted to inf/-inf. - """ - - def CheckValue(self, proposed_value): - """Check and convert proposed_value to float.""" - converted_value = super().CheckValue(proposed_value) - # This inf rounding matches the C++ proto SafeDoubleToFloat logic. - if converted_value > _FLOAT_MAX: - return _INF - if converted_value < _FLOAT_MIN: - return _NEG_INF - - return TruncateToFourByteFloat(converted_value) - -# Type-checkers for all scalar CPPTYPEs. -_VALUE_CHECKERS = { - _FieldDescriptor.CPPTYPE_INT32: Int32ValueChecker(), - _FieldDescriptor.CPPTYPE_INT64: Int64ValueChecker(), - _FieldDescriptor.CPPTYPE_UINT32: Uint32ValueChecker(), - _FieldDescriptor.CPPTYPE_UINT64: Uint64ValueChecker(), - _FieldDescriptor.CPPTYPE_DOUBLE: DoubleValueChecker(), - _FieldDescriptor.CPPTYPE_FLOAT: FloatValueChecker(), - _FieldDescriptor.CPPTYPE_BOOL: BoolValueChecker(), - _FieldDescriptor.CPPTYPE_STRING: TypeCheckerWithDefault(b'', bytes), -} - - -# Map from field type to a function F, such that F(field_num, value) -# gives the total byte size for a value of the given type. This -# byte size includes tag information and any other additional space -# associated with serializing "value". -TYPE_TO_BYTE_SIZE_FN = { - _FieldDescriptor.TYPE_DOUBLE: wire_format.DoubleByteSize, - _FieldDescriptor.TYPE_FLOAT: wire_format.FloatByteSize, - _FieldDescriptor.TYPE_INT64: wire_format.Int64ByteSize, - _FieldDescriptor.TYPE_UINT64: wire_format.UInt64ByteSize, - _FieldDescriptor.TYPE_INT32: wire_format.Int32ByteSize, - _FieldDescriptor.TYPE_FIXED64: wire_format.Fixed64ByteSize, - _FieldDescriptor.TYPE_FIXED32: wire_format.Fixed32ByteSize, - _FieldDescriptor.TYPE_BOOL: wire_format.BoolByteSize, - _FieldDescriptor.TYPE_STRING: wire_format.StringByteSize, - _FieldDescriptor.TYPE_GROUP: wire_format.GroupByteSize, - _FieldDescriptor.TYPE_MESSAGE: wire_format.MessageByteSize, - _FieldDescriptor.TYPE_BYTES: wire_format.BytesByteSize, - _FieldDescriptor.TYPE_UINT32: wire_format.UInt32ByteSize, - _FieldDescriptor.TYPE_ENUM: wire_format.EnumByteSize, - _FieldDescriptor.TYPE_SFIXED32: wire_format.SFixed32ByteSize, - _FieldDescriptor.TYPE_SFIXED64: wire_format.SFixed64ByteSize, - _FieldDescriptor.TYPE_SINT32: wire_format.SInt32ByteSize, - _FieldDescriptor.TYPE_SINT64: wire_format.SInt64ByteSize - } - - -# Maps from field types to encoder constructors. -TYPE_TO_ENCODER = { - _FieldDescriptor.TYPE_DOUBLE: encoder.DoubleEncoder, - _FieldDescriptor.TYPE_FLOAT: encoder.FloatEncoder, - _FieldDescriptor.TYPE_INT64: encoder.Int64Encoder, - _FieldDescriptor.TYPE_UINT64: encoder.UInt64Encoder, - _FieldDescriptor.TYPE_INT32: encoder.Int32Encoder, - _FieldDescriptor.TYPE_FIXED64: encoder.Fixed64Encoder, - _FieldDescriptor.TYPE_FIXED32: encoder.Fixed32Encoder, - _FieldDescriptor.TYPE_BOOL: encoder.BoolEncoder, - _FieldDescriptor.TYPE_STRING: encoder.StringEncoder, - _FieldDescriptor.TYPE_GROUP: encoder.GroupEncoder, - _FieldDescriptor.TYPE_MESSAGE: encoder.MessageEncoder, - _FieldDescriptor.TYPE_BYTES: encoder.BytesEncoder, - _FieldDescriptor.TYPE_UINT32: encoder.UInt32Encoder, - _FieldDescriptor.TYPE_ENUM: encoder.EnumEncoder, - _FieldDescriptor.TYPE_SFIXED32: encoder.SFixed32Encoder, - _FieldDescriptor.TYPE_SFIXED64: encoder.SFixed64Encoder, - _FieldDescriptor.TYPE_SINT32: encoder.SInt32Encoder, - _FieldDescriptor.TYPE_SINT64: encoder.SInt64Encoder, - } - - -# Maps from field types to sizer constructors. -TYPE_TO_SIZER = { - _FieldDescriptor.TYPE_DOUBLE: encoder.DoubleSizer, - _FieldDescriptor.TYPE_FLOAT: encoder.FloatSizer, - _FieldDescriptor.TYPE_INT64: encoder.Int64Sizer, - _FieldDescriptor.TYPE_UINT64: encoder.UInt64Sizer, - _FieldDescriptor.TYPE_INT32: encoder.Int32Sizer, - _FieldDescriptor.TYPE_FIXED64: encoder.Fixed64Sizer, - _FieldDescriptor.TYPE_FIXED32: encoder.Fixed32Sizer, - _FieldDescriptor.TYPE_BOOL: encoder.BoolSizer, - _FieldDescriptor.TYPE_STRING: encoder.StringSizer, - _FieldDescriptor.TYPE_GROUP: encoder.GroupSizer, - _FieldDescriptor.TYPE_MESSAGE: encoder.MessageSizer, - _FieldDescriptor.TYPE_BYTES: encoder.BytesSizer, - _FieldDescriptor.TYPE_UINT32: encoder.UInt32Sizer, - _FieldDescriptor.TYPE_ENUM: encoder.EnumSizer, - _FieldDescriptor.TYPE_SFIXED32: encoder.SFixed32Sizer, - _FieldDescriptor.TYPE_SFIXED64: encoder.SFixed64Sizer, - _FieldDescriptor.TYPE_SINT32: encoder.SInt32Sizer, - _FieldDescriptor.TYPE_SINT64: encoder.SInt64Sizer, - } - - -# Maps from field type to a decoder constructor. -TYPE_TO_DECODER = { - _FieldDescriptor.TYPE_DOUBLE: decoder.DoubleDecoder, - _FieldDescriptor.TYPE_FLOAT: decoder.FloatDecoder, - _FieldDescriptor.TYPE_INT64: decoder.Int64Decoder, - _FieldDescriptor.TYPE_UINT64: decoder.UInt64Decoder, - _FieldDescriptor.TYPE_INT32: decoder.Int32Decoder, - _FieldDescriptor.TYPE_FIXED64: decoder.Fixed64Decoder, - _FieldDescriptor.TYPE_FIXED32: decoder.Fixed32Decoder, - _FieldDescriptor.TYPE_BOOL: decoder.BoolDecoder, - _FieldDescriptor.TYPE_STRING: decoder.StringDecoder, - _FieldDescriptor.TYPE_GROUP: decoder.GroupDecoder, - _FieldDescriptor.TYPE_MESSAGE: decoder.MessageDecoder, - _FieldDescriptor.TYPE_BYTES: decoder.BytesDecoder, - _FieldDescriptor.TYPE_UINT32: decoder.UInt32Decoder, - _FieldDescriptor.TYPE_ENUM: decoder.EnumDecoder, - _FieldDescriptor.TYPE_SFIXED32: decoder.SFixed32Decoder, - _FieldDescriptor.TYPE_SFIXED64: decoder.SFixed64Decoder, - _FieldDescriptor.TYPE_SINT32: decoder.SInt32Decoder, - _FieldDescriptor.TYPE_SINT64: decoder.SInt64Decoder, - } - -# Maps from field type to expected wiretype. -FIELD_TYPE_TO_WIRE_TYPE = { - _FieldDescriptor.TYPE_DOUBLE: wire_format.WIRETYPE_FIXED64, - _FieldDescriptor.TYPE_FLOAT: wire_format.WIRETYPE_FIXED32, - _FieldDescriptor.TYPE_INT64: wire_format.WIRETYPE_VARINT, - _FieldDescriptor.TYPE_UINT64: wire_format.WIRETYPE_VARINT, - _FieldDescriptor.TYPE_INT32: wire_format.WIRETYPE_VARINT, - _FieldDescriptor.TYPE_FIXED64: wire_format.WIRETYPE_FIXED64, - _FieldDescriptor.TYPE_FIXED32: wire_format.WIRETYPE_FIXED32, - _FieldDescriptor.TYPE_BOOL: wire_format.WIRETYPE_VARINT, - _FieldDescriptor.TYPE_STRING: - wire_format.WIRETYPE_LENGTH_DELIMITED, - _FieldDescriptor.TYPE_GROUP: wire_format.WIRETYPE_START_GROUP, - _FieldDescriptor.TYPE_MESSAGE: - wire_format.WIRETYPE_LENGTH_DELIMITED, - _FieldDescriptor.TYPE_BYTES: - wire_format.WIRETYPE_LENGTH_DELIMITED, - _FieldDescriptor.TYPE_UINT32: wire_format.WIRETYPE_VARINT, - _FieldDescriptor.TYPE_ENUM: wire_format.WIRETYPE_VARINT, - _FieldDescriptor.TYPE_SFIXED32: wire_format.WIRETYPE_FIXED32, - _FieldDescriptor.TYPE_SFIXED64: wire_format.WIRETYPE_FIXED64, - _FieldDescriptor.TYPE_SINT32: wire_format.WIRETYPE_VARINT, - _FieldDescriptor.TYPE_SINT64: wire_format.WIRETYPE_VARINT, - } diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/well_known_types.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/well_known_types.py deleted file mode 100644 index b581ab750a..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/well_known_types.py +++ /dev/null @@ -1,878 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Contains well known classes. - -This files defines well known classes which need extra maintenance including: - - Any - - Duration - - FieldMask - - Struct - - Timestamp -""" - -__author__ = 'jieluo@google.com (Jie Luo)' - -import calendar -import collections.abc -import datetime - -from google.protobuf.descriptor import FieldDescriptor - -_TIMESTAMPFOMAT = '%Y-%m-%dT%H:%M:%S' -_NANOS_PER_SECOND = 1000000000 -_NANOS_PER_MILLISECOND = 1000000 -_NANOS_PER_MICROSECOND = 1000 -_MILLIS_PER_SECOND = 1000 -_MICROS_PER_SECOND = 1000000 -_SECONDS_PER_DAY = 24 * 3600 -_DURATION_SECONDS_MAX = 315576000000 - - -class Any(object): - """Class for Any Message type.""" - - __slots__ = () - - def Pack(self, msg, type_url_prefix='type.googleapis.com/', - deterministic=None): - """Packs the specified message into current Any message.""" - if len(type_url_prefix) < 1 or type_url_prefix[-1] != '/': - self.type_url = '%s/%s' % (type_url_prefix, msg.DESCRIPTOR.full_name) - else: - self.type_url = '%s%s' % (type_url_prefix, msg.DESCRIPTOR.full_name) - self.value = msg.SerializeToString(deterministic=deterministic) - - def Unpack(self, msg): - """Unpacks the current Any message into specified message.""" - descriptor = msg.DESCRIPTOR - if not self.Is(descriptor): - return False - msg.ParseFromString(self.value) - return True - - def TypeName(self): - """Returns the protobuf type name of the inner message.""" - # Only last part is to be used: b/25630112 - return self.type_url.split('/')[-1] - - def Is(self, descriptor): - """Checks if this Any represents the given protobuf type.""" - return '/' in self.type_url and self.TypeName() == descriptor.full_name - - -_EPOCH_DATETIME_NAIVE = datetime.datetime.utcfromtimestamp(0) -_EPOCH_DATETIME_AWARE = datetime.datetime.fromtimestamp( - 0, tz=datetime.timezone.utc) - - -class Timestamp(object): - """Class for Timestamp message type.""" - - __slots__ = () - - def ToJsonString(self): - """Converts Timestamp to RFC 3339 date string format. - - Returns: - A string converted from timestamp. The string is always Z-normalized - and uses 3, 6 or 9 fractional digits as required to represent the - exact time. Example of the return format: '1972-01-01T10:00:20.021Z' - """ - nanos = self.nanos % _NANOS_PER_SECOND - total_sec = self.seconds + (self.nanos - nanos) // _NANOS_PER_SECOND - seconds = total_sec % _SECONDS_PER_DAY - days = (total_sec - seconds) // _SECONDS_PER_DAY - dt = datetime.datetime(1970, 1, 1) + datetime.timedelta(days, seconds) - - result = dt.isoformat() - if (nanos % 1e9) == 0: - # If there are 0 fractional digits, the fractional - # point '.' should be omitted when serializing. - return result + 'Z' - if (nanos % 1e6) == 0: - # Serialize 3 fractional digits. - return result + '.%03dZ' % (nanos / 1e6) - if (nanos % 1e3) == 0: - # Serialize 6 fractional digits. - return result + '.%06dZ' % (nanos / 1e3) - # Serialize 9 fractional digits. - return result + '.%09dZ' % nanos - - def FromJsonString(self, value): - """Parse a RFC 3339 date string format to Timestamp. - - Args: - value: A date string. Any fractional digits (or none) and any offset are - accepted as long as they fit into nano-seconds precision. - Example of accepted format: '1972-01-01T10:00:20.021-05:00' - - Raises: - ValueError: On parsing problems. - """ - if not isinstance(value, str): - raise ValueError('Timestamp JSON value not a string: {!r}'.format(value)) - timezone_offset = value.find('Z') - if timezone_offset == -1: - timezone_offset = value.find('+') - if timezone_offset == -1: - timezone_offset = value.rfind('-') - if timezone_offset == -1: - raise ValueError( - 'Failed to parse timestamp: missing valid timezone offset.') - time_value = value[0:timezone_offset] - # Parse datetime and nanos. - point_position = time_value.find('.') - if point_position == -1: - second_value = time_value - nano_value = '' - else: - second_value = time_value[:point_position] - nano_value = time_value[point_position + 1:] - if 't' in second_value: - raise ValueError( - 'time data \'{0}\' does not match format \'%Y-%m-%dT%H:%M:%S\', ' - 'lowercase \'t\' is not accepted'.format(second_value)) - date_object = datetime.datetime.strptime(second_value, _TIMESTAMPFOMAT) - td = date_object - datetime.datetime(1970, 1, 1) - seconds = td.seconds + td.days * _SECONDS_PER_DAY - if len(nano_value) > 9: - raise ValueError( - 'Failed to parse Timestamp: nanos {0} more than ' - '9 fractional digits.'.format(nano_value)) - if nano_value: - nanos = round(float('0.' + nano_value) * 1e9) - else: - nanos = 0 - # Parse timezone offsets. - if value[timezone_offset] == 'Z': - if len(value) != timezone_offset + 1: - raise ValueError('Failed to parse timestamp: invalid trailing' - ' data {0}.'.format(value)) - else: - timezone = value[timezone_offset:] - pos = timezone.find(':') - if pos == -1: - raise ValueError( - 'Invalid timezone offset value: {0}.'.format(timezone)) - if timezone[0] == '+': - seconds -= (int(timezone[1:pos])*60+int(timezone[pos+1:]))*60 - else: - seconds += (int(timezone[1:pos])*60+int(timezone[pos+1:]))*60 - # Set seconds and nanos - self.seconds = int(seconds) - self.nanos = int(nanos) - - def GetCurrentTime(self): - """Get the current UTC into Timestamp.""" - self.FromDatetime(datetime.datetime.utcnow()) - - def ToNanoseconds(self): - """Converts Timestamp to nanoseconds since epoch.""" - return self.seconds * _NANOS_PER_SECOND + self.nanos - - def ToMicroseconds(self): - """Converts Timestamp to microseconds since epoch.""" - return (self.seconds * _MICROS_PER_SECOND + - self.nanos // _NANOS_PER_MICROSECOND) - - def ToMilliseconds(self): - """Converts Timestamp to milliseconds since epoch.""" - return (self.seconds * _MILLIS_PER_SECOND + - self.nanos // _NANOS_PER_MILLISECOND) - - def ToSeconds(self): - """Converts Timestamp to seconds since epoch.""" - return self.seconds - - def FromNanoseconds(self, nanos): - """Converts nanoseconds since epoch to Timestamp.""" - self.seconds = nanos // _NANOS_PER_SECOND - self.nanos = nanos % _NANOS_PER_SECOND - - def FromMicroseconds(self, micros): - """Converts microseconds since epoch to Timestamp.""" - self.seconds = micros // _MICROS_PER_SECOND - self.nanos = (micros % _MICROS_PER_SECOND) * _NANOS_PER_MICROSECOND - - def FromMilliseconds(self, millis): - """Converts milliseconds since epoch to Timestamp.""" - self.seconds = millis // _MILLIS_PER_SECOND - self.nanos = (millis % _MILLIS_PER_SECOND) * _NANOS_PER_MILLISECOND - - def FromSeconds(self, seconds): - """Converts seconds since epoch to Timestamp.""" - self.seconds = seconds - self.nanos = 0 - - def ToDatetime(self, tzinfo=None): - """Converts Timestamp to a datetime. - - Args: - tzinfo: A datetime.tzinfo subclass; defaults to None. - - Returns: - If tzinfo is None, returns a timezone-naive UTC datetime (with no timezone - information, i.e. not aware that it's UTC). - - Otherwise, returns a timezone-aware datetime in the input timezone. - """ - delta = datetime.timedelta( - seconds=self.seconds, - microseconds=_RoundTowardZero(self.nanos, _NANOS_PER_MICROSECOND)) - if tzinfo is None: - return _EPOCH_DATETIME_NAIVE + delta - else: - return _EPOCH_DATETIME_AWARE.astimezone(tzinfo) + delta - - def FromDatetime(self, dt): - """Converts datetime to Timestamp. - - Args: - dt: A datetime. If it's timezone-naive, it's assumed to be in UTC. - """ - # Using this guide: http://wiki.python.org/moin/WorkingWithTime - # And this conversion guide: http://docs.python.org/library/time.html - - # Turn the date parameter into a tuple (struct_time) that can then be - # manipulated into a long value of seconds. During the conversion from - # struct_time to long, the source date in UTC, and so it follows that the - # correct transformation is calendar.timegm() - self.seconds = calendar.timegm(dt.utctimetuple()) - self.nanos = dt.microsecond * _NANOS_PER_MICROSECOND - - -class Duration(object): - """Class for Duration message type.""" - - __slots__ = () - - def ToJsonString(self): - """Converts Duration to string format. - - Returns: - A string converted from self. The string format will contains - 3, 6, or 9 fractional digits depending on the precision required to - represent the exact Duration value. For example: "1s", "1.010s", - "1.000000100s", "-3.100s" - """ - _CheckDurationValid(self.seconds, self.nanos) - if self.seconds < 0 or self.nanos < 0: - result = '-' - seconds = - self.seconds + int((0 - self.nanos) // 1e9) - nanos = (0 - self.nanos) % 1e9 - else: - result = '' - seconds = self.seconds + int(self.nanos // 1e9) - nanos = self.nanos % 1e9 - result += '%d' % seconds - if (nanos % 1e9) == 0: - # If there are 0 fractional digits, the fractional - # point '.' should be omitted when serializing. - return result + 's' - if (nanos % 1e6) == 0: - # Serialize 3 fractional digits. - return result + '.%03ds' % (nanos / 1e6) - if (nanos % 1e3) == 0: - # Serialize 6 fractional digits. - return result + '.%06ds' % (nanos / 1e3) - # Serialize 9 fractional digits. - return result + '.%09ds' % nanos - - def FromJsonString(self, value): - """Converts a string to Duration. - - Args: - value: A string to be converted. The string must end with 's'. Any - fractional digits (or none) are accepted as long as they fit into - precision. For example: "1s", "1.01s", "1.0000001s", "-3.100s - - Raises: - ValueError: On parsing problems. - """ - if not isinstance(value, str): - raise ValueError('Duration JSON value not a string: {!r}'.format(value)) - if len(value) < 1 or value[-1] != 's': - raise ValueError( - 'Duration must end with letter "s": {0}.'.format(value)) - try: - pos = value.find('.') - if pos == -1: - seconds = int(value[:-1]) - nanos = 0 - else: - seconds = int(value[:pos]) - if value[0] == '-': - nanos = int(round(float('-0{0}'.format(value[pos: -1])) *1e9)) - else: - nanos = int(round(float('0{0}'.format(value[pos: -1])) *1e9)) - _CheckDurationValid(seconds, nanos) - self.seconds = seconds - self.nanos = nanos - except ValueError as e: - raise ValueError( - 'Couldn\'t parse duration: {0} : {1}.'.format(value, e)) - - def ToNanoseconds(self): - """Converts a Duration to nanoseconds.""" - return self.seconds * _NANOS_PER_SECOND + self.nanos - - def ToMicroseconds(self): - """Converts a Duration to microseconds.""" - micros = _RoundTowardZero(self.nanos, _NANOS_PER_MICROSECOND) - return self.seconds * _MICROS_PER_SECOND + micros - - def ToMilliseconds(self): - """Converts a Duration to milliseconds.""" - millis = _RoundTowardZero(self.nanos, _NANOS_PER_MILLISECOND) - return self.seconds * _MILLIS_PER_SECOND + millis - - def ToSeconds(self): - """Converts a Duration to seconds.""" - return self.seconds - - def FromNanoseconds(self, nanos): - """Converts nanoseconds to Duration.""" - self._NormalizeDuration(nanos // _NANOS_PER_SECOND, - nanos % _NANOS_PER_SECOND) - - def FromMicroseconds(self, micros): - """Converts microseconds to Duration.""" - self._NormalizeDuration( - micros // _MICROS_PER_SECOND, - (micros % _MICROS_PER_SECOND) * _NANOS_PER_MICROSECOND) - - def FromMilliseconds(self, millis): - """Converts milliseconds to Duration.""" - self._NormalizeDuration( - millis // _MILLIS_PER_SECOND, - (millis % _MILLIS_PER_SECOND) * _NANOS_PER_MILLISECOND) - - def FromSeconds(self, seconds): - """Converts seconds to Duration.""" - self.seconds = seconds - self.nanos = 0 - - def ToTimedelta(self): - """Converts Duration to timedelta.""" - return datetime.timedelta( - seconds=self.seconds, microseconds=_RoundTowardZero( - self.nanos, _NANOS_PER_MICROSECOND)) - - def FromTimedelta(self, td): - """Converts timedelta to Duration.""" - self._NormalizeDuration(td.seconds + td.days * _SECONDS_PER_DAY, - td.microseconds * _NANOS_PER_MICROSECOND) - - def _NormalizeDuration(self, seconds, nanos): - """Set Duration by seconds and nanos.""" - # Force nanos to be negative if the duration is negative. - if seconds < 0 and nanos > 0: - seconds += 1 - nanos -= _NANOS_PER_SECOND - self.seconds = seconds - self.nanos = nanos - - -def _CheckDurationValid(seconds, nanos): - if seconds < -_DURATION_SECONDS_MAX or seconds > _DURATION_SECONDS_MAX: - raise ValueError( - 'Duration is not valid: Seconds {0} must be in range ' - '[-315576000000, 315576000000].'.format(seconds)) - if nanos <= -_NANOS_PER_SECOND or nanos >= _NANOS_PER_SECOND: - raise ValueError( - 'Duration is not valid: Nanos {0} must be in range ' - '[-999999999, 999999999].'.format(nanos)) - if (nanos < 0 and seconds > 0) or (nanos > 0 and seconds < 0): - raise ValueError( - 'Duration is not valid: Sign mismatch.') - - -def _RoundTowardZero(value, divider): - """Truncates the remainder part after division.""" - # For some languages, the sign of the remainder is implementation - # dependent if any of the operands is negative. Here we enforce - # "rounded toward zero" semantics. For example, for (-5) / 2 an - # implementation may give -3 as the result with the remainder being - # 1. This function ensures we always return -2 (closer to zero). - result = value // divider - remainder = value % divider - if result < 0 and remainder > 0: - return result + 1 - else: - return result - - -class FieldMask(object): - """Class for FieldMask message type.""" - - __slots__ = () - - def ToJsonString(self): - """Converts FieldMask to string according to proto3 JSON spec.""" - camelcase_paths = [] - for path in self.paths: - camelcase_paths.append(_SnakeCaseToCamelCase(path)) - return ','.join(camelcase_paths) - - def FromJsonString(self, value): - """Converts string to FieldMask according to proto3 JSON spec.""" - if not isinstance(value, str): - raise ValueError('FieldMask JSON value not a string: {!r}'.format(value)) - self.Clear() - if value: - for path in value.split(','): - self.paths.append(_CamelCaseToSnakeCase(path)) - - def IsValidForDescriptor(self, message_descriptor): - """Checks whether the FieldMask is valid for Message Descriptor.""" - for path in self.paths: - if not _IsValidPath(message_descriptor, path): - return False - return True - - def AllFieldsFromDescriptor(self, message_descriptor): - """Gets all direct fields of Message Descriptor to FieldMask.""" - self.Clear() - for field in message_descriptor.fields: - self.paths.append(field.name) - - def CanonicalFormFromMask(self, mask): - """Converts a FieldMask to the canonical form. - - Removes paths that are covered by another path. For example, - "foo.bar" is covered by "foo" and will be removed if "foo" - is also in the FieldMask. Then sorts all paths in alphabetical order. - - Args: - mask: The original FieldMask to be converted. - """ - tree = _FieldMaskTree(mask) - tree.ToFieldMask(self) - - def Union(self, mask1, mask2): - """Merges mask1 and mask2 into this FieldMask.""" - _CheckFieldMaskMessage(mask1) - _CheckFieldMaskMessage(mask2) - tree = _FieldMaskTree(mask1) - tree.MergeFromFieldMask(mask2) - tree.ToFieldMask(self) - - def Intersect(self, mask1, mask2): - """Intersects mask1 and mask2 into this FieldMask.""" - _CheckFieldMaskMessage(mask1) - _CheckFieldMaskMessage(mask2) - tree = _FieldMaskTree(mask1) - intersection = _FieldMaskTree() - for path in mask2.paths: - tree.IntersectPath(path, intersection) - intersection.ToFieldMask(self) - - def MergeMessage( - self, source, destination, - replace_message_field=False, replace_repeated_field=False): - """Merges fields specified in FieldMask from source to destination. - - Args: - source: Source message. - destination: The destination message to be merged into. - replace_message_field: Replace message field if True. Merge message - field if False. - replace_repeated_field: Replace repeated field if True. Append - elements of repeated field if False. - """ - tree = _FieldMaskTree(self) - tree.MergeMessage( - source, destination, replace_message_field, replace_repeated_field) - - -def _IsValidPath(message_descriptor, path): - """Checks whether the path is valid for Message Descriptor.""" - parts = path.split('.') - last = parts.pop() - for name in parts: - field = message_descriptor.fields_by_name.get(name) - if (field is None or - field.label == FieldDescriptor.LABEL_REPEATED or - field.type != FieldDescriptor.TYPE_MESSAGE): - return False - message_descriptor = field.message_type - return last in message_descriptor.fields_by_name - - -def _CheckFieldMaskMessage(message): - """Raises ValueError if message is not a FieldMask.""" - message_descriptor = message.DESCRIPTOR - if (message_descriptor.name != 'FieldMask' or - message_descriptor.file.name != 'google/protobuf/field_mask.proto'): - raise ValueError('Message {0} is not a FieldMask.'.format( - message_descriptor.full_name)) - - -def _SnakeCaseToCamelCase(path_name): - """Converts a path name from snake_case to camelCase.""" - result = [] - after_underscore = False - for c in path_name: - if c.isupper(): - raise ValueError( - 'Fail to print FieldMask to Json string: Path name ' - '{0} must not contain uppercase letters.'.format(path_name)) - if after_underscore: - if c.islower(): - result.append(c.upper()) - after_underscore = False - else: - raise ValueError( - 'Fail to print FieldMask to Json string: The ' - 'character after a "_" must be a lowercase letter ' - 'in path name {0}.'.format(path_name)) - elif c == '_': - after_underscore = True - else: - result += c - - if after_underscore: - raise ValueError('Fail to print FieldMask to Json string: Trailing "_" ' - 'in path name {0}.'.format(path_name)) - return ''.join(result) - - -def _CamelCaseToSnakeCase(path_name): - """Converts a field name from camelCase to snake_case.""" - result = [] - for c in path_name: - if c == '_': - raise ValueError('Fail to parse FieldMask: Path name ' - '{0} must not contain "_"s.'.format(path_name)) - if c.isupper(): - result += '_' - result += c.lower() - else: - result += c - return ''.join(result) - - -class _FieldMaskTree(object): - """Represents a FieldMask in a tree structure. - - For example, given a FieldMask "foo.bar,foo.baz,bar.baz", - the FieldMaskTree will be: - [_root] -+- foo -+- bar - | | - | +- baz - | - +- bar --- baz - In the tree, each leaf node represents a field path. - """ - - __slots__ = ('_root',) - - def __init__(self, field_mask=None): - """Initializes the tree by FieldMask.""" - self._root = {} - if field_mask: - self.MergeFromFieldMask(field_mask) - - def MergeFromFieldMask(self, field_mask): - """Merges a FieldMask to the tree.""" - for path in field_mask.paths: - self.AddPath(path) - - def AddPath(self, path): - """Adds a field path into the tree. - - If the field path to add is a sub-path of an existing field path - in the tree (i.e., a leaf node), it means the tree already matches - the given path so nothing will be added to the tree. If the path - matches an existing non-leaf node in the tree, that non-leaf node - will be turned into a leaf node with all its children removed because - the path matches all the node's children. Otherwise, a new path will - be added. - - Args: - path: The field path to add. - """ - node = self._root - for name in path.split('.'): - if name not in node: - node[name] = {} - elif not node[name]: - # Pre-existing empty node implies we already have this entire tree. - return - node = node[name] - # Remove any sub-trees we might have had. - node.clear() - - def ToFieldMask(self, field_mask): - """Converts the tree to a FieldMask.""" - field_mask.Clear() - _AddFieldPaths(self._root, '', field_mask) - - def IntersectPath(self, path, intersection): - """Calculates the intersection part of a field path with this tree. - - Args: - path: The field path to calculates. - intersection: The out tree to record the intersection part. - """ - node = self._root - for name in path.split('.'): - if name not in node: - return - elif not node[name]: - intersection.AddPath(path) - return - node = node[name] - intersection.AddLeafNodes(path, node) - - def AddLeafNodes(self, prefix, node): - """Adds leaf nodes begin with prefix to this tree.""" - if not node: - self.AddPath(prefix) - for name in node: - child_path = prefix + '.' + name - self.AddLeafNodes(child_path, node[name]) - - def MergeMessage( - self, source, destination, - replace_message, replace_repeated): - """Merge all fields specified by this tree from source to destination.""" - _MergeMessage( - self._root, source, destination, replace_message, replace_repeated) - - -def _StrConvert(value): - """Converts value to str if it is not.""" - # This file is imported by c extension and some methods like ClearField - # requires string for the field name. py2/py3 has different text - # type and may use unicode. - if not isinstance(value, str): - return value.encode('utf-8') - return value - - -def _MergeMessage( - node, source, destination, replace_message, replace_repeated): - """Merge all fields specified by a sub-tree from source to destination.""" - source_descriptor = source.DESCRIPTOR - for name in node: - child = node[name] - field = source_descriptor.fields_by_name[name] - if field is None: - raise ValueError('Error: Can\'t find field {0} in message {1}.'.format( - name, source_descriptor.full_name)) - if child: - # Sub-paths are only allowed for singular message fields. - if (field.label == FieldDescriptor.LABEL_REPEATED or - field.cpp_type != FieldDescriptor.CPPTYPE_MESSAGE): - raise ValueError('Error: Field {0} in message {1} is not a singular ' - 'message field and cannot have sub-fields.'.format( - name, source_descriptor.full_name)) - if source.HasField(name): - _MergeMessage( - child, getattr(source, name), getattr(destination, name), - replace_message, replace_repeated) - continue - if field.label == FieldDescriptor.LABEL_REPEATED: - if replace_repeated: - destination.ClearField(_StrConvert(name)) - repeated_source = getattr(source, name) - repeated_destination = getattr(destination, name) - repeated_destination.MergeFrom(repeated_source) - else: - if field.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE: - if replace_message: - destination.ClearField(_StrConvert(name)) - if source.HasField(name): - getattr(destination, name).MergeFrom(getattr(source, name)) - else: - setattr(destination, name, getattr(source, name)) - - -def _AddFieldPaths(node, prefix, field_mask): - """Adds the field paths descended from node to field_mask.""" - if not node and prefix: - field_mask.paths.append(prefix) - return - for name in sorted(node): - if prefix: - child_path = prefix + '.' + name - else: - child_path = name - _AddFieldPaths(node[name], child_path, field_mask) - - -def _SetStructValue(struct_value, value): - if value is None: - struct_value.null_value = 0 - elif isinstance(value, bool): - # Note: this check must come before the number check because in Python - # True and False are also considered numbers. - struct_value.bool_value = value - elif isinstance(value, str): - struct_value.string_value = value - elif isinstance(value, (int, float)): - struct_value.number_value = value - elif isinstance(value, (dict, Struct)): - struct_value.struct_value.Clear() - struct_value.struct_value.update(value) - elif isinstance(value, (list, ListValue)): - struct_value.list_value.Clear() - struct_value.list_value.extend(value) - else: - raise ValueError('Unexpected type') - - -def _GetStructValue(struct_value): - which = struct_value.WhichOneof('kind') - if which == 'struct_value': - return struct_value.struct_value - elif which == 'null_value': - return None - elif which == 'number_value': - return struct_value.number_value - elif which == 'string_value': - return struct_value.string_value - elif which == 'bool_value': - return struct_value.bool_value - elif which == 'list_value': - return struct_value.list_value - elif which is None: - raise ValueError('Value not set') - - -class Struct(object): - """Class for Struct message type.""" - - __slots__ = () - - def __getitem__(self, key): - return _GetStructValue(self.fields[key]) - - def __contains__(self, item): - return item in self.fields - - def __setitem__(self, key, value): - _SetStructValue(self.fields[key], value) - - def __delitem__(self, key): - del self.fields[key] - - def __len__(self): - return len(self.fields) - - def __iter__(self): - return iter(self.fields) - - def keys(self): # pylint: disable=invalid-name - return self.fields.keys() - - def values(self): # pylint: disable=invalid-name - return [self[key] for key in self] - - def items(self): # pylint: disable=invalid-name - return [(key, self[key]) for key in self] - - def get_or_create_list(self, key): - """Returns a list for this key, creating if it didn't exist already.""" - if not self.fields[key].HasField('list_value'): - # Clear will mark list_value modified which will indeed create a list. - self.fields[key].list_value.Clear() - return self.fields[key].list_value - - def get_or_create_struct(self, key): - """Returns a struct for this key, creating if it didn't exist already.""" - if not self.fields[key].HasField('struct_value'): - # Clear will mark struct_value modified which will indeed create a struct. - self.fields[key].struct_value.Clear() - return self.fields[key].struct_value - - def update(self, dictionary): # pylint: disable=invalid-name - for key, value in dictionary.items(): - _SetStructValue(self.fields[key], value) - -collections.abc.MutableMapping.register(Struct) - - -class ListValue(object): - """Class for ListValue message type.""" - - __slots__ = () - - def __len__(self): - return len(self.values) - - def append(self, value): - _SetStructValue(self.values.add(), value) - - def extend(self, elem_seq): - for value in elem_seq: - self.append(value) - - def __getitem__(self, index): - """Retrieves item by the specified index.""" - return _GetStructValue(self.values.__getitem__(index)) - - def __setitem__(self, index, value): - _SetStructValue(self.values.__getitem__(index), value) - - def __delitem__(self, key): - del self.values[key] - - def items(self): - for i in range(len(self)): - yield self[i] - - def add_struct(self): - """Appends and returns a struct value as the next value in the list.""" - struct_value = self.values.add().struct_value - # Clear will mark struct_value modified which will indeed create a struct. - struct_value.Clear() - return struct_value - - def add_list(self): - """Appends and returns a list value as the next value in the list.""" - list_value = self.values.add().list_value - # Clear will mark list_value modified which will indeed create a list. - list_value.Clear() - return list_value - -collections.abc.MutableSequence.register(ListValue) - - -WKTBASES = { - 'google.protobuf.Any': Any, - 'google.protobuf.Duration': Duration, - 'google.protobuf.FieldMask': FieldMask, - 'google.protobuf.ListValue': ListValue, - 'google.protobuf.Struct': Struct, - 'google.protobuf.Timestamp': Timestamp, -} diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/wire_format.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/wire_format.py deleted file mode 100644 index 883f525585..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/wire_format.py +++ /dev/null @@ -1,268 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Constants and static functions to support protocol buffer wire format.""" - -__author__ = 'robinson@google.com (Will Robinson)' - -import struct -from google.protobuf import descriptor -from google.protobuf import message - - -TAG_TYPE_BITS = 3 # Number of bits used to hold type info in a proto tag. -TAG_TYPE_MASK = (1 << TAG_TYPE_BITS) - 1 # 0x7 - -# These numbers identify the wire type of a protocol buffer value. -# We use the least-significant TAG_TYPE_BITS bits of the varint-encoded -# tag-and-type to store one of these WIRETYPE_* constants. -# These values must match WireType enum in google/protobuf/wire_format.h. -WIRETYPE_VARINT = 0 -WIRETYPE_FIXED64 = 1 -WIRETYPE_LENGTH_DELIMITED = 2 -WIRETYPE_START_GROUP = 3 -WIRETYPE_END_GROUP = 4 -WIRETYPE_FIXED32 = 5 -_WIRETYPE_MAX = 5 - - -# Bounds for various integer types. -INT32_MAX = int((1 << 31) - 1) -INT32_MIN = int(-(1 << 31)) -UINT32_MAX = (1 << 32) - 1 - -INT64_MAX = (1 << 63) - 1 -INT64_MIN = -(1 << 63) -UINT64_MAX = (1 << 64) - 1 - -# "struct" format strings that will encode/decode the specified formats. -FORMAT_UINT32_LITTLE_ENDIAN = '> TAG_TYPE_BITS), (tag & TAG_TYPE_MASK) - - -def ZigZagEncode(value): - """ZigZag Transform: Encodes signed integers so that they can be - effectively used with varint encoding. See wire_format.h for - more details. - """ - if value >= 0: - return value << 1 - return (value << 1) ^ (~0) - - -def ZigZagDecode(value): - """Inverse of ZigZagEncode().""" - if not value & 0x1: - return value >> 1 - return (value >> 1) ^ (~0) - - - -# The *ByteSize() functions below return the number of bytes required to -# serialize "field number + type" information and then serialize the value. - - -def Int32ByteSize(field_number, int32): - return Int64ByteSize(field_number, int32) - - -def Int32ByteSizeNoTag(int32): - return _VarUInt64ByteSizeNoTag(0xffffffffffffffff & int32) - - -def Int64ByteSize(field_number, int64): - # Have to convert to uint before calling UInt64ByteSize(). - return UInt64ByteSize(field_number, 0xffffffffffffffff & int64) - - -def UInt32ByteSize(field_number, uint32): - return UInt64ByteSize(field_number, uint32) - - -def UInt64ByteSize(field_number, uint64): - return TagByteSize(field_number) + _VarUInt64ByteSizeNoTag(uint64) - - -def SInt32ByteSize(field_number, int32): - return UInt32ByteSize(field_number, ZigZagEncode(int32)) - - -def SInt64ByteSize(field_number, int64): - return UInt64ByteSize(field_number, ZigZagEncode(int64)) - - -def Fixed32ByteSize(field_number, fixed32): - return TagByteSize(field_number) + 4 - - -def Fixed64ByteSize(field_number, fixed64): - return TagByteSize(field_number) + 8 - - -def SFixed32ByteSize(field_number, sfixed32): - return TagByteSize(field_number) + 4 - - -def SFixed64ByteSize(field_number, sfixed64): - return TagByteSize(field_number) + 8 - - -def FloatByteSize(field_number, flt): - return TagByteSize(field_number) + 4 - - -def DoubleByteSize(field_number, double): - return TagByteSize(field_number) + 8 - - -def BoolByteSize(field_number, b): - return TagByteSize(field_number) + 1 - - -def EnumByteSize(field_number, enum): - return UInt32ByteSize(field_number, enum) - - -def StringByteSize(field_number, string): - return BytesByteSize(field_number, string.encode('utf-8')) - - -def BytesByteSize(field_number, b): - return (TagByteSize(field_number) - + _VarUInt64ByteSizeNoTag(len(b)) - + len(b)) - - -def GroupByteSize(field_number, message): - return (2 * TagByteSize(field_number) # START and END group. - + message.ByteSize()) - - -def MessageByteSize(field_number, message): - return (TagByteSize(field_number) - + _VarUInt64ByteSizeNoTag(message.ByteSize()) - + message.ByteSize()) - - -def MessageSetItemByteSize(field_number, msg): - # First compute the sizes of the tags. - # There are 2 tags for the beginning and ending of the repeated group, that - # is field number 1, one with field number 2 (type_id) and one with field - # number 3 (message). - total_size = (2 * TagByteSize(1) + TagByteSize(2) + TagByteSize(3)) - - # Add the number of bytes for type_id. - total_size += _VarUInt64ByteSizeNoTag(field_number) - - message_size = msg.ByteSize() - - # The number of bytes for encoding the length of the message. - total_size += _VarUInt64ByteSizeNoTag(message_size) - - # The size of the message. - total_size += message_size - return total_size - - -def TagByteSize(field_number): - """Returns the bytes required to serialize a tag with this field number.""" - # Just pass in type 0, since the type won't affect the tag+type size. - return _VarUInt64ByteSizeNoTag(PackTag(field_number, 0)) - - -# Private helper function for the *ByteSize() functions above. - -def _VarUInt64ByteSizeNoTag(uint64): - """Returns the number of bytes required to serialize a single varint - using boundary value comparisons. (unrolled loop optimization -WPierce) - uint64 must be unsigned. - """ - if uint64 <= 0x7f: return 1 - if uint64 <= 0x3fff: return 2 - if uint64 <= 0x1fffff: return 3 - if uint64 <= 0xfffffff: return 4 - if uint64 <= 0x7ffffffff: return 5 - if uint64 <= 0x3ffffffffff: return 6 - if uint64 <= 0x1ffffffffffff: return 7 - if uint64 <= 0xffffffffffffff: return 8 - if uint64 <= 0x7fffffffffffffff: return 9 - if uint64 > UINT64_MAX: - raise message.EncodeError('Value out of range: %d' % uint64) - return 10 - - -NON_PACKABLE_TYPES = ( - descriptor.FieldDescriptor.TYPE_STRING, - descriptor.FieldDescriptor.TYPE_GROUP, - descriptor.FieldDescriptor.TYPE_MESSAGE, - descriptor.FieldDescriptor.TYPE_BYTES -) - - -def IsTypePackable(field_type): - """Return true iff packable = true is valid for fields of this type. - - Args: - field_type: a FieldDescriptor::Type value. - - Returns: - True iff fields of this type are packable. - """ - return field_type not in NON_PACKABLE_TYPES diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/json_format.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/json_format.py deleted file mode 100644 index 5024ed89d7..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/json_format.py +++ /dev/null @@ -1,912 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Contains routines for printing protocol messages in JSON format. - -Simple usage example: - - # Create a proto object and serialize it to a json format string. - message = my_proto_pb2.MyMessage(foo='bar') - json_string = json_format.MessageToJson(message) - - # Parse a json format string to proto object. - message = json_format.Parse(json_string, my_proto_pb2.MyMessage()) -""" - -__author__ = 'jieluo@google.com (Jie Luo)' - - -import base64 -from collections import OrderedDict -import json -import math -from operator import methodcaller -import re -import sys - -from google.protobuf.internal import type_checkers -from google.protobuf import descriptor -from google.protobuf import symbol_database - - -_TIMESTAMPFOMAT = '%Y-%m-%dT%H:%M:%S' -_INT_TYPES = frozenset([descriptor.FieldDescriptor.CPPTYPE_INT32, - descriptor.FieldDescriptor.CPPTYPE_UINT32, - descriptor.FieldDescriptor.CPPTYPE_INT64, - descriptor.FieldDescriptor.CPPTYPE_UINT64]) -_INT64_TYPES = frozenset([descriptor.FieldDescriptor.CPPTYPE_INT64, - descriptor.FieldDescriptor.CPPTYPE_UINT64]) -_FLOAT_TYPES = frozenset([descriptor.FieldDescriptor.CPPTYPE_FLOAT, - descriptor.FieldDescriptor.CPPTYPE_DOUBLE]) -_INFINITY = 'Infinity' -_NEG_INFINITY = '-Infinity' -_NAN = 'NaN' - -_UNPAIRED_SURROGATE_PATTERN = re.compile( - u'[\ud800-\udbff](?![\udc00-\udfff])|(? self.max_recursion_depth: - raise ParseError('Message too deep. Max recursion depth is {0}'.format( - self.max_recursion_depth)) - message_descriptor = message.DESCRIPTOR - full_name = message_descriptor.full_name - if not path: - path = message_descriptor.name - if _IsWrapperMessage(message_descriptor): - self._ConvertWrapperMessage(value, message, path) - elif full_name in _WKTJSONMETHODS: - methodcaller(_WKTJSONMETHODS[full_name][1], value, message, path)(self) - else: - self._ConvertFieldValuePair(value, message, path) - self.recursion_depth -= 1 - - def _ConvertFieldValuePair(self, js, message, path): - """Convert field value pairs into regular message. - - Args: - js: A JSON object to convert the field value pairs. - message: A regular protocol message to record the data. - path: parent path to log parse error info. - - Raises: - ParseError: In case of problems converting. - """ - names = [] - message_descriptor = message.DESCRIPTOR - fields_by_json_name = dict((f.json_name, f) - for f in message_descriptor.fields) - for name in js: - try: - field = fields_by_json_name.get(name, None) - if not field: - field = message_descriptor.fields_by_name.get(name, None) - if not field and _VALID_EXTENSION_NAME.match(name): - if not message_descriptor.is_extendable: - raise ParseError( - 'Message type {0} does not have extensions at {1}'.format( - message_descriptor.full_name, path)) - identifier = name[1:-1] # strip [] brackets - # pylint: disable=protected-access - field = message.Extensions._FindExtensionByName(identifier) - # pylint: enable=protected-access - if not field: - # Try looking for extension by the message type name, dropping the - # field name following the final . separator in full_name. - identifier = '.'.join(identifier.split('.')[:-1]) - # pylint: disable=protected-access - field = message.Extensions._FindExtensionByName(identifier) - # pylint: enable=protected-access - if not field: - if self.ignore_unknown_fields: - continue - raise ParseError( - ('Message type "{0}" has no field named "{1}" at "{2}".\n' - ' Available Fields(except extensions): "{3}"').format( - message_descriptor.full_name, name, path, - [f.json_name for f in message_descriptor.fields])) - if name in names: - raise ParseError('Message type "{0}" should not have multiple ' - '"{1}" fields at "{2}".'.format( - message.DESCRIPTOR.full_name, name, path)) - names.append(name) - value = js[name] - # Check no other oneof field is parsed. - if field.containing_oneof is not None and value is not None: - oneof_name = field.containing_oneof.name - if oneof_name in names: - raise ParseError('Message type "{0}" should not have multiple ' - '"{1}" oneof fields at "{2}".'.format( - message.DESCRIPTOR.full_name, oneof_name, - path)) - names.append(oneof_name) - - if value is None: - if (field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE - and field.message_type.full_name == 'google.protobuf.Value'): - sub_message = getattr(message, field.name) - sub_message.null_value = 0 - elif (field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_ENUM - and field.enum_type.full_name == 'google.protobuf.NullValue'): - setattr(message, field.name, 0) - else: - message.ClearField(field.name) - continue - - # Parse field value. - if _IsMapEntry(field): - message.ClearField(field.name) - self._ConvertMapFieldValue(value, message, field, - '{0}.{1}'.format(path, name)) - elif field.label == descriptor.FieldDescriptor.LABEL_REPEATED: - message.ClearField(field.name) - if not isinstance(value, list): - raise ParseError('repeated field {0} must be in [] which is ' - '{1} at {2}'.format(name, value, path)) - if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: - # Repeated message field. - for index, item in enumerate(value): - sub_message = getattr(message, field.name).add() - # None is a null_value in Value. - if (item is None and - sub_message.DESCRIPTOR.full_name != 'google.protobuf.Value'): - raise ParseError('null is not allowed to be used as an element' - ' in a repeated field at {0}.{1}[{2}]'.format( - path, name, index)) - self.ConvertMessage(item, sub_message, - '{0}.{1}[{2}]'.format(path, name, index)) - else: - # Repeated scalar field. - for index, item in enumerate(value): - if item is None: - raise ParseError('null is not allowed to be used as an element' - ' in a repeated field at {0}.{1}[{2}]'.format( - path, name, index)) - getattr(message, field.name).append( - _ConvertScalarFieldValue( - item, field, '{0}.{1}[{2}]'.format(path, name, index))) - elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: - if field.is_extension: - sub_message = message.Extensions[field] - else: - sub_message = getattr(message, field.name) - sub_message.SetInParent() - self.ConvertMessage(value, sub_message, '{0}.{1}'.format(path, name)) - else: - if field.is_extension: - message.Extensions[field] = _ConvertScalarFieldValue( - value, field, '{0}.{1}'.format(path, name)) - else: - setattr( - message, field.name, - _ConvertScalarFieldValue(value, field, - '{0}.{1}'.format(path, name))) - except ParseError as e: - if field and field.containing_oneof is None: - raise ParseError('Failed to parse {0} field: {1}.'.format(name, e)) - else: - raise ParseError(str(e)) - except ValueError as e: - raise ParseError('Failed to parse {0} field: {1}.'.format(name, e)) - except TypeError as e: - raise ParseError('Failed to parse {0} field: {1}.'.format(name, e)) - - def _ConvertAnyMessage(self, value, message, path): - """Convert a JSON representation into Any message.""" - if isinstance(value, dict) and not value: - return - try: - type_url = value['@type'] - except KeyError: - raise ParseError( - '@type is missing when parsing any message at {0}'.format(path)) - - try: - sub_message = _CreateMessageFromTypeUrl(type_url, self.descriptor_pool) - except TypeError as e: - raise ParseError('{0} at {1}'.format(e, path)) - message_descriptor = sub_message.DESCRIPTOR - full_name = message_descriptor.full_name - if _IsWrapperMessage(message_descriptor): - self._ConvertWrapperMessage(value['value'], sub_message, - '{0}.value'.format(path)) - elif full_name in _WKTJSONMETHODS: - methodcaller(_WKTJSONMETHODS[full_name][1], value['value'], sub_message, - '{0}.value'.format(path))( - self) - else: - del value['@type'] - self._ConvertFieldValuePair(value, sub_message, path) - value['@type'] = type_url - # Sets Any message - message.value = sub_message.SerializeToString() - message.type_url = type_url - - def _ConvertGenericMessage(self, value, message, path): - """Convert a JSON representation into message with FromJsonString.""" - # Duration, Timestamp, FieldMask have a FromJsonString method to do the - # conversion. Users can also call the method directly. - try: - message.FromJsonString(value) - except ValueError as e: - raise ParseError('{0} at {1}'.format(e, path)) - - def _ConvertValueMessage(self, value, message, path): - """Convert a JSON representation into Value message.""" - if isinstance(value, dict): - self._ConvertStructMessage(value, message.struct_value, path) - elif isinstance(value, list): - self._ConvertListValueMessage(value, message.list_value, path) - elif value is None: - message.null_value = 0 - elif isinstance(value, bool): - message.bool_value = value - elif isinstance(value, str): - message.string_value = value - elif isinstance(value, _INT_OR_FLOAT): - message.number_value = value - else: - raise ParseError('Value {0} has unexpected type {1} at {2}'.format( - value, type(value), path)) - - def _ConvertListValueMessage(self, value, message, path): - """Convert a JSON representation into ListValue message.""" - if not isinstance(value, list): - raise ParseError('ListValue must be in [] which is {0} at {1}'.format( - value, path)) - message.ClearField('values') - for index, item in enumerate(value): - self._ConvertValueMessage(item, message.values.add(), - '{0}[{1}]'.format(path, index)) - - def _ConvertStructMessage(self, value, message, path): - """Convert a JSON representation into Struct message.""" - if not isinstance(value, dict): - raise ParseError('Struct must be in a dict which is {0} at {1}'.format( - value, path)) - # Clear will mark the struct as modified so it will be created even if - # there are no values. - message.Clear() - for key in value: - self._ConvertValueMessage(value[key], message.fields[key], - '{0}.{1}'.format(path, key)) - return - - def _ConvertWrapperMessage(self, value, message, path): - """Convert a JSON representation into Wrapper message.""" - field = message.DESCRIPTOR.fields_by_name['value'] - setattr( - message, 'value', - _ConvertScalarFieldValue(value, field, path='{0}.value'.format(path))) - - def _ConvertMapFieldValue(self, value, message, field, path): - """Convert map field value for a message map field. - - Args: - value: A JSON object to convert the map field value. - message: A protocol message to record the converted data. - field: The descriptor of the map field to be converted. - path: parent path to log parse error info. - - Raises: - ParseError: In case of convert problems. - """ - if not isinstance(value, dict): - raise ParseError( - 'Map field {0} must be in a dict which is {1} at {2}'.format( - field.name, value, path)) - key_field = field.message_type.fields_by_name['key'] - value_field = field.message_type.fields_by_name['value'] - for key in value: - key_value = _ConvertScalarFieldValue(key, key_field, - '{0}.key'.format(path), True) - if value_field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: - self.ConvertMessage(value[key], - getattr(message, field.name)[key_value], - '{0}[{1}]'.format(path, key_value)) - else: - getattr(message, field.name)[key_value] = _ConvertScalarFieldValue( - value[key], value_field, path='{0}[{1}]'.format(path, key_value)) - - -def _ConvertScalarFieldValue(value, field, path, require_str=False): - """Convert a single scalar field value. - - Args: - value: A scalar value to convert the scalar field value. - field: The descriptor of the field to convert. - path: parent path to log parse error info. - require_str: If True, the field value must be a str. - - Returns: - The converted scalar field value - - Raises: - ParseError: In case of convert problems. - """ - try: - if field.cpp_type in _INT_TYPES: - return _ConvertInteger(value) - elif field.cpp_type in _FLOAT_TYPES: - return _ConvertFloat(value, field) - elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_BOOL: - return _ConvertBool(value, require_str) - elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_STRING: - if field.type == descriptor.FieldDescriptor.TYPE_BYTES: - if isinstance(value, str): - encoded = value.encode('utf-8') - else: - encoded = value - # Add extra padding '=' - padded_value = encoded + b'=' * (4 - len(encoded) % 4) - return base64.urlsafe_b64decode(padded_value) - else: - # Checking for unpaired surrogates appears to be unreliable, - # depending on the specific Python version, so we check manually. - if _UNPAIRED_SURROGATE_PATTERN.search(value): - raise ParseError('Unpaired surrogate') - return value - elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_ENUM: - # Convert an enum value. - enum_value = field.enum_type.values_by_name.get(value, None) - if enum_value is None: - try: - number = int(value) - enum_value = field.enum_type.values_by_number.get(number, None) - except ValueError: - raise ParseError('Invalid enum value {0} for enum type {1}'.format( - value, field.enum_type.full_name)) - if enum_value is None: - if field.file.syntax == 'proto3': - # Proto3 accepts unknown enums. - return number - raise ParseError('Invalid enum value {0} for enum type {1}'.format( - value, field.enum_type.full_name)) - return enum_value.number - except ParseError as e: - raise ParseError('{0} at {1}'.format(e, path)) - - -def _ConvertInteger(value): - """Convert an integer. - - Args: - value: A scalar value to convert. - - Returns: - The integer value. - - Raises: - ParseError: If an integer couldn't be consumed. - """ - if isinstance(value, float) and not value.is_integer(): - raise ParseError('Couldn\'t parse integer: {0}'.format(value)) - - if isinstance(value, str) and value.find(' ') != -1: - raise ParseError('Couldn\'t parse integer: "{0}"'.format(value)) - - if isinstance(value, bool): - raise ParseError('Bool value {0} is not acceptable for ' - 'integer field'.format(value)) - - return int(value) - - -def _ConvertFloat(value, field): - """Convert an floating point number.""" - if isinstance(value, float): - if math.isnan(value): - raise ParseError('Couldn\'t parse NaN, use quoted "NaN" instead') - if math.isinf(value): - if value > 0: - raise ParseError('Couldn\'t parse Infinity or value too large, ' - 'use quoted "Infinity" instead') - else: - raise ParseError('Couldn\'t parse -Infinity or value too small, ' - 'use quoted "-Infinity" instead') - if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_FLOAT: - # pylint: disable=protected-access - if value > type_checkers._FLOAT_MAX: - raise ParseError('Float value too large') - # pylint: disable=protected-access - if value < type_checkers._FLOAT_MIN: - raise ParseError('Float value too small') - if value == 'nan': - raise ParseError('Couldn\'t parse float "nan", use "NaN" instead') - try: - # Assume Python compatible syntax. - return float(value) - except ValueError: - # Check alternative spellings. - if value == _NEG_INFINITY: - return float('-inf') - elif value == _INFINITY: - return float('inf') - elif value == _NAN: - return float('nan') - else: - raise ParseError('Couldn\'t parse float: {0}'.format(value)) - - -def _ConvertBool(value, require_str): - """Convert a boolean value. - - Args: - value: A scalar value to convert. - require_str: If True, value must be a str. - - Returns: - The bool parsed. - - Raises: - ParseError: If a boolean value couldn't be consumed. - """ - if require_str: - if value == 'true': - return True - elif value == 'false': - return False - else: - raise ParseError('Expected "true" or "false", not {0}'.format(value)) - - if not isinstance(value, bool): - raise ParseError('Expected true or false without quotes') - return value - -_WKTJSONMETHODS = { - 'google.protobuf.Any': ['_AnyMessageToJsonObject', - '_ConvertAnyMessage'], - 'google.protobuf.Duration': ['_GenericMessageToJsonObject', - '_ConvertGenericMessage'], - 'google.protobuf.FieldMask': ['_GenericMessageToJsonObject', - '_ConvertGenericMessage'], - 'google.protobuf.ListValue': ['_ListValueMessageToJsonObject', - '_ConvertListValueMessage'], - 'google.protobuf.Struct': ['_StructMessageToJsonObject', - '_ConvertStructMessage'], - 'google.protobuf.Timestamp': ['_GenericMessageToJsonObject', - '_ConvertGenericMessage'], - 'google.protobuf.Value': ['_ValueMessageToJsonObject', - '_ConvertValueMessage'] -} diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/message.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/message.py deleted file mode 100644 index 76c6802f70..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/message.py +++ /dev/null @@ -1,424 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -# TODO(robinson): We should just make these methods all "pure-virtual" and move -# all implementation out, into reflection.py for now. - - -"""Contains an abstract base class for protocol messages.""" - -__author__ = 'robinson@google.com (Will Robinson)' - -class Error(Exception): - """Base error type for this module.""" - pass - - -class DecodeError(Error): - """Exception raised when deserializing messages.""" - pass - - -class EncodeError(Error): - """Exception raised when serializing messages.""" - pass - - -class Message(object): - - """Abstract base class for protocol messages. - - Protocol message classes are almost always generated by the protocol - compiler. These generated types subclass Message and implement the methods - shown below. - """ - - # TODO(robinson): Link to an HTML document here. - - # TODO(robinson): Document that instances of this class will also - # have an Extensions attribute with __getitem__ and __setitem__. - # Again, not sure how to best convey this. - - # TODO(robinson): Document that the class must also have a static - # RegisterExtension(extension_field) method. - # Not sure how to best express at this point. - - # TODO(robinson): Document these fields and methods. - - __slots__ = [] - - #: The :class:`google.protobuf.descriptor.Descriptor` for this message type. - DESCRIPTOR = None - - def __deepcopy__(self, memo=None): - clone = type(self)() - clone.MergeFrom(self) - return clone - - def __eq__(self, other_msg): - """Recursively compares two messages by value and structure.""" - raise NotImplementedError - - def __ne__(self, other_msg): - # Can't just say self != other_msg, since that would infinitely recurse. :) - return not self == other_msg - - def __hash__(self): - raise TypeError('unhashable object') - - def __str__(self): - """Outputs a human-readable representation of the message.""" - raise NotImplementedError - - def __unicode__(self): - """Outputs a human-readable representation of the message.""" - raise NotImplementedError - - def MergeFrom(self, other_msg): - """Merges the contents of the specified message into current message. - - This method merges the contents of the specified message into the current - message. Singular fields that are set in the specified message overwrite - the corresponding fields in the current message. Repeated fields are - appended. Singular sub-messages and groups are recursively merged. - - Args: - other_msg (Message): A message to merge into the current message. - """ - raise NotImplementedError - - def CopyFrom(self, other_msg): - """Copies the content of the specified message into the current message. - - The method clears the current message and then merges the specified - message using MergeFrom. - - Args: - other_msg (Message): A message to copy into the current one. - """ - if self is other_msg: - return - self.Clear() - self.MergeFrom(other_msg) - - def Clear(self): - """Clears all data that was set in the message.""" - raise NotImplementedError - - def SetInParent(self): - """Mark this as present in the parent. - - This normally happens automatically when you assign a field of a - sub-message, but sometimes you want to make the sub-message - present while keeping it empty. If you find yourself using this, - you may want to reconsider your design. - """ - raise NotImplementedError - - def IsInitialized(self): - """Checks if the message is initialized. - - Returns: - bool: The method returns True if the message is initialized (i.e. all of - its required fields are set). - """ - raise NotImplementedError - - # TODO(robinson): MergeFromString() should probably return None and be - # implemented in terms of a helper that returns the # of bytes read. Our - # deserialization routines would use the helper when recursively - # deserializing, but the end user would almost always just want the no-return - # MergeFromString(). - - def MergeFromString(self, serialized): - """Merges serialized protocol buffer data into this message. - - When we find a field in `serialized` that is already present - in this message: - - - If it's a "repeated" field, we append to the end of our list. - - Else, if it's a scalar, we overwrite our field. - - Else, (it's a nonrepeated composite), we recursively merge - into the existing composite. - - Args: - serialized (bytes): Any object that allows us to call - ``memoryview(serialized)`` to access a string of bytes using the - buffer interface. - - Returns: - int: The number of bytes read from `serialized`. - For non-group messages, this will always be `len(serialized)`, - but for messages which are actually groups, this will - generally be less than `len(serialized)`, since we must - stop when we reach an ``END_GROUP`` tag. Note that if - we *do* stop because of an ``END_GROUP`` tag, the number - of bytes returned does not include the bytes - for the ``END_GROUP`` tag information. - - Raises: - DecodeError: if the input cannot be parsed. - """ - # TODO(robinson): Document handling of unknown fields. - # TODO(robinson): When we switch to a helper, this will return None. - raise NotImplementedError - - def ParseFromString(self, serialized): - """Parse serialized protocol buffer data into this message. - - Like :func:`MergeFromString()`, except we clear the object first. - - Raises: - message.DecodeError if the input cannot be parsed. - """ - self.Clear() - return self.MergeFromString(serialized) - - def SerializeToString(self, **kwargs): - """Serializes the protocol message to a binary string. - - Keyword Args: - deterministic (bool): If true, requests deterministic serialization - of the protobuf, with predictable ordering of map keys. - - Returns: - A binary string representation of the message if all of the required - fields in the message are set (i.e. the message is initialized). - - Raises: - EncodeError: if the message isn't initialized (see :func:`IsInitialized`). - """ - raise NotImplementedError - - def SerializePartialToString(self, **kwargs): - """Serializes the protocol message to a binary string. - - This method is similar to SerializeToString but doesn't check if the - message is initialized. - - Keyword Args: - deterministic (bool): If true, requests deterministic serialization - of the protobuf, with predictable ordering of map keys. - - Returns: - bytes: A serialized representation of the partial message. - """ - raise NotImplementedError - - # TODO(robinson): Decide whether we like these better - # than auto-generated has_foo() and clear_foo() methods - # on the instances themselves. This way is less consistent - # with C++, but it makes reflection-type access easier and - # reduces the number of magically autogenerated things. - # - # TODO(robinson): Be sure to document (and test) exactly - # which field names are accepted here. Are we case-sensitive? - # What do we do with fields that share names with Python keywords - # like 'lambda' and 'yield'? - # - # nnorwitz says: - # """ - # Typically (in python), an underscore is appended to names that are - # keywords. So they would become lambda_ or yield_. - # """ - def ListFields(self): - """Returns a list of (FieldDescriptor, value) tuples for present fields. - - A message field is non-empty if HasField() would return true. A singular - primitive field is non-empty if HasField() would return true in proto2 or it - is non zero in proto3. A repeated field is non-empty if it contains at least - one element. The fields are ordered by field number. - - Returns: - list[tuple(FieldDescriptor, value)]: field descriptors and values - for all fields in the message which are not empty. The values vary by - field type. - """ - raise NotImplementedError - - def HasField(self, field_name): - """Checks if a certain field is set for the message. - - For a oneof group, checks if any field inside is set. Note that if the - field_name is not defined in the message descriptor, :exc:`ValueError` will - be raised. - - Args: - field_name (str): The name of the field to check for presence. - - Returns: - bool: Whether a value has been set for the named field. - - Raises: - ValueError: if the `field_name` is not a member of this message. - """ - raise NotImplementedError - - def ClearField(self, field_name): - """Clears the contents of a given field. - - Inside a oneof group, clears the field set. If the name neither refers to a - defined field or oneof group, :exc:`ValueError` is raised. - - Args: - field_name (str): The name of the field to check for presence. - - Raises: - ValueError: if the `field_name` is not a member of this message. - """ - raise NotImplementedError - - def WhichOneof(self, oneof_group): - """Returns the name of the field that is set inside a oneof group. - - If no field is set, returns None. - - Args: - oneof_group (str): the name of the oneof group to check. - - Returns: - str or None: The name of the group that is set, or None. - - Raises: - ValueError: no group with the given name exists - """ - raise NotImplementedError - - def HasExtension(self, extension_handle): - """Checks if a certain extension is present for this message. - - Extensions are retrieved using the :attr:`Extensions` mapping (if present). - - Args: - extension_handle: The handle for the extension to check. - - Returns: - bool: Whether the extension is present for this message. - - Raises: - KeyError: if the extension is repeated. Similar to repeated fields, - there is no separate notion of presence: a "not present" repeated - extension is an empty list. - """ - raise NotImplementedError - - def ClearExtension(self, extension_handle): - """Clears the contents of a given extension. - - Args: - extension_handle: The handle for the extension to clear. - """ - raise NotImplementedError - - def UnknownFields(self): - """Returns the UnknownFieldSet. - - Returns: - UnknownFieldSet: The unknown fields stored in this message. - """ - raise NotImplementedError - - def DiscardUnknownFields(self): - """Clears all fields in the :class:`UnknownFieldSet`. - - This operation is recursive for nested message. - """ - raise NotImplementedError - - def ByteSize(self): - """Returns the serialized size of this message. - - Recursively calls ByteSize() on all contained messages. - - Returns: - int: The number of bytes required to serialize this message. - """ - raise NotImplementedError - - @classmethod - def FromString(cls, s): - raise NotImplementedError - - @staticmethod - def RegisterExtension(extension_handle): - raise NotImplementedError - - def _SetListener(self, message_listener): - """Internal method used by the protocol message implementation. - Clients should not call this directly. - - Sets a listener that this message will call on certain state transitions. - - The purpose of this method is to register back-edges from children to - parents at runtime, for the purpose of setting "has" bits and - byte-size-dirty bits in the parent and ancestor objects whenever a child or - descendant object is modified. - - If the client wants to disconnect this Message from the object tree, she - explicitly sets callback to None. - - If message_listener is None, unregisters any existing listener. Otherwise, - message_listener must implement the MessageListener interface in - internal/message_listener.py, and we discard any listener registered - via a previous _SetListener() call. - """ - raise NotImplementedError - - def __getstate__(self): - """Support the pickle protocol.""" - return dict(serialized=self.SerializePartialToString()) - - def __setstate__(self, state): - """Support the pickle protocol.""" - self.__init__() - serialized = state['serialized'] - # On Python 3, using encoding='latin1' is required for unpickling - # protos pickled by Python 2. - if not isinstance(serialized, bytes): - serialized = serialized.encode('latin1') - self.ParseFromString(serialized) - - def __reduce__(self): - message_descriptor = self.DESCRIPTOR - if message_descriptor.containing_type is None: - return type(self), (), self.__getstate__() - # the message type must be nested. - # Python does not pickle nested classes; use the symbol_database on the - # receiving end. - container = message_descriptor - return (_InternalConstructMessage, (container.full_name,), - self.__getstate__()) - - -def _InternalConstructMessage(full_name): - """Constructs a nested message.""" - from google.protobuf import symbol_database # pylint:disable=g-import-not-at-top - - return symbol_database.Default().GetSymbol(full_name)() diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/message_factory.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/message_factory.py deleted file mode 100644 index 3656fa6874..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/message_factory.py +++ /dev/null @@ -1,185 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Provides a factory class for generating dynamic messages. - -The easiest way to use this class is if you have access to the FileDescriptor -protos containing the messages you want to create you can just do the following: - -message_classes = message_factory.GetMessages(iterable_of_file_descriptors) -my_proto_instance = message_classes['some.proto.package.MessageName']() -""" - -__author__ = 'matthewtoia@google.com (Matt Toia)' - -from google.protobuf.internal import api_implementation -from google.protobuf import descriptor_pool -from google.protobuf import message - -if api_implementation.Type() == 'cpp': - from google.protobuf.pyext import cpp_message as message_impl -else: - from google.protobuf.internal import python_message as message_impl - - -# The type of all Message classes. -_GENERATED_PROTOCOL_MESSAGE_TYPE = message_impl.GeneratedProtocolMessageType - - -class MessageFactory(object): - """Factory for creating Proto2 messages from descriptors in a pool.""" - - def __init__(self, pool=None): - """Initializes a new factory.""" - self.pool = pool or descriptor_pool.DescriptorPool() - - # local cache of all classes built from protobuf descriptors - self._classes = {} - - def GetPrototype(self, descriptor): - """Obtains a proto2 message class based on the passed in descriptor. - - Passing a descriptor with a fully qualified name matching a previous - invocation will cause the same class to be returned. - - Args: - descriptor: The descriptor to build from. - - Returns: - A class describing the passed in descriptor. - """ - if descriptor not in self._classes: - result_class = self.CreatePrototype(descriptor) - # The assignment to _classes is redundant for the base implementation, but - # might avoid confusion in cases where CreatePrototype gets overridden and - # does not call the base implementation. - self._classes[descriptor] = result_class - return result_class - return self._classes[descriptor] - - def CreatePrototype(self, descriptor): - """Builds a proto2 message class based on the passed in descriptor. - - Don't call this function directly, it always creates a new class. Call - GetPrototype() instead. This method is meant to be overridden in subblasses - to perform additional operations on the newly constructed class. - - Args: - descriptor: The descriptor to build from. - - Returns: - A class describing the passed in descriptor. - """ - descriptor_name = descriptor.name - result_class = _GENERATED_PROTOCOL_MESSAGE_TYPE( - descriptor_name, - (message.Message,), - { - 'DESCRIPTOR': descriptor, - # If module not set, it wrongly points to message_factory module. - '__module__': None, - }) - result_class._FACTORY = self # pylint: disable=protected-access - # Assign in _classes before doing recursive calls to avoid infinite - # recursion. - self._classes[descriptor] = result_class - for field in descriptor.fields: - if field.message_type: - self.GetPrototype(field.message_type) - for extension in result_class.DESCRIPTOR.extensions: - if extension.containing_type not in self._classes: - self.GetPrototype(extension.containing_type) - extended_class = self._classes[extension.containing_type] - extended_class.RegisterExtension(extension) - return result_class - - def GetMessages(self, files): - """Gets all the messages from a specified file. - - This will find and resolve dependencies, failing if the descriptor - pool cannot satisfy them. - - Args: - files: The file names to extract messages from. - - Returns: - A dictionary mapping proto names to the message classes. This will include - any dependent messages as well as any messages defined in the same file as - a specified message. - """ - result = {} - for file_name in files: - file_desc = self.pool.FindFileByName(file_name) - for desc in file_desc.message_types_by_name.values(): - result[desc.full_name] = self.GetPrototype(desc) - - # While the extension FieldDescriptors are created by the descriptor pool, - # the python classes created in the factory need them to be registered - # explicitly, which is done below. - # - # The call to RegisterExtension will specifically check if the - # extension was already registered on the object and either - # ignore the registration if the original was the same, or raise - # an error if they were different. - - for extension in file_desc.extensions_by_name.values(): - if extension.containing_type not in self._classes: - self.GetPrototype(extension.containing_type) - extended_class = self._classes[extension.containing_type] - extended_class.RegisterExtension(extension) - return result - - -_FACTORY = MessageFactory() - - -def GetMessages(file_protos): - """Builds a dictionary of all the messages available in a set of files. - - Args: - file_protos: Iterable of FileDescriptorProto to build messages out of. - - Returns: - A dictionary mapping proto names to the message classes. This will include - any dependent messages as well as any messages defined in the same file as - a specified message. - """ - # The cpp implementation of the protocol buffer library requires to add the - # message in topological order of the dependency graph. - file_by_name = {file_proto.name: file_proto for file_proto in file_protos} - def _AddFile(file_proto): - for dependency in file_proto.dependency: - if dependency in file_by_name: - # Remove from elements to be visited, in order to cut cycles. - _AddFile(file_by_name.pop(dependency)) - _FACTORY.pool.Add(file_proto) - while file_by_name: - _AddFile(file_by_name.popitem()[1]) - return _FACTORY.GetMessages([file_proto.name for file_proto in file_protos]) diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/proto_builder.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/proto_builder.py deleted file mode 100644 index a4667ce63e..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/proto_builder.py +++ /dev/null @@ -1,134 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Dynamic Protobuf class creator.""" - -from collections import OrderedDict -import hashlib -import os - -from google.protobuf import descriptor_pb2 -from google.protobuf import descriptor -from google.protobuf import message_factory - - -def _GetMessageFromFactory(factory, full_name): - """Get a proto class from the MessageFactory by name. - - Args: - factory: a MessageFactory instance. - full_name: str, the fully qualified name of the proto type. - Returns: - A class, for the type identified by full_name. - Raises: - KeyError, if the proto is not found in the factory's descriptor pool. - """ - proto_descriptor = factory.pool.FindMessageTypeByName(full_name) - proto_cls = factory.GetPrototype(proto_descriptor) - return proto_cls - - -def MakeSimpleProtoClass(fields, full_name=None, pool=None): - """Create a Protobuf class whose fields are basic types. - - Note: this doesn't validate field names! - - Args: - fields: dict of {name: field_type} mappings for each field in the proto. If - this is an OrderedDict the order will be maintained, otherwise the - fields will be sorted by name. - full_name: optional str, the fully-qualified name of the proto type. - pool: optional DescriptorPool instance. - Returns: - a class, the new protobuf class with a FileDescriptor. - """ - factory = message_factory.MessageFactory(pool=pool) - - if full_name is not None: - try: - proto_cls = _GetMessageFromFactory(factory, full_name) - return proto_cls - except KeyError: - # The factory's DescriptorPool doesn't know about this class yet. - pass - - # Get a list of (name, field_type) tuples from the fields dict. If fields was - # an OrderedDict we keep the order, but otherwise we sort the field to ensure - # consistent ordering. - field_items = fields.items() - if not isinstance(fields, OrderedDict): - field_items = sorted(field_items) - - # Use a consistent file name that is unlikely to conflict with any imported - # proto files. - fields_hash = hashlib.sha1() - for f_name, f_type in field_items: - fields_hash.update(f_name.encode('utf-8')) - fields_hash.update(str(f_type).encode('utf-8')) - proto_file_name = fields_hash.hexdigest() + '.proto' - - # If the proto is anonymous, use the same hash to name it. - if full_name is None: - full_name = ('net.proto2.python.public.proto_builder.AnonymousProto_' + - fields_hash.hexdigest()) - try: - proto_cls = _GetMessageFromFactory(factory, full_name) - return proto_cls - except KeyError: - # The factory's DescriptorPool doesn't know about this class yet. - pass - - # This is the first time we see this proto: add a new descriptor to the pool. - factory.pool.Add( - _MakeFileDescriptorProto(proto_file_name, full_name, field_items)) - return _GetMessageFromFactory(factory, full_name) - - -def _MakeFileDescriptorProto(proto_file_name, full_name, field_items): - """Populate FileDescriptorProto for MessageFactory's DescriptorPool.""" - package, name = full_name.rsplit('.', 1) - file_proto = descriptor_pb2.FileDescriptorProto() - file_proto.name = os.path.join(package.replace('.', '/'), proto_file_name) - file_proto.package = package - desc_proto = file_proto.message_type.add() - desc_proto.name = name - for f_number, (f_name, f_type) in enumerate(field_items, 1): - field_proto = desc_proto.field.add() - field_proto.name = f_name - # # If the number falls in the reserved range, reassign it to the correct - # # number after the range. - if f_number >= descriptor.FieldDescriptor.FIRST_RESERVED_FIELD_NUMBER: - f_number += ( - descriptor.FieldDescriptor.LAST_RESERVED_FIELD_NUMBER - - descriptor.FieldDescriptor.FIRST_RESERVED_FIELD_NUMBER + 1) - field_proto.number = f_number - field_proto.label = descriptor_pb2.FieldDescriptorProto.LABEL_OPTIONAL - field_proto.type = f_type - return file_proto diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/pyext/__init__.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/pyext/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/pyext/cpp_message.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/pyext/cpp_message.py deleted file mode 100644 index fc8eb32d79..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/pyext/cpp_message.py +++ /dev/null @@ -1,65 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Protocol message implementation hooks for C++ implementation. - -Contains helper functions used to create protocol message classes from -Descriptor objects at runtime backed by the protocol buffer C++ API. -""" - -__author__ = 'tibell@google.com (Johan Tibell)' - -from google.protobuf.pyext import _message - - -class GeneratedProtocolMessageType(_message.MessageMeta): - - """Metaclass for protocol message classes created at runtime from Descriptors. - - The protocol compiler currently uses this metaclass to create protocol - message classes at runtime. Clients can also manually create their own - classes at runtime, as in this example: - - mydescriptor = Descriptor(.....) - factory = symbol_database.Default() - factory.pool.AddDescriptor(mydescriptor) - MyProtoClass = factory.GetPrototype(mydescriptor) - myproto_instance = MyProtoClass() - myproto.foo_field = 23 - ... - - The above example will not work for nested types. If you wish to include them, - use reflection.MakeClass() instead of manually instantiating the class in - order to create the appropriate class structure. - """ - - # Must be consistent with the protocol-compiler code in - # proto2/compiler/internal/generator.*. - _DESCRIPTOR_KEY = 'DESCRIPTOR' diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/pyext/python_pb2.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/pyext/python_pb2.py deleted file mode 100644 index 2c6ecf4c98..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/pyext/python_pb2.py +++ /dev/null @@ -1,34 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/pyext/python.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\"google/protobuf/pyext/python.proto\x12\x1fgoogle.protobuf.python.internal\"\xbc\x02\n\x0cTestAllTypes\x12\\\n\x17repeated_nested_message\x18\x01 \x03(\x0b\x32;.google.protobuf.python.internal.TestAllTypes.NestedMessage\x12\\\n\x17optional_nested_message\x18\x02 \x01(\x0b\x32;.google.protobuf.python.internal.TestAllTypes.NestedMessage\x12\x16\n\x0eoptional_int32\x18\x03 \x01(\x05\x1aX\n\rNestedMessage\x12\n\n\x02\x62\x62\x18\x01 \x01(\x05\x12;\n\x02\x63\x63\x18\x02 \x01(\x0b\x32/.google.protobuf.python.internal.ForeignMessage\"&\n\x0e\x46oreignMessage\x12\t\n\x01\x63\x18\x01 \x01(\x05\x12\t\n\x01\x64\x18\x02 \x03(\x05\"\x1d\n\x11TestAllExtensions*\x08\x08\x01\x10\x80\x80\x80\x80\x02:\x9a\x01\n!optional_nested_message_extension\x12\x32.google.protobuf.python.internal.TestAllExtensions\x18\x01 \x01(\x0b\x32;.google.protobuf.python.internal.TestAllTypes.NestedMessage:\x9a\x01\n!repeated_nested_message_extension\x12\x32.google.protobuf.python.internal.TestAllExtensions\x18\x02 \x03(\x0b\x32;.google.protobuf.python.internal.TestAllTypes.NestedMessageB\x02H\x01') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.pyext.python_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - TestAllExtensions.RegisterExtension(optional_nested_message_extension) - TestAllExtensions.RegisterExtension(repeated_nested_message_extension) - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'H\001' - _TESTALLTYPES._serialized_start=72 - _TESTALLTYPES._serialized_end=388 - _TESTALLTYPES_NESTEDMESSAGE._serialized_start=300 - _TESTALLTYPES_NESTEDMESSAGE._serialized_end=388 - _FOREIGNMESSAGE._serialized_start=390 - _FOREIGNMESSAGE._serialized_end=428 - _TESTALLEXTENSIONS._serialized_start=430 - _TESTALLEXTENSIONS._serialized_end=459 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/reflection.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/reflection.py deleted file mode 100644 index 81e18859a8..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/reflection.py +++ /dev/null @@ -1,95 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -# This code is meant to work on Python 2.4 and above only. - -"""Contains a metaclass and helper functions used to create -protocol message classes from Descriptor objects at runtime. - -Recall that a metaclass is the "type" of a class. -(A class is to a metaclass what an instance is to a class.) - -In this case, we use the GeneratedProtocolMessageType metaclass -to inject all the useful functionality into the classes -output by the protocol compiler at compile-time. - -The upshot of all this is that the real implementation -details for ALL pure-Python protocol buffers are *here in -this file*. -""" - -__author__ = 'robinson@google.com (Will Robinson)' - - -from google.protobuf import message_factory -from google.protobuf import symbol_database - -# The type of all Message classes. -# Part of the public interface, but normally only used by message factories. -GeneratedProtocolMessageType = message_factory._GENERATED_PROTOCOL_MESSAGE_TYPE - -MESSAGE_CLASS_CACHE = {} - - -# Deprecated. Please NEVER use reflection.ParseMessage(). -def ParseMessage(descriptor, byte_str): - """Generate a new Message instance from this Descriptor and a byte string. - - DEPRECATED: ParseMessage is deprecated because it is using MakeClass(). - Please use MessageFactory.GetPrototype() instead. - - Args: - descriptor: Protobuf Descriptor object - byte_str: Serialized protocol buffer byte string - - Returns: - Newly created protobuf Message object. - """ - result_class = MakeClass(descriptor) - new_msg = result_class() - new_msg.ParseFromString(byte_str) - return new_msg - - -# Deprecated. Please NEVER use reflection.MakeClass(). -def MakeClass(descriptor): - """Construct a class object for a protobuf described by descriptor. - - DEPRECATED: use MessageFactory.GetPrototype() instead. - - Args: - descriptor: A descriptor.Descriptor object describing the protobuf. - Returns: - The Message class object described by the descriptor. - """ - # Original implementation leads to duplicate message classes, which won't play - # well with extensions. Message factory info is also missing. - # Redirect to message_factory. - return symbol_database.Default().GetPrototype(descriptor) diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/service.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/service.py deleted file mode 100644 index 5625246324..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/service.py +++ /dev/null @@ -1,228 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""DEPRECATED: Declares the RPC service interfaces. - -This module declares the abstract interfaces underlying proto2 RPC -services. These are intended to be independent of any particular RPC -implementation, so that proto2 services can be used on top of a variety -of implementations. Starting with version 2.3.0, RPC implementations should -not try to build on these, but should instead provide code generator plugins -which generate code specific to the particular RPC implementation. This way -the generated code can be more appropriate for the implementation in use -and can avoid unnecessary layers of indirection. -""" - -__author__ = 'petar@google.com (Petar Petrov)' - - -class RpcException(Exception): - """Exception raised on failed blocking RPC method call.""" - pass - - -class Service(object): - - """Abstract base interface for protocol-buffer-based RPC services. - - Services themselves are abstract classes (implemented either by servers or as - stubs), but they subclass this base interface. The methods of this - interface can be used to call the methods of the service without knowing - its exact type at compile time (analogous to the Message interface). - """ - - def GetDescriptor(): - """Retrieves this service's descriptor.""" - raise NotImplementedError - - def CallMethod(self, method_descriptor, rpc_controller, - request, done): - """Calls a method of the service specified by method_descriptor. - - If "done" is None then the call is blocking and the response - message will be returned directly. Otherwise the call is asynchronous - and "done" will later be called with the response value. - - In the blocking case, RpcException will be raised on error. - - Preconditions: - - * method_descriptor.service == GetDescriptor - * request is of the exact same classes as returned by - GetRequestClass(method). - * After the call has started, the request must not be modified. - * "rpc_controller" is of the correct type for the RPC implementation being - used by this Service. For stubs, the "correct type" depends on the - RpcChannel which the stub is using. - - Postconditions: - - * "done" will be called when the method is complete. This may be - before CallMethod() returns or it may be at some point in the future. - * If the RPC failed, the response value passed to "done" will be None. - Further details about the failure can be found by querying the - RpcController. - """ - raise NotImplementedError - - def GetRequestClass(self, method_descriptor): - """Returns the class of the request message for the specified method. - - CallMethod() requires that the request is of a particular subclass of - Message. GetRequestClass() gets the default instance of this required - type. - - Example: - method = service.GetDescriptor().FindMethodByName("Foo") - request = stub.GetRequestClass(method)() - request.ParseFromString(input) - service.CallMethod(method, request, callback) - """ - raise NotImplementedError - - def GetResponseClass(self, method_descriptor): - """Returns the class of the response message for the specified method. - - This method isn't really needed, as the RpcChannel's CallMethod constructs - the response protocol message. It's provided anyway in case it is useful - for the caller to know the response type in advance. - """ - raise NotImplementedError - - -class RpcController(object): - - """An RpcController mediates a single method call. - - The primary purpose of the controller is to provide a way to manipulate - settings specific to the RPC implementation and to find out about RPC-level - errors. The methods provided by the RpcController interface are intended - to be a "least common denominator" set of features which we expect all - implementations to support. Specific implementations may provide more - advanced features (e.g. deadline propagation). - """ - - # Client-side methods below - - def Reset(self): - """Resets the RpcController to its initial state. - - After the RpcController has been reset, it may be reused in - a new call. Must not be called while an RPC is in progress. - """ - raise NotImplementedError - - def Failed(self): - """Returns true if the call failed. - - After a call has finished, returns true if the call failed. The possible - reasons for failure depend on the RPC implementation. Failed() must not - be called before a call has finished. If Failed() returns true, the - contents of the response message are undefined. - """ - raise NotImplementedError - - def ErrorText(self): - """If Failed is true, returns a human-readable description of the error.""" - raise NotImplementedError - - def StartCancel(self): - """Initiate cancellation. - - Advises the RPC system that the caller desires that the RPC call be - canceled. The RPC system may cancel it immediately, may wait awhile and - then cancel it, or may not even cancel the call at all. If the call is - canceled, the "done" callback will still be called and the RpcController - will indicate that the call failed at that time. - """ - raise NotImplementedError - - # Server-side methods below - - def SetFailed(self, reason): - """Sets a failure reason. - - Causes Failed() to return true on the client side. "reason" will be - incorporated into the message returned by ErrorText(). If you find - you need to return machine-readable information about failures, you - should incorporate it into your response protocol buffer and should - NOT call SetFailed(). - """ - raise NotImplementedError - - def IsCanceled(self): - """Checks if the client cancelled the RPC. - - If true, indicates that the client canceled the RPC, so the server may - as well give up on replying to it. The server should still call the - final "done" callback. - """ - raise NotImplementedError - - def NotifyOnCancel(self, callback): - """Sets a callback to invoke on cancel. - - Asks that the given callback be called when the RPC is canceled. The - callback will always be called exactly once. If the RPC completes without - being canceled, the callback will be called after completion. If the RPC - has already been canceled when NotifyOnCancel() is called, the callback - will be called immediately. - - NotifyOnCancel() must be called no more than once per request. - """ - raise NotImplementedError - - -class RpcChannel(object): - - """Abstract interface for an RPC channel. - - An RpcChannel represents a communication line to a service which can be used - to call that service's methods. The service may be running on another - machine. Normally, you should not use an RpcChannel directly, but instead - construct a stub {@link Service} wrapping it. Example: - - Example: - RpcChannel channel = rpcImpl.Channel("remotehost.example.com:1234") - RpcController controller = rpcImpl.Controller() - MyService service = MyService_Stub(channel) - service.MyMethod(controller, request, callback) - """ - - def CallMethod(self, method_descriptor, rpc_controller, - request, response_class, done): - """Calls the method identified by the descriptor. - - Call the given method of the remote service. The signature of this - procedure looks the same as Service.CallMethod(), but the requirements - are less strict in one important way: the request object doesn't have to - be of any specific class as long as its descriptor is method.input_type. - """ - raise NotImplementedError diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/service_reflection.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/service_reflection.py deleted file mode 100644 index f82ab7145a..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/service_reflection.py +++ /dev/null @@ -1,295 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Contains metaclasses used to create protocol service and service stub -classes from ServiceDescriptor objects at runtime. - -The GeneratedServiceType and GeneratedServiceStubType metaclasses are used to -inject all useful functionality into the classes output by the protocol -compiler at compile-time. -""" - -__author__ = 'petar@google.com (Petar Petrov)' - - -class GeneratedServiceType(type): - - """Metaclass for service classes created at runtime from ServiceDescriptors. - - Implementations for all methods described in the Service class are added here - by this class. We also create properties to allow getting/setting all fields - in the protocol message. - - The protocol compiler currently uses this metaclass to create protocol service - classes at runtime. Clients can also manually create their own classes at - runtime, as in this example:: - - mydescriptor = ServiceDescriptor(.....) - class MyProtoService(service.Service): - __metaclass__ = GeneratedServiceType - DESCRIPTOR = mydescriptor - myservice_instance = MyProtoService() - # ... - """ - - _DESCRIPTOR_KEY = 'DESCRIPTOR' - - def __init__(cls, name, bases, dictionary): - """Creates a message service class. - - Args: - name: Name of the class (ignored, but required by the metaclass - protocol). - bases: Base classes of the class being constructed. - dictionary: The class dictionary of the class being constructed. - dictionary[_DESCRIPTOR_KEY] must contain a ServiceDescriptor object - describing this protocol service type. - """ - # Don't do anything if this class doesn't have a descriptor. This happens - # when a service class is subclassed. - if GeneratedServiceType._DESCRIPTOR_KEY not in dictionary: - return - - descriptor = dictionary[GeneratedServiceType._DESCRIPTOR_KEY] - service_builder = _ServiceBuilder(descriptor) - service_builder.BuildService(cls) - cls.DESCRIPTOR = descriptor - - -class GeneratedServiceStubType(GeneratedServiceType): - - """Metaclass for service stubs created at runtime from ServiceDescriptors. - - This class has similar responsibilities as GeneratedServiceType, except that - it creates the service stub classes. - """ - - _DESCRIPTOR_KEY = 'DESCRIPTOR' - - def __init__(cls, name, bases, dictionary): - """Creates a message service stub class. - - Args: - name: Name of the class (ignored, here). - bases: Base classes of the class being constructed. - dictionary: The class dictionary of the class being constructed. - dictionary[_DESCRIPTOR_KEY] must contain a ServiceDescriptor object - describing this protocol service type. - """ - super(GeneratedServiceStubType, cls).__init__(name, bases, dictionary) - # Don't do anything if this class doesn't have a descriptor. This happens - # when a service stub is subclassed. - if GeneratedServiceStubType._DESCRIPTOR_KEY not in dictionary: - return - - descriptor = dictionary[GeneratedServiceStubType._DESCRIPTOR_KEY] - service_stub_builder = _ServiceStubBuilder(descriptor) - service_stub_builder.BuildServiceStub(cls) - - -class _ServiceBuilder(object): - - """This class constructs a protocol service class using a service descriptor. - - Given a service descriptor, this class constructs a class that represents - the specified service descriptor. One service builder instance constructs - exactly one service class. That means all instances of that class share the - same builder. - """ - - def __init__(self, service_descriptor): - """Initializes an instance of the service class builder. - - Args: - service_descriptor: ServiceDescriptor to use when constructing the - service class. - """ - self.descriptor = service_descriptor - - def BuildService(builder, cls): - """Constructs the service class. - - Args: - cls: The class that will be constructed. - """ - - # CallMethod needs to operate with an instance of the Service class. This - # internal wrapper function exists only to be able to pass the service - # instance to the method that does the real CallMethod work. - # Making sure to use exact argument names from the abstract interface in - # service.py to match the type signature - def _WrapCallMethod(self, method_descriptor, rpc_controller, request, done): - return builder._CallMethod(self, method_descriptor, rpc_controller, - request, done) - - def _WrapGetRequestClass(self, method_descriptor): - return builder._GetRequestClass(method_descriptor) - - def _WrapGetResponseClass(self, method_descriptor): - return builder._GetResponseClass(method_descriptor) - - builder.cls = cls - cls.CallMethod = _WrapCallMethod - cls.GetDescriptor = staticmethod(lambda: builder.descriptor) - cls.GetDescriptor.__doc__ = 'Returns the service descriptor.' - cls.GetRequestClass = _WrapGetRequestClass - cls.GetResponseClass = _WrapGetResponseClass - for method in builder.descriptor.methods: - setattr(cls, method.name, builder._GenerateNonImplementedMethod(method)) - - def _CallMethod(self, srvc, method_descriptor, - rpc_controller, request, callback): - """Calls the method described by a given method descriptor. - - Args: - srvc: Instance of the service for which this method is called. - method_descriptor: Descriptor that represent the method to call. - rpc_controller: RPC controller to use for this method's execution. - request: Request protocol message. - callback: A callback to invoke after the method has completed. - """ - if method_descriptor.containing_service != self.descriptor: - raise RuntimeError( - 'CallMethod() given method descriptor for wrong service type.') - method = getattr(srvc, method_descriptor.name) - return method(rpc_controller, request, callback) - - def _GetRequestClass(self, method_descriptor): - """Returns the class of the request protocol message. - - Args: - method_descriptor: Descriptor of the method for which to return the - request protocol message class. - - Returns: - A class that represents the input protocol message of the specified - method. - """ - if method_descriptor.containing_service != self.descriptor: - raise RuntimeError( - 'GetRequestClass() given method descriptor for wrong service type.') - return method_descriptor.input_type._concrete_class - - def _GetResponseClass(self, method_descriptor): - """Returns the class of the response protocol message. - - Args: - method_descriptor: Descriptor of the method for which to return the - response protocol message class. - - Returns: - A class that represents the output protocol message of the specified - method. - """ - if method_descriptor.containing_service != self.descriptor: - raise RuntimeError( - 'GetResponseClass() given method descriptor for wrong service type.') - return method_descriptor.output_type._concrete_class - - def _GenerateNonImplementedMethod(self, method): - """Generates and returns a method that can be set for a service methods. - - Args: - method: Descriptor of the service method for which a method is to be - generated. - - Returns: - A method that can be added to the service class. - """ - return lambda inst, rpc_controller, request, callback: ( - self._NonImplementedMethod(method.name, rpc_controller, callback)) - - def _NonImplementedMethod(self, method_name, rpc_controller, callback): - """The body of all methods in the generated service class. - - Args: - method_name: Name of the method being executed. - rpc_controller: RPC controller used to execute this method. - callback: A callback which will be invoked when the method finishes. - """ - rpc_controller.SetFailed('Method %s not implemented.' % method_name) - callback(None) - - -class _ServiceStubBuilder(object): - - """Constructs a protocol service stub class using a service descriptor. - - Given a service descriptor, this class constructs a suitable stub class. - A stub is just a type-safe wrapper around an RpcChannel which emulates a - local implementation of the service. - - One service stub builder instance constructs exactly one class. It means all - instances of that class share the same service stub builder. - """ - - def __init__(self, service_descriptor): - """Initializes an instance of the service stub class builder. - - Args: - service_descriptor: ServiceDescriptor to use when constructing the - stub class. - """ - self.descriptor = service_descriptor - - def BuildServiceStub(self, cls): - """Constructs the stub class. - - Args: - cls: The class that will be constructed. - """ - - def _ServiceStubInit(stub, rpc_channel): - stub.rpc_channel = rpc_channel - self.cls = cls - cls.__init__ = _ServiceStubInit - for method in self.descriptor.methods: - setattr(cls, method.name, self._GenerateStubMethod(method)) - - def _GenerateStubMethod(self, method): - return (lambda inst, rpc_controller, request, callback=None: - self._StubMethod(inst, method, rpc_controller, request, callback)) - - def _StubMethod(self, stub, method_descriptor, - rpc_controller, request, callback): - """The body of all service methods in the generated stub class. - - Args: - stub: Stub instance. - method_descriptor: Descriptor of the invoked method. - rpc_controller: Rpc controller to execute the method. - request: Request protocol message. - callback: A callback to execute when the method finishes. - Returns: - Response message (in case of blocking call). - """ - return stub.rpc_channel.CallMethod( - method_descriptor, rpc_controller, request, - method_descriptor.output_type._concrete_class, callback) diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/source_context_pb2.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/source_context_pb2.py deleted file mode 100644 index 30cca2e06e..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/source_context_pb2.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/source_context.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$google/protobuf/source_context.proto\x12\x0fgoogle.protobuf\"\"\n\rSourceContext\x12\x11\n\tfile_name\x18\x01 \x01(\tB\x8a\x01\n\x13\x63om.google.protobufB\x12SourceContextProtoP\x01Z6google.golang.org/protobuf/types/known/sourcecontextpb\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.source_context_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.google.protobufB\022SourceContextProtoP\001Z6google.golang.org/protobuf/types/known/sourcecontextpb\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' - _SOURCECONTEXT._serialized_start=57 - _SOURCECONTEXT._serialized_end=91 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/struct_pb2.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/struct_pb2.py deleted file mode 100644 index 149728ca08..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/struct_pb2.py +++ /dev/null @@ -1,36 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/struct.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1cgoogle/protobuf/struct.proto\x12\x0fgoogle.protobuf\"\x84\x01\n\x06Struct\x12\x33\n\x06\x66ields\x18\x01 \x03(\x0b\x32#.google.protobuf.Struct.FieldsEntry\x1a\x45\n\x0b\x46ieldsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12%\n\x05value\x18\x02 \x01(\x0b\x32\x16.google.protobuf.Value:\x02\x38\x01\"\xea\x01\n\x05Value\x12\x30\n\nnull_value\x18\x01 \x01(\x0e\x32\x1a.google.protobuf.NullValueH\x00\x12\x16\n\x0cnumber_value\x18\x02 \x01(\x01H\x00\x12\x16\n\x0cstring_value\x18\x03 \x01(\tH\x00\x12\x14\n\nbool_value\x18\x04 \x01(\x08H\x00\x12/\n\x0cstruct_value\x18\x05 \x01(\x0b\x32\x17.google.protobuf.StructH\x00\x12\x30\n\nlist_value\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.ListValueH\x00\x42\x06\n\x04kind\"3\n\tListValue\x12&\n\x06values\x18\x01 \x03(\x0b\x32\x16.google.protobuf.Value*\x1b\n\tNullValue\x12\x0e\n\nNULL_VALUE\x10\x00\x42\x7f\n\x13\x63om.google.protobufB\x0bStructProtoP\x01Z/google.golang.org/protobuf/types/known/structpb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.struct_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.google.protobufB\013StructProtoP\001Z/google.golang.org/protobuf/types/known/structpb\370\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' - _STRUCT_FIELDSENTRY._options = None - _STRUCT_FIELDSENTRY._serialized_options = b'8\001' - _NULLVALUE._serialized_start=474 - _NULLVALUE._serialized_end=501 - _STRUCT._serialized_start=50 - _STRUCT._serialized_end=182 - _STRUCT_FIELDSENTRY._serialized_start=113 - _STRUCT_FIELDSENTRY._serialized_end=182 - _VALUE._serialized_start=185 - _VALUE._serialized_end=419 - _LISTVALUE._serialized_start=421 - _LISTVALUE._serialized_end=472 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/symbol_database.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/symbol_database.py deleted file mode 100644 index fdcf8cf06c..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/symbol_database.py +++ /dev/null @@ -1,194 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""A database of Python protocol buffer generated symbols. - -SymbolDatabase is the MessageFactory for messages generated at compile time, -and makes it easy to create new instances of a registered type, given only the -type's protocol buffer symbol name. - -Example usage:: - - db = symbol_database.SymbolDatabase() - - # Register symbols of interest, from one or multiple files. - db.RegisterFileDescriptor(my_proto_pb2.DESCRIPTOR) - db.RegisterMessage(my_proto_pb2.MyMessage) - db.RegisterEnumDescriptor(my_proto_pb2.MyEnum.DESCRIPTOR) - - # The database can be used as a MessageFactory, to generate types based on - # their name: - types = db.GetMessages(['my_proto.proto']) - my_message_instance = types['MyMessage']() - - # The database's underlying descriptor pool can be queried, so it's not - # necessary to know a type's filename to be able to generate it: - filename = db.pool.FindFileContainingSymbol('MyMessage') - my_message_instance = db.GetMessages([filename])['MyMessage']() - - # This functionality is also provided directly via a convenience method: - my_message_instance = db.GetSymbol('MyMessage')() -""" - - -from google.protobuf.internal import api_implementation -from google.protobuf import descriptor_pool -from google.protobuf import message_factory - - -class SymbolDatabase(message_factory.MessageFactory): - """A database of Python generated symbols.""" - - def RegisterMessage(self, message): - """Registers the given message type in the local database. - - Calls to GetSymbol() and GetMessages() will return messages registered here. - - Args: - message: A :class:`google.protobuf.message.Message` subclass (or - instance); its descriptor will be registered. - - Returns: - The provided message. - """ - - desc = message.DESCRIPTOR - self._classes[desc] = message - self.RegisterMessageDescriptor(desc) - return message - - def RegisterMessageDescriptor(self, message_descriptor): - """Registers the given message descriptor in the local database. - - Args: - message_descriptor (Descriptor): the message descriptor to add. - """ - if api_implementation.Type() == 'python': - # pylint: disable=protected-access - self.pool._AddDescriptor(message_descriptor) - - def RegisterEnumDescriptor(self, enum_descriptor): - """Registers the given enum descriptor in the local database. - - Args: - enum_descriptor (EnumDescriptor): The enum descriptor to register. - - Returns: - EnumDescriptor: The provided descriptor. - """ - if api_implementation.Type() == 'python': - # pylint: disable=protected-access - self.pool._AddEnumDescriptor(enum_descriptor) - return enum_descriptor - - def RegisterServiceDescriptor(self, service_descriptor): - """Registers the given service descriptor in the local database. - - Args: - service_descriptor (ServiceDescriptor): the service descriptor to - register. - """ - if api_implementation.Type() == 'python': - # pylint: disable=protected-access - self.pool._AddServiceDescriptor(service_descriptor) - - def RegisterFileDescriptor(self, file_descriptor): - """Registers the given file descriptor in the local database. - - Args: - file_descriptor (FileDescriptor): The file descriptor to register. - """ - if api_implementation.Type() == 'python': - # pylint: disable=protected-access - self.pool._InternalAddFileDescriptor(file_descriptor) - - def GetSymbol(self, symbol): - """Tries to find a symbol in the local database. - - Currently, this method only returns message.Message instances, however, if - may be extended in future to support other symbol types. - - Args: - symbol (str): a protocol buffer symbol. - - Returns: - A Python class corresponding to the symbol. - - Raises: - KeyError: if the symbol could not be found. - """ - - return self._classes[self.pool.FindMessageTypeByName(symbol)] - - def GetMessages(self, files): - # TODO(amauryfa): Fix the differences with MessageFactory. - """Gets all registered messages from a specified file. - - Only messages already created and registered will be returned; (this is the - case for imported _pb2 modules) - But unlike MessageFactory, this version also returns already defined nested - messages, but does not register any message extensions. - - Args: - files (list[str]): The file names to extract messages from. - - Returns: - A dictionary mapping proto names to the message classes. - - Raises: - KeyError: if a file could not be found. - """ - - def _GetAllMessages(desc): - """Walk a message Descriptor and recursively yields all message names.""" - yield desc - for msg_desc in desc.nested_types: - for nested_desc in _GetAllMessages(msg_desc): - yield nested_desc - - result = {} - for file_name in files: - file_desc = self.pool.FindFileByName(file_name) - for msg_desc in file_desc.message_types_by_name.values(): - for desc in _GetAllMessages(msg_desc): - try: - result[desc.full_name] = self._classes[desc] - except KeyError: - # This descriptor has no registered class, skip it. - pass - return result - - -_DEFAULT = SymbolDatabase(pool=descriptor_pool.Default()) - - -def Default(): - """Returns the default SymbolDatabase.""" - return _DEFAULT diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/text_encoding.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/text_encoding.py deleted file mode 100644 index 759cf11f62..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/text_encoding.py +++ /dev/null @@ -1,110 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Encoding related utilities.""" -import re - -_cescape_chr_to_symbol_map = {} -_cescape_chr_to_symbol_map[9] = r'\t' # optional escape -_cescape_chr_to_symbol_map[10] = r'\n' # optional escape -_cescape_chr_to_symbol_map[13] = r'\r' # optional escape -_cescape_chr_to_symbol_map[34] = r'\"' # necessary escape -_cescape_chr_to_symbol_map[39] = r"\'" # optional escape -_cescape_chr_to_symbol_map[92] = r'\\' # necessary escape - -# Lookup table for unicode -_cescape_unicode_to_str = [chr(i) for i in range(0, 256)] -for byte, string in _cescape_chr_to_symbol_map.items(): - _cescape_unicode_to_str[byte] = string - -# Lookup table for non-utf8, with necessary escapes at (o >= 127 or o < 32) -_cescape_byte_to_str = ([r'\%03o' % i for i in range(0, 32)] + - [chr(i) for i in range(32, 127)] + - [r'\%03o' % i for i in range(127, 256)]) -for byte, string in _cescape_chr_to_symbol_map.items(): - _cescape_byte_to_str[byte] = string -del byte, string - - -def CEscape(text, as_utf8): - # type: (...) -> str - """Escape a bytes string for use in an text protocol buffer. - - Args: - text: A byte string to be escaped. - as_utf8: Specifies if result may contain non-ASCII characters. - In Python 3 this allows unescaped non-ASCII Unicode characters. - In Python 2 the return value will be valid UTF-8 rather than only ASCII. - Returns: - Escaped string (str). - """ - # Python's text.encode() 'string_escape' or 'unicode_escape' codecs do not - # satisfy our needs; they encodes unprintable characters using two-digit hex - # escapes whereas our C++ unescaping function allows hex escapes to be any - # length. So, "\0011".encode('string_escape') ends up being "\\x011", which - # will be decoded in C++ as a single-character string with char code 0x11. - text_is_unicode = isinstance(text, str) - if as_utf8 and text_is_unicode: - # We're already unicode, no processing beyond control char escapes. - return text.translate(_cescape_chr_to_symbol_map) - ord_ = ord if text_is_unicode else lambda x: x # bytes iterate as ints. - if as_utf8: - return ''.join(_cescape_unicode_to_str[ord_(c)] for c in text) - return ''.join(_cescape_byte_to_str[ord_(c)] for c in text) - - -_CUNESCAPE_HEX = re.compile(r'(\\+)x([0-9a-fA-F])(?![0-9a-fA-F])') - - -def CUnescape(text): - # type: (str) -> bytes - """Unescape a text string with C-style escape sequences to UTF-8 bytes. - - Args: - text: The data to parse in a str. - Returns: - A byte string. - """ - - def ReplaceHex(m): - # Only replace the match if the number of leading back slashes is odd. i.e. - # the slash itself is not escaped. - if len(m.group(1)) & 1: - return m.group(1) + 'x0' + m.group(2) - return m.group(0) - - # This is required because the 'string_escape' encoding doesn't - # allow single-digit hex escapes (like '\xf'). - result = _CUNESCAPE_HEX.sub(ReplaceHex, text) - - return (result.encode('utf-8') # Make it bytes to allow decode. - .decode('unicode_escape') - # Make it bytes again to return the proper type. - .encode('raw_unicode_escape')) diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/text_format.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/text_format.py deleted file mode 100644 index 412385c26f..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/text_format.py +++ /dev/null @@ -1,1795 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Contains routines for printing protocol messages in text format. - -Simple usage example:: - - # Create a proto object and serialize it to a text proto string. - message = my_proto_pb2.MyMessage(foo='bar') - text_proto = text_format.MessageToString(message) - - # Parse a text proto string. - message = text_format.Parse(text_proto, my_proto_pb2.MyMessage()) -""" - -__author__ = 'kenton@google.com (Kenton Varda)' - -# TODO(b/129989314) Import thread contention leads to test failures. -import encodings.raw_unicode_escape # pylint: disable=unused-import -import encodings.unicode_escape # pylint: disable=unused-import -import io -import math -import re - -from google.protobuf.internal import decoder -from google.protobuf.internal import type_checkers -from google.protobuf import descriptor -from google.protobuf import text_encoding - -# pylint: disable=g-import-not-at-top -__all__ = ['MessageToString', 'Parse', 'PrintMessage', 'PrintField', - 'PrintFieldValue', 'Merge', 'MessageToBytes'] - -_INTEGER_CHECKERS = (type_checkers.Uint32ValueChecker(), - type_checkers.Int32ValueChecker(), - type_checkers.Uint64ValueChecker(), - type_checkers.Int64ValueChecker()) -_FLOAT_INFINITY = re.compile('-?inf(?:inity)?f?$', re.IGNORECASE) -_FLOAT_NAN = re.compile('nanf?$', re.IGNORECASE) -_QUOTES = frozenset(("'", '"')) -_ANY_FULL_TYPE_NAME = 'google.protobuf.Any' - - -class Error(Exception): - """Top-level module error for text_format.""" - - -class ParseError(Error): - """Thrown in case of text parsing or tokenizing error.""" - - def __init__(self, message=None, line=None, column=None): - if message is not None and line is not None: - loc = str(line) - if column is not None: - loc += ':{0}'.format(column) - message = '{0} : {1}'.format(loc, message) - if message is not None: - super(ParseError, self).__init__(message) - else: - super(ParseError, self).__init__() - self._line = line - self._column = column - - def GetLine(self): - return self._line - - def GetColumn(self): - return self._column - - -class TextWriter(object): - - def __init__(self, as_utf8): - self._writer = io.StringIO() - - def write(self, val): - return self._writer.write(val) - - def close(self): - return self._writer.close() - - def getvalue(self): - return self._writer.getvalue() - - -def MessageToString( - message, - as_utf8=False, - as_one_line=False, - use_short_repeated_primitives=False, - pointy_brackets=False, - use_index_order=False, - float_format=None, - double_format=None, - use_field_number=False, - descriptor_pool=None, - indent=0, - message_formatter=None, - print_unknown_fields=False, - force_colon=False): - # type: (...) -> str - """Convert protobuf message to text format. - - Double values can be formatted compactly with 15 digits of - precision (which is the most that IEEE 754 "double" can guarantee) - using double_format='.15g'. To ensure that converting to text and back to a - proto will result in an identical value, double_format='.17g' should be used. - - Args: - message: The protocol buffers message. - as_utf8: Return unescaped Unicode for non-ASCII characters. - In Python 3 actual Unicode characters may appear as is in strings. - In Python 2 the return value will be valid UTF-8 rather than only ASCII. - as_one_line: Don't introduce newlines between fields. - use_short_repeated_primitives: Use short repeated format for primitives. - pointy_brackets: If True, use angle brackets instead of curly braces for - nesting. - use_index_order: If True, fields of a proto message will be printed using - the order defined in source code instead of the field number, extensions - will be printed at the end of the message and their relative order is - determined by the extension number. By default, use the field number - order. - float_format (str): If set, use this to specify float field formatting - (per the "Format Specification Mini-Language"); otherwise, shortest float - that has same value in wire will be printed. Also affect double field - if double_format is not set but float_format is set. - double_format (str): If set, use this to specify double field formatting - (per the "Format Specification Mini-Language"); if it is not set but - float_format is set, use float_format. Otherwise, use ``str()`` - use_field_number: If True, print field numbers instead of names. - descriptor_pool (DescriptorPool): Descriptor pool used to resolve Any types. - indent (int): The initial indent level, in terms of spaces, for pretty - print. - message_formatter (function(message, indent, as_one_line) -> unicode|None): - Custom formatter for selected sub-messages (usually based on message - type). Use to pretty print parts of the protobuf for easier diffing. - print_unknown_fields: If True, unknown fields will be printed. - force_colon: If set, a colon will be added after the field name even if the - field is a proto message. - - Returns: - str: A string of the text formatted protocol buffer message. - """ - out = TextWriter(as_utf8) - printer = _Printer( - out, - indent, - as_utf8, - as_one_line, - use_short_repeated_primitives, - pointy_brackets, - use_index_order, - float_format, - double_format, - use_field_number, - descriptor_pool, - message_formatter, - print_unknown_fields=print_unknown_fields, - force_colon=force_colon) - printer.PrintMessage(message) - result = out.getvalue() - out.close() - if as_one_line: - return result.rstrip() - return result - - -def MessageToBytes(message, **kwargs): - # type: (...) -> bytes - """Convert protobuf message to encoded text format. See MessageToString.""" - text = MessageToString(message, **kwargs) - if isinstance(text, bytes): - return text - codec = 'utf-8' if kwargs.get('as_utf8') else 'ascii' - return text.encode(codec) - - -def _IsMapEntry(field): - return (field.type == descriptor.FieldDescriptor.TYPE_MESSAGE and - field.message_type.has_options and - field.message_type.GetOptions().map_entry) - - -def PrintMessage(message, - out, - indent=0, - as_utf8=False, - as_one_line=False, - use_short_repeated_primitives=False, - pointy_brackets=False, - use_index_order=False, - float_format=None, - double_format=None, - use_field_number=False, - descriptor_pool=None, - message_formatter=None, - print_unknown_fields=False, - force_colon=False): - printer = _Printer( - out=out, indent=indent, as_utf8=as_utf8, - as_one_line=as_one_line, - use_short_repeated_primitives=use_short_repeated_primitives, - pointy_brackets=pointy_brackets, - use_index_order=use_index_order, - float_format=float_format, - double_format=double_format, - use_field_number=use_field_number, - descriptor_pool=descriptor_pool, - message_formatter=message_formatter, - print_unknown_fields=print_unknown_fields, - force_colon=force_colon) - printer.PrintMessage(message) - - -def PrintField(field, - value, - out, - indent=0, - as_utf8=False, - as_one_line=False, - use_short_repeated_primitives=False, - pointy_brackets=False, - use_index_order=False, - float_format=None, - double_format=None, - message_formatter=None, - print_unknown_fields=False, - force_colon=False): - """Print a single field name/value pair.""" - printer = _Printer(out, indent, as_utf8, as_one_line, - use_short_repeated_primitives, pointy_brackets, - use_index_order, float_format, double_format, - message_formatter=message_formatter, - print_unknown_fields=print_unknown_fields, - force_colon=force_colon) - printer.PrintField(field, value) - - -def PrintFieldValue(field, - value, - out, - indent=0, - as_utf8=False, - as_one_line=False, - use_short_repeated_primitives=False, - pointy_brackets=False, - use_index_order=False, - float_format=None, - double_format=None, - message_formatter=None, - print_unknown_fields=False, - force_colon=False): - """Print a single field value (not including name).""" - printer = _Printer(out, indent, as_utf8, as_one_line, - use_short_repeated_primitives, pointy_brackets, - use_index_order, float_format, double_format, - message_formatter=message_formatter, - print_unknown_fields=print_unknown_fields, - force_colon=force_colon) - printer.PrintFieldValue(field, value) - - -def _BuildMessageFromTypeName(type_name, descriptor_pool): - """Returns a protobuf message instance. - - Args: - type_name: Fully-qualified protobuf message type name string. - descriptor_pool: DescriptorPool instance. - - Returns: - A Message instance of type matching type_name, or None if the a Descriptor - wasn't found matching type_name. - """ - # pylint: disable=g-import-not-at-top - if descriptor_pool is None: - from google.protobuf import descriptor_pool as pool_mod - descriptor_pool = pool_mod.Default() - from google.protobuf import symbol_database - database = symbol_database.Default() - try: - message_descriptor = descriptor_pool.FindMessageTypeByName(type_name) - except KeyError: - return None - message_type = database.GetPrototype(message_descriptor) - return message_type() - - -# These values must match WireType enum in google/protobuf/wire_format.h. -WIRETYPE_LENGTH_DELIMITED = 2 -WIRETYPE_START_GROUP = 3 - - -class _Printer(object): - """Text format printer for protocol message.""" - - def __init__( - self, - out, - indent=0, - as_utf8=False, - as_one_line=False, - use_short_repeated_primitives=False, - pointy_brackets=False, - use_index_order=False, - float_format=None, - double_format=None, - use_field_number=False, - descriptor_pool=None, - message_formatter=None, - print_unknown_fields=False, - force_colon=False): - """Initialize the Printer. - - Double values can be formatted compactly with 15 digits of precision - (which is the most that IEEE 754 "double" can guarantee) using - double_format='.15g'. To ensure that converting to text and back to a proto - will result in an identical value, double_format='.17g' should be used. - - Args: - out: To record the text format result. - indent: The initial indent level for pretty print. - as_utf8: Return unescaped Unicode for non-ASCII characters. - In Python 3 actual Unicode characters may appear as is in strings. - In Python 2 the return value will be valid UTF-8 rather than ASCII. - as_one_line: Don't introduce newlines between fields. - use_short_repeated_primitives: Use short repeated format for primitives. - pointy_brackets: If True, use angle brackets instead of curly braces for - nesting. - use_index_order: If True, print fields of a proto message using the order - defined in source code instead of the field number. By default, use the - field number order. - float_format: If set, use this to specify float field formatting - (per the "Format Specification Mini-Language"); otherwise, shortest - float that has same value in wire will be printed. Also affect double - field if double_format is not set but float_format is set. - double_format: If set, use this to specify double field formatting - (per the "Format Specification Mini-Language"); if it is not set but - float_format is set, use float_format. Otherwise, str() is used. - use_field_number: If True, print field numbers instead of names. - descriptor_pool: A DescriptorPool used to resolve Any types. - message_formatter: A function(message, indent, as_one_line): unicode|None - to custom format selected sub-messages (usually based on message type). - Use to pretty print parts of the protobuf for easier diffing. - print_unknown_fields: If True, unknown fields will be printed. - force_colon: If set, a colon will be added after the field name even if - the field is a proto message. - """ - self.out = out - self.indent = indent - self.as_utf8 = as_utf8 - self.as_one_line = as_one_line - self.use_short_repeated_primitives = use_short_repeated_primitives - self.pointy_brackets = pointy_brackets - self.use_index_order = use_index_order - self.float_format = float_format - if double_format is not None: - self.double_format = double_format - else: - self.double_format = float_format - self.use_field_number = use_field_number - self.descriptor_pool = descriptor_pool - self.message_formatter = message_formatter - self.print_unknown_fields = print_unknown_fields - self.force_colon = force_colon - - def _TryPrintAsAnyMessage(self, message): - """Serializes if message is a google.protobuf.Any field.""" - if '/' not in message.type_url: - return False - packed_message = _BuildMessageFromTypeName(message.TypeName(), - self.descriptor_pool) - if packed_message: - packed_message.MergeFromString(message.value) - colon = ':' if self.force_colon else '' - self.out.write('%s[%s]%s ' % (self.indent * ' ', message.type_url, colon)) - self._PrintMessageFieldValue(packed_message) - self.out.write(' ' if self.as_one_line else '\n') - return True - else: - return False - - def _TryCustomFormatMessage(self, message): - formatted = self.message_formatter(message, self.indent, self.as_one_line) - if formatted is None: - return False - - out = self.out - out.write(' ' * self.indent) - out.write(formatted) - out.write(' ' if self.as_one_line else '\n') - return True - - def PrintMessage(self, message): - """Convert protobuf message to text format. - - Args: - message: The protocol buffers message. - """ - if self.message_formatter and self._TryCustomFormatMessage(message): - return - if (message.DESCRIPTOR.full_name == _ANY_FULL_TYPE_NAME and - self._TryPrintAsAnyMessage(message)): - return - fields = message.ListFields() - if self.use_index_order: - fields.sort( - key=lambda x: x[0].number if x[0].is_extension else x[0].index) - for field, value in fields: - if _IsMapEntry(field): - for key in sorted(value): - # This is slow for maps with submessage entries because it copies the - # entire tree. Unfortunately this would take significant refactoring - # of this file to work around. - # - # TODO(haberman): refactor and optimize if this becomes an issue. - entry_submsg = value.GetEntryClass()(key=key, value=value[key]) - self.PrintField(field, entry_submsg) - elif field.label == descriptor.FieldDescriptor.LABEL_REPEATED: - if (self.use_short_repeated_primitives - and field.cpp_type != descriptor.FieldDescriptor.CPPTYPE_MESSAGE - and field.cpp_type != descriptor.FieldDescriptor.CPPTYPE_STRING): - self._PrintShortRepeatedPrimitivesValue(field, value) - else: - for element in value: - self.PrintField(field, element) - else: - self.PrintField(field, value) - - if self.print_unknown_fields: - self._PrintUnknownFields(message.UnknownFields()) - - def _PrintUnknownFields(self, unknown_fields): - """Print unknown fields.""" - out = self.out - for field in unknown_fields: - out.write(' ' * self.indent) - out.write(str(field.field_number)) - if field.wire_type == WIRETYPE_START_GROUP: - if self.as_one_line: - out.write(' { ') - else: - out.write(' {\n') - self.indent += 2 - - self._PrintUnknownFields(field.data) - - if self.as_one_line: - out.write('} ') - else: - self.indent -= 2 - out.write(' ' * self.indent + '}\n') - elif field.wire_type == WIRETYPE_LENGTH_DELIMITED: - try: - # If this field is parseable as a Message, it is probably - # an embedded message. - # pylint: disable=protected-access - (embedded_unknown_message, pos) = decoder._DecodeUnknownFieldSet( - memoryview(field.data), 0, len(field.data)) - except Exception: # pylint: disable=broad-except - pos = 0 - - if pos == len(field.data): - if self.as_one_line: - out.write(' { ') - else: - out.write(' {\n') - self.indent += 2 - - self._PrintUnknownFields(embedded_unknown_message) - - if self.as_one_line: - out.write('} ') - else: - self.indent -= 2 - out.write(' ' * self.indent + '}\n') - else: - # A string or bytes field. self.as_utf8 may not work. - out.write(': \"') - out.write(text_encoding.CEscape(field.data, False)) - out.write('\" ' if self.as_one_line else '\"\n') - else: - # varint, fixed32, fixed64 - out.write(': ') - out.write(str(field.data)) - out.write(' ' if self.as_one_line else '\n') - - def _PrintFieldName(self, field): - """Print field name.""" - out = self.out - out.write(' ' * self.indent) - if self.use_field_number: - out.write(str(field.number)) - else: - if field.is_extension: - out.write('[') - if (field.containing_type.GetOptions().message_set_wire_format and - field.type == descriptor.FieldDescriptor.TYPE_MESSAGE and - field.label == descriptor.FieldDescriptor.LABEL_OPTIONAL): - out.write(field.message_type.full_name) - else: - out.write(field.full_name) - out.write(']') - elif field.type == descriptor.FieldDescriptor.TYPE_GROUP: - # For groups, use the capitalized name. - out.write(field.message_type.name) - else: - out.write(field.name) - - if (self.force_colon or - field.cpp_type != descriptor.FieldDescriptor.CPPTYPE_MESSAGE): - # The colon is optional in this case, but our cross-language golden files - # don't include it. Here, the colon is only included if force_colon is - # set to True - out.write(':') - - def PrintField(self, field, value): - """Print a single field name/value pair.""" - self._PrintFieldName(field) - self.out.write(' ') - self.PrintFieldValue(field, value) - self.out.write(' ' if self.as_one_line else '\n') - - def _PrintShortRepeatedPrimitivesValue(self, field, value): - """"Prints short repeated primitives value.""" - # Note: this is called only when value has at least one element. - self._PrintFieldName(field) - self.out.write(' [') - for i in range(len(value) - 1): - self.PrintFieldValue(field, value[i]) - self.out.write(', ') - self.PrintFieldValue(field, value[-1]) - self.out.write(']') - self.out.write(' ' if self.as_one_line else '\n') - - def _PrintMessageFieldValue(self, value): - if self.pointy_brackets: - openb = '<' - closeb = '>' - else: - openb = '{' - closeb = '}' - - if self.as_one_line: - self.out.write('%s ' % openb) - self.PrintMessage(value) - self.out.write(closeb) - else: - self.out.write('%s\n' % openb) - self.indent += 2 - self.PrintMessage(value) - self.indent -= 2 - self.out.write(' ' * self.indent + closeb) - - def PrintFieldValue(self, field, value): - """Print a single field value (not including name). - - For repeated fields, the value should be a single element. - - Args: - field: The descriptor of the field to be printed. - value: The value of the field. - """ - out = self.out - if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: - self._PrintMessageFieldValue(value) - elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_ENUM: - enum_value = field.enum_type.values_by_number.get(value, None) - if enum_value is not None: - out.write(enum_value.name) - else: - out.write(str(value)) - elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_STRING: - out.write('\"') - if isinstance(value, str) and not self.as_utf8: - out_value = value.encode('utf-8') - else: - out_value = value - if field.type == descriptor.FieldDescriptor.TYPE_BYTES: - # We always need to escape all binary data in TYPE_BYTES fields. - out_as_utf8 = False - else: - out_as_utf8 = self.as_utf8 - out.write(text_encoding.CEscape(out_value, out_as_utf8)) - out.write('\"') - elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_BOOL: - if value: - out.write('true') - else: - out.write('false') - elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_FLOAT: - if self.float_format is not None: - out.write('{1:{0}}'.format(self.float_format, value)) - else: - if math.isnan(value): - out.write(str(value)) - else: - out.write(str(type_checkers.ToShortestFloat(value))) - elif (field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_DOUBLE and - self.double_format is not None): - out.write('{1:{0}}'.format(self.double_format, value)) - else: - out.write(str(value)) - - -def Parse(text, - message, - allow_unknown_extension=False, - allow_field_number=False, - descriptor_pool=None, - allow_unknown_field=False): - """Parses a text representation of a protocol message into a message. - - NOTE: for historical reasons this function does not clear the input - message. This is different from what the binary msg.ParseFrom(...) does. - If text contains a field already set in message, the value is appended if the - field is repeated. Otherwise, an error is raised. - - Example:: - - a = MyProto() - a.repeated_field.append('test') - b = MyProto() - - # Repeated fields are combined - text_format.Parse(repr(a), b) - text_format.Parse(repr(a), b) # repeated_field contains ["test", "test"] - - # Non-repeated fields cannot be overwritten - a.singular_field = 1 - b.singular_field = 2 - text_format.Parse(repr(a), b) # ParseError - - # Binary version: - b.ParseFromString(a.SerializeToString()) # repeated_field is now "test" - - Caller is responsible for clearing the message as needed. - - Args: - text (str): Message text representation. - message (Message): A protocol buffer message to merge into. - allow_unknown_extension: if True, skip over missing extensions and keep - parsing - allow_field_number: if True, both field number and field name are allowed. - descriptor_pool (DescriptorPool): Descriptor pool used to resolve Any types. - allow_unknown_field: if True, skip over unknown field and keep - parsing. Avoid to use this option if possible. It may hide some - errors (e.g. spelling error on field name) - - Returns: - Message: The same message passed as argument. - - Raises: - ParseError: On text parsing problems. - """ - return ParseLines(text.split(b'\n' if isinstance(text, bytes) else u'\n'), - message, - allow_unknown_extension, - allow_field_number, - descriptor_pool=descriptor_pool, - allow_unknown_field=allow_unknown_field) - - -def Merge(text, - message, - allow_unknown_extension=False, - allow_field_number=False, - descriptor_pool=None, - allow_unknown_field=False): - """Parses a text representation of a protocol message into a message. - - Like Parse(), but allows repeated values for a non-repeated field, and uses - the last one. This means any non-repeated, top-level fields specified in text - replace those in the message. - - Args: - text (str): Message text representation. - message (Message): A protocol buffer message to merge into. - allow_unknown_extension: if True, skip over missing extensions and keep - parsing - allow_field_number: if True, both field number and field name are allowed. - descriptor_pool (DescriptorPool): Descriptor pool used to resolve Any types. - allow_unknown_field: if True, skip over unknown field and keep - parsing. Avoid to use this option if possible. It may hide some - errors (e.g. spelling error on field name) - - Returns: - Message: The same message passed as argument. - - Raises: - ParseError: On text parsing problems. - """ - return MergeLines( - text.split(b'\n' if isinstance(text, bytes) else u'\n'), - message, - allow_unknown_extension, - allow_field_number, - descriptor_pool=descriptor_pool, - allow_unknown_field=allow_unknown_field) - - -def ParseLines(lines, - message, - allow_unknown_extension=False, - allow_field_number=False, - descriptor_pool=None, - allow_unknown_field=False): - """Parses a text representation of a protocol message into a message. - - See Parse() for caveats. - - Args: - lines: An iterable of lines of a message's text representation. - message: A protocol buffer message to merge into. - allow_unknown_extension: if True, skip over missing extensions and keep - parsing - allow_field_number: if True, both field number and field name are allowed. - descriptor_pool: A DescriptorPool used to resolve Any types. - allow_unknown_field: if True, skip over unknown field and keep - parsing. Avoid to use this option if possible. It may hide some - errors (e.g. spelling error on field name) - - Returns: - The same message passed as argument. - - Raises: - ParseError: On text parsing problems. - """ - parser = _Parser(allow_unknown_extension, - allow_field_number, - descriptor_pool=descriptor_pool, - allow_unknown_field=allow_unknown_field) - return parser.ParseLines(lines, message) - - -def MergeLines(lines, - message, - allow_unknown_extension=False, - allow_field_number=False, - descriptor_pool=None, - allow_unknown_field=False): - """Parses a text representation of a protocol message into a message. - - See Merge() for more details. - - Args: - lines: An iterable of lines of a message's text representation. - message: A protocol buffer message to merge into. - allow_unknown_extension: if True, skip over missing extensions and keep - parsing - allow_field_number: if True, both field number and field name are allowed. - descriptor_pool: A DescriptorPool used to resolve Any types. - allow_unknown_field: if True, skip over unknown field and keep - parsing. Avoid to use this option if possible. It may hide some - errors (e.g. spelling error on field name) - - Returns: - The same message passed as argument. - - Raises: - ParseError: On text parsing problems. - """ - parser = _Parser(allow_unknown_extension, - allow_field_number, - descriptor_pool=descriptor_pool, - allow_unknown_field=allow_unknown_field) - return parser.MergeLines(lines, message) - - -class _Parser(object): - """Text format parser for protocol message.""" - - def __init__(self, - allow_unknown_extension=False, - allow_field_number=False, - descriptor_pool=None, - allow_unknown_field=False): - self.allow_unknown_extension = allow_unknown_extension - self.allow_field_number = allow_field_number - self.descriptor_pool = descriptor_pool - self.allow_unknown_field = allow_unknown_field - - def ParseLines(self, lines, message): - """Parses a text representation of a protocol message into a message.""" - self._allow_multiple_scalars = False - self._ParseOrMerge(lines, message) - return message - - def MergeLines(self, lines, message): - """Merges a text representation of a protocol message into a message.""" - self._allow_multiple_scalars = True - self._ParseOrMerge(lines, message) - return message - - def _ParseOrMerge(self, lines, message): - """Converts a text representation of a protocol message into a message. - - Args: - lines: Lines of a message's text representation. - message: A protocol buffer message to merge into. - - Raises: - ParseError: On text parsing problems. - """ - # Tokenize expects native str lines. - str_lines = ( - line if isinstance(line, str) else line.decode('utf-8') - for line in lines) - tokenizer = Tokenizer(str_lines) - while not tokenizer.AtEnd(): - self._MergeField(tokenizer, message) - - def _MergeField(self, tokenizer, message): - """Merges a single protocol message field into a message. - - Args: - tokenizer: A tokenizer to parse the field name and values. - message: A protocol message to record the data. - - Raises: - ParseError: In case of text parsing problems. - """ - message_descriptor = message.DESCRIPTOR - if (message_descriptor.full_name == _ANY_FULL_TYPE_NAME and - tokenizer.TryConsume('[')): - type_url_prefix, packed_type_name = self._ConsumeAnyTypeUrl(tokenizer) - tokenizer.Consume(']') - tokenizer.TryConsume(':') - if tokenizer.TryConsume('<'): - expanded_any_end_token = '>' - else: - tokenizer.Consume('{') - expanded_any_end_token = '}' - expanded_any_sub_message = _BuildMessageFromTypeName(packed_type_name, - self.descriptor_pool) - if not expanded_any_sub_message: - raise ParseError('Type %s not found in descriptor pool' % - packed_type_name) - while not tokenizer.TryConsume(expanded_any_end_token): - if tokenizer.AtEnd(): - raise tokenizer.ParseErrorPreviousToken('Expected "%s".' % - (expanded_any_end_token,)) - self._MergeField(tokenizer, expanded_any_sub_message) - deterministic = False - - message.Pack(expanded_any_sub_message, - type_url_prefix=type_url_prefix, - deterministic=deterministic) - return - - if tokenizer.TryConsume('['): - name = [tokenizer.ConsumeIdentifier()] - while tokenizer.TryConsume('.'): - name.append(tokenizer.ConsumeIdentifier()) - name = '.'.join(name) - - if not message_descriptor.is_extendable: - raise tokenizer.ParseErrorPreviousToken( - 'Message type "%s" does not have extensions.' % - message_descriptor.full_name) - # pylint: disable=protected-access - field = message.Extensions._FindExtensionByName(name) - # pylint: enable=protected-access - - - if not field: - if self.allow_unknown_extension: - field = None - else: - raise tokenizer.ParseErrorPreviousToken( - 'Extension "%s" not registered. ' - 'Did you import the _pb2 module which defines it? ' - 'If you are trying to place the extension in the MessageSet ' - 'field of another message that is in an Any or MessageSet field, ' - 'that message\'s _pb2 module must be imported as well' % name) - elif message_descriptor != field.containing_type: - raise tokenizer.ParseErrorPreviousToken( - 'Extension "%s" does not extend message type "%s".' % - (name, message_descriptor.full_name)) - - tokenizer.Consume(']') - - else: - name = tokenizer.ConsumeIdentifierOrNumber() - if self.allow_field_number and name.isdigit(): - number = ParseInteger(name, True, True) - field = message_descriptor.fields_by_number.get(number, None) - if not field and message_descriptor.is_extendable: - field = message.Extensions._FindExtensionByNumber(number) - else: - field = message_descriptor.fields_by_name.get(name, None) - - # Group names are expected to be capitalized as they appear in the - # .proto file, which actually matches their type names, not their field - # names. - if not field: - field = message_descriptor.fields_by_name.get(name.lower(), None) - if field and field.type != descriptor.FieldDescriptor.TYPE_GROUP: - field = None - - if (field and field.type == descriptor.FieldDescriptor.TYPE_GROUP and - field.message_type.name != name): - field = None - - if not field and not self.allow_unknown_field: - raise tokenizer.ParseErrorPreviousToken( - 'Message type "%s" has no field named "%s".' % - (message_descriptor.full_name, name)) - - if field: - if not self._allow_multiple_scalars and field.containing_oneof: - # Check if there's a different field set in this oneof. - # Note that we ignore the case if the same field was set before, and we - # apply _allow_multiple_scalars to non-scalar fields as well. - which_oneof = message.WhichOneof(field.containing_oneof.name) - if which_oneof is not None and which_oneof != field.name: - raise tokenizer.ParseErrorPreviousToken( - 'Field "%s" is specified along with field "%s", another member ' - 'of oneof "%s" for message type "%s".' % - (field.name, which_oneof, field.containing_oneof.name, - message_descriptor.full_name)) - - if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: - tokenizer.TryConsume(':') - merger = self._MergeMessageField - else: - tokenizer.Consume(':') - merger = self._MergeScalarField - - if (field.label == descriptor.FieldDescriptor.LABEL_REPEATED and - tokenizer.TryConsume('[')): - # Short repeated format, e.g. "foo: [1, 2, 3]" - if not tokenizer.TryConsume(']'): - while True: - merger(tokenizer, message, field) - if tokenizer.TryConsume(']'): - break - tokenizer.Consume(',') - - else: - merger(tokenizer, message, field) - - else: # Proto field is unknown. - assert (self.allow_unknown_extension or self.allow_unknown_field) - _SkipFieldContents(tokenizer) - - # For historical reasons, fields may optionally be separated by commas or - # semicolons. - if not tokenizer.TryConsume(','): - tokenizer.TryConsume(';') - - - def _ConsumeAnyTypeUrl(self, tokenizer): - """Consumes a google.protobuf.Any type URL and returns the type name.""" - # Consume "type.googleapis.com/". - prefix = [tokenizer.ConsumeIdentifier()] - tokenizer.Consume('.') - prefix.append(tokenizer.ConsumeIdentifier()) - tokenizer.Consume('.') - prefix.append(tokenizer.ConsumeIdentifier()) - tokenizer.Consume('/') - # Consume the fully-qualified type name. - name = [tokenizer.ConsumeIdentifier()] - while tokenizer.TryConsume('.'): - name.append(tokenizer.ConsumeIdentifier()) - return '.'.join(prefix), '.'.join(name) - - def _MergeMessageField(self, tokenizer, message, field): - """Merges a single scalar field into a message. - - Args: - tokenizer: A tokenizer to parse the field value. - message: The message of which field is a member. - field: The descriptor of the field to be merged. - - Raises: - ParseError: In case of text parsing problems. - """ - is_map_entry = _IsMapEntry(field) - - if tokenizer.TryConsume('<'): - end_token = '>' - else: - tokenizer.Consume('{') - end_token = '}' - - if field.label == descriptor.FieldDescriptor.LABEL_REPEATED: - if field.is_extension: - sub_message = message.Extensions[field].add() - elif is_map_entry: - sub_message = getattr(message, field.name).GetEntryClass()() - else: - sub_message = getattr(message, field.name).add() - else: - if field.is_extension: - if (not self._allow_multiple_scalars and - message.HasExtension(field)): - raise tokenizer.ParseErrorPreviousToken( - 'Message type "%s" should not have multiple "%s" extensions.' % - (message.DESCRIPTOR.full_name, field.full_name)) - sub_message = message.Extensions[field] - else: - # Also apply _allow_multiple_scalars to message field. - # TODO(jieluo): Change to _allow_singular_overwrites. - if (not self._allow_multiple_scalars and - message.HasField(field.name)): - raise tokenizer.ParseErrorPreviousToken( - 'Message type "%s" should not have multiple "%s" fields.' % - (message.DESCRIPTOR.full_name, field.name)) - sub_message = getattr(message, field.name) - sub_message.SetInParent() - - while not tokenizer.TryConsume(end_token): - if tokenizer.AtEnd(): - raise tokenizer.ParseErrorPreviousToken('Expected "%s".' % (end_token,)) - self._MergeField(tokenizer, sub_message) - - if is_map_entry: - value_cpptype = field.message_type.fields_by_name['value'].cpp_type - if value_cpptype == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: - value = getattr(message, field.name)[sub_message.key] - value.CopyFrom(sub_message.value) - else: - getattr(message, field.name)[sub_message.key] = sub_message.value - - @staticmethod - def _IsProto3Syntax(message): - message_descriptor = message.DESCRIPTOR - return (hasattr(message_descriptor, 'syntax') and - message_descriptor.syntax == 'proto3') - - def _MergeScalarField(self, tokenizer, message, field): - """Merges a single scalar field into a message. - - Args: - tokenizer: A tokenizer to parse the field value. - message: A protocol message to record the data. - field: The descriptor of the field to be merged. - - Raises: - ParseError: In case of text parsing problems. - RuntimeError: On runtime errors. - """ - _ = self.allow_unknown_extension - value = None - - if field.type in (descriptor.FieldDescriptor.TYPE_INT32, - descriptor.FieldDescriptor.TYPE_SINT32, - descriptor.FieldDescriptor.TYPE_SFIXED32): - value = _ConsumeInt32(tokenizer) - elif field.type in (descriptor.FieldDescriptor.TYPE_INT64, - descriptor.FieldDescriptor.TYPE_SINT64, - descriptor.FieldDescriptor.TYPE_SFIXED64): - value = _ConsumeInt64(tokenizer) - elif field.type in (descriptor.FieldDescriptor.TYPE_UINT32, - descriptor.FieldDescriptor.TYPE_FIXED32): - value = _ConsumeUint32(tokenizer) - elif field.type in (descriptor.FieldDescriptor.TYPE_UINT64, - descriptor.FieldDescriptor.TYPE_FIXED64): - value = _ConsumeUint64(tokenizer) - elif field.type in (descriptor.FieldDescriptor.TYPE_FLOAT, - descriptor.FieldDescriptor.TYPE_DOUBLE): - value = tokenizer.ConsumeFloat() - elif field.type == descriptor.FieldDescriptor.TYPE_BOOL: - value = tokenizer.ConsumeBool() - elif field.type == descriptor.FieldDescriptor.TYPE_STRING: - value = tokenizer.ConsumeString() - elif field.type == descriptor.FieldDescriptor.TYPE_BYTES: - value = tokenizer.ConsumeByteString() - elif field.type == descriptor.FieldDescriptor.TYPE_ENUM: - value = tokenizer.ConsumeEnum(field) - else: - raise RuntimeError('Unknown field type %d' % field.type) - - if field.label == descriptor.FieldDescriptor.LABEL_REPEATED: - if field.is_extension: - message.Extensions[field].append(value) - else: - getattr(message, field.name).append(value) - else: - if field.is_extension: - if (not self._allow_multiple_scalars and - not self._IsProto3Syntax(message) and - message.HasExtension(field)): - raise tokenizer.ParseErrorPreviousToken( - 'Message type "%s" should not have multiple "%s" extensions.' % - (message.DESCRIPTOR.full_name, field.full_name)) - else: - message.Extensions[field] = value - else: - duplicate_error = False - if not self._allow_multiple_scalars: - if self._IsProto3Syntax(message): - # Proto3 doesn't represent presence so we try best effort to check - # multiple scalars by compare to default values. - duplicate_error = bool(getattr(message, field.name)) - else: - duplicate_error = message.HasField(field.name) - - if duplicate_error: - raise tokenizer.ParseErrorPreviousToken( - 'Message type "%s" should not have multiple "%s" fields.' % - (message.DESCRIPTOR.full_name, field.name)) - else: - setattr(message, field.name, value) - - -def _SkipFieldContents(tokenizer): - """Skips over contents (value or message) of a field. - - Args: - tokenizer: A tokenizer to parse the field name and values. - """ - # Try to guess the type of this field. - # If this field is not a message, there should be a ":" between the - # field name and the field value and also the field value should not - # start with "{" or "<" which indicates the beginning of a message body. - # If there is no ":" or there is a "{" or "<" after ":", this field has - # to be a message or the input is ill-formed. - if tokenizer.TryConsume(':') and not tokenizer.LookingAt( - '{') and not tokenizer.LookingAt('<'): - _SkipFieldValue(tokenizer) - else: - _SkipFieldMessage(tokenizer) - - -def _SkipField(tokenizer): - """Skips over a complete field (name and value/message). - - Args: - tokenizer: A tokenizer to parse the field name and values. - """ - if tokenizer.TryConsume('['): - # Consume extension name. - tokenizer.ConsumeIdentifier() - while tokenizer.TryConsume('.'): - tokenizer.ConsumeIdentifier() - tokenizer.Consume(']') - else: - tokenizer.ConsumeIdentifierOrNumber() - - _SkipFieldContents(tokenizer) - - # For historical reasons, fields may optionally be separated by commas or - # semicolons. - if not tokenizer.TryConsume(','): - tokenizer.TryConsume(';') - - -def _SkipFieldMessage(tokenizer): - """Skips over a field message. - - Args: - tokenizer: A tokenizer to parse the field name and values. - """ - - if tokenizer.TryConsume('<'): - delimiter = '>' - else: - tokenizer.Consume('{') - delimiter = '}' - - while not tokenizer.LookingAt('>') and not tokenizer.LookingAt('}'): - _SkipField(tokenizer) - - tokenizer.Consume(delimiter) - - -def _SkipFieldValue(tokenizer): - """Skips over a field value. - - Args: - tokenizer: A tokenizer to parse the field name and values. - - Raises: - ParseError: In case an invalid field value is found. - """ - # String/bytes tokens can come in multiple adjacent string literals. - # If we can consume one, consume as many as we can. - if tokenizer.TryConsumeByteString(): - while tokenizer.TryConsumeByteString(): - pass - return - - if (not tokenizer.TryConsumeIdentifier() and - not _TryConsumeInt64(tokenizer) and not _TryConsumeUint64(tokenizer) and - not tokenizer.TryConsumeFloat()): - raise ParseError('Invalid field value: ' + tokenizer.token) - - -class Tokenizer(object): - """Protocol buffer text representation tokenizer. - - This class handles the lower level string parsing by splitting it into - meaningful tokens. - - It was directly ported from the Java protocol buffer API. - """ - - _WHITESPACE = re.compile(r'\s+') - _COMMENT = re.compile(r'(\s*#.*$)', re.MULTILINE) - _WHITESPACE_OR_COMMENT = re.compile(r'(\s|(#.*$))+', re.MULTILINE) - _TOKEN = re.compile('|'.join([ - r'[a-zA-Z_][0-9a-zA-Z_+-]*', # an identifier - r'([0-9+-]|(\.[0-9]))[0-9a-zA-Z_.+-]*', # a number - ] + [ # quoted str for each quote mark - # Avoid backtracking! https://stackoverflow.com/a/844267 - r'{qt}[^{qt}\n\\]*((\\.)+[^{qt}\n\\]*)*({qt}|\\?$)'.format(qt=mark) - for mark in _QUOTES - ])) - - _IDENTIFIER = re.compile(r'[^\d\W]\w*') - _IDENTIFIER_OR_NUMBER = re.compile(r'\w+') - - def __init__(self, lines, skip_comments=True): - self._position = 0 - self._line = -1 - self._column = 0 - self._token_start = None - self.token = '' - self._lines = iter(lines) - self._current_line = '' - self._previous_line = 0 - self._previous_column = 0 - self._more_lines = True - self._skip_comments = skip_comments - self._whitespace_pattern = (skip_comments and self._WHITESPACE_OR_COMMENT - or self._WHITESPACE) - self._SkipWhitespace() - self.NextToken() - - def LookingAt(self, token): - return self.token == token - - def AtEnd(self): - """Checks the end of the text was reached. - - Returns: - True iff the end was reached. - """ - return not self.token - - def _PopLine(self): - while len(self._current_line) <= self._column: - try: - self._current_line = next(self._lines) - except StopIteration: - self._current_line = '' - self._more_lines = False - return - else: - self._line += 1 - self._column = 0 - - def _SkipWhitespace(self): - while True: - self._PopLine() - match = self._whitespace_pattern.match(self._current_line, self._column) - if not match: - break - length = len(match.group(0)) - self._column += length - - def TryConsume(self, token): - """Tries to consume a given piece of text. - - Args: - token: Text to consume. - - Returns: - True iff the text was consumed. - """ - if self.token == token: - self.NextToken() - return True - return False - - def Consume(self, token): - """Consumes a piece of text. - - Args: - token: Text to consume. - - Raises: - ParseError: If the text couldn't be consumed. - """ - if not self.TryConsume(token): - raise self.ParseError('Expected "%s".' % token) - - def ConsumeComment(self): - result = self.token - if not self._COMMENT.match(result): - raise self.ParseError('Expected comment.') - self.NextToken() - return result - - def ConsumeCommentOrTrailingComment(self): - """Consumes a comment, returns a 2-tuple (trailing bool, comment str).""" - - # Tokenizer initializes _previous_line and _previous_column to 0. As the - # tokenizer starts, it looks like there is a previous token on the line. - just_started = self._line == 0 and self._column == 0 - - before_parsing = self._previous_line - comment = self.ConsumeComment() - - # A trailing comment is a comment on the same line than the previous token. - trailing = (self._previous_line == before_parsing - and not just_started) - - return trailing, comment - - def TryConsumeIdentifier(self): - try: - self.ConsumeIdentifier() - return True - except ParseError: - return False - - def ConsumeIdentifier(self): - """Consumes protocol message field identifier. - - Returns: - Identifier string. - - Raises: - ParseError: If an identifier couldn't be consumed. - """ - result = self.token - if not self._IDENTIFIER.match(result): - raise self.ParseError('Expected identifier.') - self.NextToken() - return result - - def TryConsumeIdentifierOrNumber(self): - try: - self.ConsumeIdentifierOrNumber() - return True - except ParseError: - return False - - def ConsumeIdentifierOrNumber(self): - """Consumes protocol message field identifier. - - Returns: - Identifier string. - - Raises: - ParseError: If an identifier couldn't be consumed. - """ - result = self.token - if not self._IDENTIFIER_OR_NUMBER.match(result): - raise self.ParseError('Expected identifier or number, got %s.' % result) - self.NextToken() - return result - - def TryConsumeInteger(self): - try: - self.ConsumeInteger() - return True - except ParseError: - return False - - def ConsumeInteger(self): - """Consumes an integer number. - - Returns: - The integer parsed. - - Raises: - ParseError: If an integer couldn't be consumed. - """ - try: - result = _ParseAbstractInteger(self.token) - except ValueError as e: - raise self.ParseError(str(e)) - self.NextToken() - return result - - def TryConsumeFloat(self): - try: - self.ConsumeFloat() - return True - except ParseError: - return False - - def ConsumeFloat(self): - """Consumes an floating point number. - - Returns: - The number parsed. - - Raises: - ParseError: If a floating point number couldn't be consumed. - """ - try: - result = ParseFloat(self.token) - except ValueError as e: - raise self.ParseError(str(e)) - self.NextToken() - return result - - def ConsumeBool(self): - """Consumes a boolean value. - - Returns: - The bool parsed. - - Raises: - ParseError: If a boolean value couldn't be consumed. - """ - try: - result = ParseBool(self.token) - except ValueError as e: - raise self.ParseError(str(e)) - self.NextToken() - return result - - def TryConsumeByteString(self): - try: - self.ConsumeByteString() - return True - except ParseError: - return False - - def ConsumeString(self): - """Consumes a string value. - - Returns: - The string parsed. - - Raises: - ParseError: If a string value couldn't be consumed. - """ - the_bytes = self.ConsumeByteString() - try: - return str(the_bytes, 'utf-8') - except UnicodeDecodeError as e: - raise self._StringParseError(e) - - def ConsumeByteString(self): - """Consumes a byte array value. - - Returns: - The array parsed (as a string). - - Raises: - ParseError: If a byte array value couldn't be consumed. - """ - the_list = [self._ConsumeSingleByteString()] - while self.token and self.token[0] in _QUOTES: - the_list.append(self._ConsumeSingleByteString()) - return b''.join(the_list) - - def _ConsumeSingleByteString(self): - """Consume one token of a string literal. - - String literals (whether bytes or text) can come in multiple adjacent - tokens which are automatically concatenated, like in C or Python. This - method only consumes one token. - - Returns: - The token parsed. - Raises: - ParseError: When the wrong format data is found. - """ - text = self.token - if len(text) < 1 or text[0] not in _QUOTES: - raise self.ParseError('Expected string but found: %r' % (text,)) - - if len(text) < 2 or text[-1] != text[0]: - raise self.ParseError('String missing ending quote: %r' % (text,)) - - try: - result = text_encoding.CUnescape(text[1:-1]) - except ValueError as e: - raise self.ParseError(str(e)) - self.NextToken() - return result - - def ConsumeEnum(self, field): - try: - result = ParseEnum(field, self.token) - except ValueError as e: - raise self.ParseError(str(e)) - self.NextToken() - return result - - def ParseErrorPreviousToken(self, message): - """Creates and *returns* a ParseError for the previously read token. - - Args: - message: A message to set for the exception. - - Returns: - A ParseError instance. - """ - return ParseError(message, self._previous_line + 1, - self._previous_column + 1) - - def ParseError(self, message): - """Creates and *returns* a ParseError for the current token.""" - return ParseError('\'' + self._current_line + '\': ' + message, - self._line + 1, self._column + 1) - - def _StringParseError(self, e): - return self.ParseError('Couldn\'t parse string: ' + str(e)) - - def NextToken(self): - """Reads the next meaningful token.""" - self._previous_line = self._line - self._previous_column = self._column - - self._column += len(self.token) - self._SkipWhitespace() - - if not self._more_lines: - self.token = '' - return - - match = self._TOKEN.match(self._current_line, self._column) - if not match and not self._skip_comments: - match = self._COMMENT.match(self._current_line, self._column) - if match: - token = match.group(0) - self.token = token - else: - self.token = self._current_line[self._column] - -# Aliased so it can still be accessed by current visibility violators. -# TODO(dbarnett): Migrate violators to textformat_tokenizer. -_Tokenizer = Tokenizer # pylint: disable=invalid-name - - -def _ConsumeInt32(tokenizer): - """Consumes a signed 32bit integer number from tokenizer. - - Args: - tokenizer: A tokenizer used to parse the number. - - Returns: - The integer parsed. - - Raises: - ParseError: If a signed 32bit integer couldn't be consumed. - """ - return _ConsumeInteger(tokenizer, is_signed=True, is_long=False) - - -def _ConsumeUint32(tokenizer): - """Consumes an unsigned 32bit integer number from tokenizer. - - Args: - tokenizer: A tokenizer used to parse the number. - - Returns: - The integer parsed. - - Raises: - ParseError: If an unsigned 32bit integer couldn't be consumed. - """ - return _ConsumeInteger(tokenizer, is_signed=False, is_long=False) - - -def _TryConsumeInt64(tokenizer): - try: - _ConsumeInt64(tokenizer) - return True - except ParseError: - return False - - -def _ConsumeInt64(tokenizer): - """Consumes a signed 32bit integer number from tokenizer. - - Args: - tokenizer: A tokenizer used to parse the number. - - Returns: - The integer parsed. - - Raises: - ParseError: If a signed 32bit integer couldn't be consumed. - """ - return _ConsumeInteger(tokenizer, is_signed=True, is_long=True) - - -def _TryConsumeUint64(tokenizer): - try: - _ConsumeUint64(tokenizer) - return True - except ParseError: - return False - - -def _ConsumeUint64(tokenizer): - """Consumes an unsigned 64bit integer number from tokenizer. - - Args: - tokenizer: A tokenizer used to parse the number. - - Returns: - The integer parsed. - - Raises: - ParseError: If an unsigned 64bit integer couldn't be consumed. - """ - return _ConsumeInteger(tokenizer, is_signed=False, is_long=True) - - -def _ConsumeInteger(tokenizer, is_signed=False, is_long=False): - """Consumes an integer number from tokenizer. - - Args: - tokenizer: A tokenizer used to parse the number. - is_signed: True if a signed integer must be parsed. - is_long: True if a long integer must be parsed. - - Returns: - The integer parsed. - - Raises: - ParseError: If an integer with given characteristics couldn't be consumed. - """ - try: - result = ParseInteger(tokenizer.token, is_signed=is_signed, is_long=is_long) - except ValueError as e: - raise tokenizer.ParseError(str(e)) - tokenizer.NextToken() - return result - - -def ParseInteger(text, is_signed=False, is_long=False): - """Parses an integer. - - Args: - text: The text to parse. - is_signed: True if a signed integer must be parsed. - is_long: True if a long integer must be parsed. - - Returns: - The integer value. - - Raises: - ValueError: Thrown Iff the text is not a valid integer. - """ - # Do the actual parsing. Exception handling is propagated to caller. - result = _ParseAbstractInteger(text) - - # Check if the integer is sane. Exceptions handled by callers. - checker = _INTEGER_CHECKERS[2 * int(is_long) + int(is_signed)] - checker.CheckValue(result) - return result - - -def _ParseAbstractInteger(text): - """Parses an integer without checking size/signedness. - - Args: - text: The text to parse. - - Returns: - The integer value. - - Raises: - ValueError: Thrown Iff the text is not a valid integer. - """ - # Do the actual parsing. Exception handling is propagated to caller. - orig_text = text - c_octal_match = re.match(r'(-?)0(\d+)$', text) - if c_octal_match: - # Python 3 no longer supports 0755 octal syntax without the 'o', so - # we always use the '0o' prefix for multi-digit numbers starting with 0. - text = c_octal_match.group(1) + '0o' + c_octal_match.group(2) - try: - return int(text, 0) - except ValueError: - raise ValueError('Couldn\'t parse integer: %s' % orig_text) - - -def ParseFloat(text): - """Parse a floating point number. - - Args: - text: Text to parse. - - Returns: - The number parsed. - - Raises: - ValueError: If a floating point number couldn't be parsed. - """ - try: - # Assume Python compatible syntax. - return float(text) - except ValueError: - # Check alternative spellings. - if _FLOAT_INFINITY.match(text): - if text[0] == '-': - return float('-inf') - else: - return float('inf') - elif _FLOAT_NAN.match(text): - return float('nan') - else: - # assume '1.0f' format - try: - return float(text.rstrip('f')) - except ValueError: - raise ValueError('Couldn\'t parse float: %s' % text) - - -def ParseBool(text): - """Parse a boolean value. - - Args: - text: Text to parse. - - Returns: - Boolean values parsed - - Raises: - ValueError: If text is not a valid boolean. - """ - if text in ('true', 't', '1', 'True'): - return True - elif text in ('false', 'f', '0', 'False'): - return False - else: - raise ValueError('Expected "true" or "false".') - - -def ParseEnum(field, value): - """Parse an enum value. - - The value can be specified by a number (the enum value), or by - a string literal (the enum name). - - Args: - field: Enum field descriptor. - value: String value. - - Returns: - Enum value number. - - Raises: - ValueError: If the enum value could not be parsed. - """ - enum_descriptor = field.enum_type - try: - number = int(value, 0) - except ValueError: - # Identifier. - enum_value = enum_descriptor.values_by_name.get(value, None) - if enum_value is None: - raise ValueError('Enum type "%s" has no value named %s.' % - (enum_descriptor.full_name, value)) - else: - # Numeric value. - if hasattr(field.file, 'syntax'): - # Attribute is checked for compatibility. - if field.file.syntax == 'proto3': - # Proto3 accept numeric unknown enums. - return number - enum_value = enum_descriptor.values_by_number.get(number, None) - if enum_value is None: - raise ValueError('Enum type "%s" has no value with number %d.' % - (enum_descriptor.full_name, number)) - return enum_value.number diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/timestamp_pb2.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/timestamp_pb2.py deleted file mode 100644 index 558d496941..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/timestamp_pb2.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/timestamp.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1fgoogle/protobuf/timestamp.proto\x12\x0fgoogle.protobuf\"+\n\tTimestamp\x12\x0f\n\x07seconds\x18\x01 \x01(\x03\x12\r\n\x05nanos\x18\x02 \x01(\x05\x42\x85\x01\n\x13\x63om.google.protobufB\x0eTimestampProtoP\x01Z2google.golang.org/protobuf/types/known/timestamppb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.timestamp_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.google.protobufB\016TimestampProtoP\001Z2google.golang.org/protobuf/types/known/timestamppb\370\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' - _TIMESTAMP._serialized_start=52 - _TIMESTAMP._serialized_end=95 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/type_pb2.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/type_pb2.py deleted file mode 100644 index 19903fb6b4..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/type_pb2.py +++ /dev/null @@ -1,42 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/type.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2 -from google.protobuf import source_context_pb2 as google_dot_protobuf_dot_source__context__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1agoogle/protobuf/type.proto\x12\x0fgoogle.protobuf\x1a\x19google/protobuf/any.proto\x1a$google/protobuf/source_context.proto\"\xd7\x01\n\x04Type\x12\x0c\n\x04name\x18\x01 \x01(\t\x12&\n\x06\x66ields\x18\x02 \x03(\x0b\x32\x16.google.protobuf.Field\x12\x0e\n\x06oneofs\x18\x03 \x03(\t\x12(\n\x07options\x18\x04 \x03(\x0b\x32\x17.google.protobuf.Option\x12\x36\n\x0esource_context\x18\x05 \x01(\x0b\x32\x1e.google.protobuf.SourceContext\x12\'\n\x06syntax\x18\x06 \x01(\x0e\x32\x17.google.protobuf.Syntax\"\xd5\x05\n\x05\x46ield\x12)\n\x04kind\x18\x01 \x01(\x0e\x32\x1b.google.protobuf.Field.Kind\x12\x37\n\x0b\x63\x61rdinality\x18\x02 \x01(\x0e\x32\".google.protobuf.Field.Cardinality\x12\x0e\n\x06number\x18\x03 \x01(\x05\x12\x0c\n\x04name\x18\x04 \x01(\t\x12\x10\n\x08type_url\x18\x06 \x01(\t\x12\x13\n\x0boneof_index\x18\x07 \x01(\x05\x12\x0e\n\x06packed\x18\x08 \x01(\x08\x12(\n\x07options\x18\t \x03(\x0b\x32\x17.google.protobuf.Option\x12\x11\n\tjson_name\x18\n \x01(\t\x12\x15\n\rdefault_value\x18\x0b \x01(\t\"\xc8\x02\n\x04Kind\x12\x10\n\x0cTYPE_UNKNOWN\x10\x00\x12\x0f\n\x0bTYPE_DOUBLE\x10\x01\x12\x0e\n\nTYPE_FLOAT\x10\x02\x12\x0e\n\nTYPE_INT64\x10\x03\x12\x0f\n\x0bTYPE_UINT64\x10\x04\x12\x0e\n\nTYPE_INT32\x10\x05\x12\x10\n\x0cTYPE_FIXED64\x10\x06\x12\x10\n\x0cTYPE_FIXED32\x10\x07\x12\r\n\tTYPE_BOOL\x10\x08\x12\x0f\n\x0bTYPE_STRING\x10\t\x12\x0e\n\nTYPE_GROUP\x10\n\x12\x10\n\x0cTYPE_MESSAGE\x10\x0b\x12\x0e\n\nTYPE_BYTES\x10\x0c\x12\x0f\n\x0bTYPE_UINT32\x10\r\x12\r\n\tTYPE_ENUM\x10\x0e\x12\x11\n\rTYPE_SFIXED32\x10\x0f\x12\x11\n\rTYPE_SFIXED64\x10\x10\x12\x0f\n\x0bTYPE_SINT32\x10\x11\x12\x0f\n\x0bTYPE_SINT64\x10\x12\"t\n\x0b\x43\x61rdinality\x12\x17\n\x13\x43\x41RDINALITY_UNKNOWN\x10\x00\x12\x18\n\x14\x43\x41RDINALITY_OPTIONAL\x10\x01\x12\x18\n\x14\x43\x41RDINALITY_REQUIRED\x10\x02\x12\x18\n\x14\x43\x41RDINALITY_REPEATED\x10\x03\"\xce\x01\n\x04\x45num\x12\x0c\n\x04name\x18\x01 \x01(\t\x12-\n\tenumvalue\x18\x02 \x03(\x0b\x32\x1a.google.protobuf.EnumValue\x12(\n\x07options\x18\x03 \x03(\x0b\x32\x17.google.protobuf.Option\x12\x36\n\x0esource_context\x18\x04 \x01(\x0b\x32\x1e.google.protobuf.SourceContext\x12\'\n\x06syntax\x18\x05 \x01(\x0e\x32\x17.google.protobuf.Syntax\"S\n\tEnumValue\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06number\x18\x02 \x01(\x05\x12(\n\x07options\x18\x03 \x03(\x0b\x32\x17.google.protobuf.Option\";\n\x06Option\x12\x0c\n\x04name\x18\x01 \x01(\t\x12#\n\x05value\x18\x02 \x01(\x0b\x32\x14.google.protobuf.Any*.\n\x06Syntax\x12\x11\n\rSYNTAX_PROTO2\x10\x00\x12\x11\n\rSYNTAX_PROTO3\x10\x01\x42{\n\x13\x63om.google.protobufB\tTypeProtoP\x01Z-google.golang.org/protobuf/types/known/typepb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.type_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.google.protobufB\tTypeProtoP\001Z-google.golang.org/protobuf/types/known/typepb\370\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' - _SYNTAX._serialized_start=1413 - _SYNTAX._serialized_end=1459 - _TYPE._serialized_start=113 - _TYPE._serialized_end=328 - _FIELD._serialized_start=331 - _FIELD._serialized_end=1056 - _FIELD_KIND._serialized_start=610 - _FIELD_KIND._serialized_end=938 - _FIELD_CARDINALITY._serialized_start=940 - _FIELD_CARDINALITY._serialized_end=1056 - _ENUM._serialized_start=1059 - _ENUM._serialized_end=1265 - _ENUMVALUE._serialized_start=1267 - _ENUMVALUE._serialized_end=1350 - _OPTION._serialized_start=1352 - _OPTION._serialized_end=1411 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/util/__init__.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/util/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/util/json_format_pb2.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/util/json_format_pb2.py deleted file mode 100644 index 66a5836c82..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/util/json_format_pb2.py +++ /dev/null @@ -1,72 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/util/json_format.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n&google/protobuf/util/json_format.proto\x12\x11protobuf_unittest\"\x89\x01\n\x13TestFlagsAndStrings\x12\t\n\x01\x41\x18\x01 \x02(\x05\x12K\n\rrepeatedgroup\x18\x02 \x03(\n24.protobuf_unittest.TestFlagsAndStrings.RepeatedGroup\x1a\x1a\n\rRepeatedGroup\x12\t\n\x01\x66\x18\x03 \x02(\t\"!\n\x14TestBase64ByteArrays\x12\t\n\x01\x61\x18\x01 \x02(\x0c\"G\n\x12TestJavaScriptJSON\x12\t\n\x01\x61\x18\x01 \x01(\x05\x12\r\n\x05\x66inal\x18\x02 \x01(\x02\x12\n\n\x02in\x18\x03 \x01(\t\x12\x0b\n\x03Var\x18\x04 \x01(\t\"Q\n\x18TestJavaScriptOrderJSON1\x12\t\n\x01\x64\x18\x01 \x01(\x05\x12\t\n\x01\x63\x18\x02 \x01(\x05\x12\t\n\x01x\x18\x03 \x01(\x08\x12\t\n\x01\x62\x18\x04 \x01(\x05\x12\t\n\x01\x61\x18\x05 \x01(\x05\"\x89\x01\n\x18TestJavaScriptOrderJSON2\x12\t\n\x01\x64\x18\x01 \x01(\x05\x12\t\n\x01\x63\x18\x02 \x01(\x05\x12\t\n\x01x\x18\x03 \x01(\x08\x12\t\n\x01\x62\x18\x04 \x01(\x05\x12\t\n\x01\x61\x18\x05 \x01(\x05\x12\x36\n\x01z\x18\x06 \x03(\x0b\x32+.protobuf_unittest.TestJavaScriptOrderJSON1\"$\n\x0cTestLargeInt\x12\t\n\x01\x61\x18\x01 \x02(\x03\x12\t\n\x01\x62\x18\x02 \x02(\x04\"\xa0\x01\n\x0bTestNumbers\x12\x30\n\x01\x61\x18\x01 \x01(\x0e\x32%.protobuf_unittest.TestNumbers.MyType\x12\t\n\x01\x62\x18\x02 \x01(\x05\x12\t\n\x01\x63\x18\x03 \x01(\x02\x12\t\n\x01\x64\x18\x04 \x01(\x08\x12\t\n\x01\x65\x18\x05 \x01(\x01\x12\t\n\x01\x66\x18\x06 \x01(\r\"(\n\x06MyType\x12\x06\n\x02OK\x10\x00\x12\x0b\n\x07WARNING\x10\x01\x12\t\n\x05\x45RROR\x10\x02\"T\n\rTestCamelCase\x12\x14\n\x0cnormal_field\x18\x01 \x01(\t\x12\x15\n\rCAPITAL_FIELD\x18\x02 \x01(\x05\x12\x16\n\x0e\x43\x61melCaseField\x18\x03 \x01(\x05\"|\n\x0bTestBoolMap\x12=\n\x08\x62ool_map\x18\x01 \x03(\x0b\x32+.protobuf_unittest.TestBoolMap.BoolMapEntry\x1a.\n\x0c\x42oolMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\x08\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\"O\n\rTestRecursion\x12\r\n\x05value\x18\x01 \x01(\x05\x12/\n\x05\x63hild\x18\x02 \x01(\x0b\x32 .protobuf_unittest.TestRecursion\"\x86\x01\n\rTestStringMap\x12\x43\n\nstring_map\x18\x01 \x03(\x0b\x32/.protobuf_unittest.TestStringMap.StringMapEntry\x1a\x30\n\x0eStringMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xc4\x01\n\x14TestStringSerializer\x12\x15\n\rscalar_string\x18\x01 \x01(\t\x12\x17\n\x0frepeated_string\x18\x02 \x03(\t\x12J\n\nstring_map\x18\x03 \x03(\x0b\x32\x36.protobuf_unittest.TestStringSerializer.StringMapEntry\x1a\x30\n\x0eStringMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"$\n\x18TestMessageWithExtension*\x08\x08\x64\x10\x80\x80\x80\x80\x02\"z\n\rTestExtension\x12\r\n\x05value\x18\x01 \x01(\t2Z\n\x03\x65xt\x12+.protobuf_unittest.TestMessageWithExtension\x18\x64 \x01(\x0b\x32 .protobuf_unittest.TestExtension\"Q\n\x14TestDefaultEnumValue\x12\x39\n\nenum_value\x18\x01 \x01(\x0e\x32\x1c.protobuf_unittest.EnumValue:\x07\x44\x45\x46\x41ULT*2\n\tEnumValue\x12\x0c\n\x08PROTOCOL\x10\x00\x12\n\n\x06\x42UFFER\x10\x01\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x02') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.util.json_format_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - TestMessageWithExtension.RegisterExtension(_TESTEXTENSION.extensions_by_name['ext']) - - DESCRIPTOR._options = None - _TESTBOOLMAP_BOOLMAPENTRY._options = None - _TESTBOOLMAP_BOOLMAPENTRY._serialized_options = b'8\001' - _TESTSTRINGMAP_STRINGMAPENTRY._options = None - _TESTSTRINGMAP_STRINGMAPENTRY._serialized_options = b'8\001' - _TESTSTRINGSERIALIZER_STRINGMAPENTRY._options = None - _TESTSTRINGSERIALIZER_STRINGMAPENTRY._serialized_options = b'8\001' - _ENUMVALUE._serialized_start=1607 - _ENUMVALUE._serialized_end=1657 - _TESTFLAGSANDSTRINGS._serialized_start=62 - _TESTFLAGSANDSTRINGS._serialized_end=199 - _TESTFLAGSANDSTRINGS_REPEATEDGROUP._serialized_start=173 - _TESTFLAGSANDSTRINGS_REPEATEDGROUP._serialized_end=199 - _TESTBASE64BYTEARRAYS._serialized_start=201 - _TESTBASE64BYTEARRAYS._serialized_end=234 - _TESTJAVASCRIPTJSON._serialized_start=236 - _TESTJAVASCRIPTJSON._serialized_end=307 - _TESTJAVASCRIPTORDERJSON1._serialized_start=309 - _TESTJAVASCRIPTORDERJSON1._serialized_end=390 - _TESTJAVASCRIPTORDERJSON2._serialized_start=393 - _TESTJAVASCRIPTORDERJSON2._serialized_end=530 - _TESTLARGEINT._serialized_start=532 - _TESTLARGEINT._serialized_end=568 - _TESTNUMBERS._serialized_start=571 - _TESTNUMBERS._serialized_end=731 - _TESTNUMBERS_MYTYPE._serialized_start=691 - _TESTNUMBERS_MYTYPE._serialized_end=731 - _TESTCAMELCASE._serialized_start=733 - _TESTCAMELCASE._serialized_end=817 - _TESTBOOLMAP._serialized_start=819 - _TESTBOOLMAP._serialized_end=943 - _TESTBOOLMAP_BOOLMAPENTRY._serialized_start=897 - _TESTBOOLMAP_BOOLMAPENTRY._serialized_end=943 - _TESTRECURSION._serialized_start=945 - _TESTRECURSION._serialized_end=1024 - _TESTSTRINGMAP._serialized_start=1027 - _TESTSTRINGMAP._serialized_end=1161 - _TESTSTRINGMAP_STRINGMAPENTRY._serialized_start=1113 - _TESTSTRINGMAP_STRINGMAPENTRY._serialized_end=1161 - _TESTSTRINGSERIALIZER._serialized_start=1164 - _TESTSTRINGSERIALIZER._serialized_end=1360 - _TESTSTRINGSERIALIZER_STRINGMAPENTRY._serialized_start=1113 - _TESTSTRINGSERIALIZER_STRINGMAPENTRY._serialized_end=1161 - _TESTMESSAGEWITHEXTENSION._serialized_start=1362 - _TESTMESSAGEWITHEXTENSION._serialized_end=1398 - _TESTEXTENSION._serialized_start=1400 - _TESTEXTENSION._serialized_end=1522 - _TESTDEFAULTENUMVALUE._serialized_start=1524 - _TESTDEFAULTENUMVALUE._serialized_end=1605 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/util/json_format_proto3_pb2.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/util/json_format_proto3_pb2.py deleted file mode 100644 index 5498deafa9..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/util/json_format_proto3_pb2.py +++ /dev/null @@ -1,129 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/util/json_format_proto3.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2 -from google.protobuf import duration_pb2 as google_dot_protobuf_dot_duration__pb2 -from google.protobuf import field_mask_pb2 as google_dot_protobuf_dot_field__mask__pb2 -from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2 -from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 -from google.protobuf import wrappers_pb2 as google_dot_protobuf_dot_wrappers__pb2 -from google.protobuf import unittest_pb2 as google_dot_protobuf_dot_unittest__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n-google/protobuf/util/json_format_proto3.proto\x12\x06proto3\x1a\x19google/protobuf/any.proto\x1a\x1egoogle/protobuf/duration.proto\x1a google/protobuf/field_mask.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1egoogle/protobuf/wrappers.proto\x1a\x1egoogle/protobuf/unittest.proto\"\x1c\n\x0bMessageType\x12\r\n\x05value\x18\x01 \x01(\x05\"\x94\x05\n\x0bTestMessage\x12\x12\n\nbool_value\x18\x01 \x01(\x08\x12\x13\n\x0bint32_value\x18\x02 \x01(\x05\x12\x13\n\x0bint64_value\x18\x03 \x01(\x03\x12\x14\n\x0cuint32_value\x18\x04 \x01(\r\x12\x14\n\x0cuint64_value\x18\x05 \x01(\x04\x12\x13\n\x0b\x66loat_value\x18\x06 \x01(\x02\x12\x14\n\x0c\x64ouble_value\x18\x07 \x01(\x01\x12\x14\n\x0cstring_value\x18\x08 \x01(\t\x12\x13\n\x0b\x62ytes_value\x18\t \x01(\x0c\x12$\n\nenum_value\x18\n \x01(\x0e\x32\x10.proto3.EnumType\x12*\n\rmessage_value\x18\x0b \x01(\x0b\x32\x13.proto3.MessageType\x12\x1b\n\x13repeated_bool_value\x18\x15 \x03(\x08\x12\x1c\n\x14repeated_int32_value\x18\x16 \x03(\x05\x12\x1c\n\x14repeated_int64_value\x18\x17 \x03(\x03\x12\x1d\n\x15repeated_uint32_value\x18\x18 \x03(\r\x12\x1d\n\x15repeated_uint64_value\x18\x19 \x03(\x04\x12\x1c\n\x14repeated_float_value\x18\x1a \x03(\x02\x12\x1d\n\x15repeated_double_value\x18\x1b \x03(\x01\x12\x1d\n\x15repeated_string_value\x18\x1c \x03(\t\x12\x1c\n\x14repeated_bytes_value\x18\x1d \x03(\x0c\x12-\n\x13repeated_enum_value\x18\x1e \x03(\x0e\x32\x10.proto3.EnumType\x12\x33\n\x16repeated_message_value\x18\x1f \x03(\x0b\x32\x13.proto3.MessageType\"\x8c\x02\n\tTestOneof\x12\x1b\n\x11oneof_int32_value\x18\x01 \x01(\x05H\x00\x12\x1c\n\x12oneof_string_value\x18\x02 \x01(\tH\x00\x12\x1b\n\x11oneof_bytes_value\x18\x03 \x01(\x0cH\x00\x12,\n\x10oneof_enum_value\x18\x04 \x01(\x0e\x32\x10.proto3.EnumTypeH\x00\x12\x32\n\x13oneof_message_value\x18\x05 \x01(\x0b\x32\x13.proto3.MessageTypeH\x00\x12\x36\n\x10oneof_null_value\x18\x06 \x01(\x0e\x32\x1a.google.protobuf.NullValueH\x00\x42\r\n\x0boneof_value\"\xe1\x04\n\x07TestMap\x12.\n\x08\x62ool_map\x18\x01 \x03(\x0b\x32\x1c.proto3.TestMap.BoolMapEntry\x12\x30\n\tint32_map\x18\x02 \x03(\x0b\x32\x1d.proto3.TestMap.Int32MapEntry\x12\x30\n\tint64_map\x18\x03 \x03(\x0b\x32\x1d.proto3.TestMap.Int64MapEntry\x12\x32\n\nuint32_map\x18\x04 \x03(\x0b\x32\x1e.proto3.TestMap.Uint32MapEntry\x12\x32\n\nuint64_map\x18\x05 \x03(\x0b\x32\x1e.proto3.TestMap.Uint64MapEntry\x12\x32\n\nstring_map\x18\x06 \x03(\x0b\x32\x1e.proto3.TestMap.StringMapEntry\x1a.\n\x0c\x42oolMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\x08\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a/\n\rInt32MapEntry\x12\x0b\n\x03key\x18\x01 \x01(\x05\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a/\n\rInt64MapEntry\x12\x0b\n\x03key\x18\x01 \x01(\x03\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a\x30\n\x0eUint32MapEntry\x12\x0b\n\x03key\x18\x01 \x01(\r\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a\x30\n\x0eUint64MapEntry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a\x30\n\x0eStringMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\"\x85\x06\n\rTestNestedMap\x12\x34\n\x08\x62ool_map\x18\x01 \x03(\x0b\x32\".proto3.TestNestedMap.BoolMapEntry\x12\x36\n\tint32_map\x18\x02 \x03(\x0b\x32#.proto3.TestNestedMap.Int32MapEntry\x12\x36\n\tint64_map\x18\x03 \x03(\x0b\x32#.proto3.TestNestedMap.Int64MapEntry\x12\x38\n\nuint32_map\x18\x04 \x03(\x0b\x32$.proto3.TestNestedMap.Uint32MapEntry\x12\x38\n\nuint64_map\x18\x05 \x03(\x0b\x32$.proto3.TestNestedMap.Uint64MapEntry\x12\x38\n\nstring_map\x18\x06 \x03(\x0b\x32$.proto3.TestNestedMap.StringMapEntry\x12\x32\n\x07map_map\x18\x07 \x03(\x0b\x32!.proto3.TestNestedMap.MapMapEntry\x1a.\n\x0c\x42oolMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\x08\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a/\n\rInt32MapEntry\x12\x0b\n\x03key\x18\x01 \x01(\x05\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a/\n\rInt64MapEntry\x12\x0b\n\x03key\x18\x01 \x01(\x03\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a\x30\n\x0eUint32MapEntry\x12\x0b\n\x03key\x18\x01 \x01(\r\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a\x30\n\x0eUint64MapEntry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a\x30\n\x0eStringMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a\x44\n\x0bMapMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12$\n\x05value\x18\x02 \x01(\x0b\x32\x15.proto3.TestNestedMap:\x02\x38\x01\"{\n\rTestStringMap\x12\x38\n\nstring_map\x18\x01 \x03(\x0b\x32$.proto3.TestStringMap.StringMapEntry\x1a\x30\n\x0eStringMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xee\x07\n\x0bTestWrapper\x12.\n\nbool_value\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x30\n\x0bint32_value\x18\x02 \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12\x30\n\x0bint64_value\x18\x03 \x01(\x0b\x32\x1b.google.protobuf.Int64Value\x12\x32\n\x0cuint32_value\x18\x04 \x01(\x0b\x32\x1c.google.protobuf.UInt32Value\x12\x32\n\x0cuint64_value\x18\x05 \x01(\x0b\x32\x1c.google.protobuf.UInt64Value\x12\x30\n\x0b\x66loat_value\x18\x06 \x01(\x0b\x32\x1b.google.protobuf.FloatValue\x12\x32\n\x0c\x64ouble_value\x18\x07 \x01(\x0b\x32\x1c.google.protobuf.DoubleValue\x12\x32\n\x0cstring_value\x18\x08 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x30\n\x0b\x62ytes_value\x18\t \x01(\x0b\x32\x1b.google.protobuf.BytesValue\x12\x37\n\x13repeated_bool_value\x18\x0b \x03(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x39\n\x14repeated_int32_value\x18\x0c \x03(\x0b\x32\x1b.google.protobuf.Int32Value\x12\x39\n\x14repeated_int64_value\x18\r \x03(\x0b\x32\x1b.google.protobuf.Int64Value\x12;\n\x15repeated_uint32_value\x18\x0e \x03(\x0b\x32\x1c.google.protobuf.UInt32Value\x12;\n\x15repeated_uint64_value\x18\x0f \x03(\x0b\x32\x1c.google.protobuf.UInt64Value\x12\x39\n\x14repeated_float_value\x18\x10 \x03(\x0b\x32\x1b.google.protobuf.FloatValue\x12;\n\x15repeated_double_value\x18\x11 \x03(\x0b\x32\x1c.google.protobuf.DoubleValue\x12;\n\x15repeated_string_value\x18\x12 \x03(\x0b\x32\x1c.google.protobuf.StringValue\x12\x39\n\x14repeated_bytes_value\x18\x13 \x03(\x0b\x32\x1b.google.protobuf.BytesValue\"n\n\rTestTimestamp\x12)\n\x05value\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x32\n\x0erepeated_value\x18\x02 \x03(\x0b\x32\x1a.google.protobuf.Timestamp\"k\n\x0cTestDuration\x12(\n\x05value\x18\x01 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x31\n\x0erepeated_value\x18\x02 \x03(\x0b\x32\x19.google.protobuf.Duration\":\n\rTestFieldMask\x12)\n\x05value\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.FieldMask\"e\n\nTestStruct\x12&\n\x05value\x18\x01 \x01(\x0b\x32\x17.google.protobuf.Struct\x12/\n\x0erepeated_value\x18\x02 \x03(\x0b\x32\x17.google.protobuf.Struct\"\\\n\x07TestAny\x12#\n\x05value\x18\x01 \x01(\x0b\x32\x14.google.protobuf.Any\x12,\n\x0erepeated_value\x18\x02 \x03(\x0b\x32\x14.google.protobuf.Any\"b\n\tTestValue\x12%\n\x05value\x18\x01 \x01(\x0b\x32\x16.google.protobuf.Value\x12.\n\x0erepeated_value\x18\x02 \x03(\x0b\x32\x16.google.protobuf.Value\"n\n\rTestListValue\x12)\n\x05value\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.ListValue\x12\x32\n\x0erepeated_value\x18\x02 \x03(\x0b\x32\x1a.google.protobuf.ListValue\"\x89\x01\n\rTestBoolValue\x12\x12\n\nbool_value\x18\x01 \x01(\x08\x12\x34\n\x08\x62ool_map\x18\x02 \x03(\x0b\x32\".proto3.TestBoolValue.BoolMapEntry\x1a.\n\x0c\x42oolMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\x08\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\"+\n\x12TestCustomJsonName\x12\x15\n\x05value\x18\x01 \x01(\x05R\x06@value\"J\n\x0eTestExtensions\x12\x38\n\nextensions\x18\x01 \x01(\x0b\x32$.protobuf_unittest.TestAllExtensions\"\x84\x01\n\rTestEnumValue\x12%\n\x0b\x65num_value1\x18\x01 \x01(\x0e\x32\x10.proto3.EnumType\x12%\n\x0b\x65num_value2\x18\x02 \x01(\x0e\x32\x10.proto3.EnumType\x12%\n\x0b\x65num_value3\x18\x03 \x01(\x0e\x32\x10.proto3.EnumType*\x1c\n\x08\x45numType\x12\x07\n\x03\x46OO\x10\x00\x12\x07\n\x03\x42\x41R\x10\x01\x42,\n\x18\x63om.google.protobuf.utilB\x10JsonFormatProto3b\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.util.json_format_proto3_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\030com.google.protobuf.utilB\020JsonFormatProto3' - _TESTMAP_BOOLMAPENTRY._options = None - _TESTMAP_BOOLMAPENTRY._serialized_options = b'8\001' - _TESTMAP_INT32MAPENTRY._options = None - _TESTMAP_INT32MAPENTRY._serialized_options = b'8\001' - _TESTMAP_INT64MAPENTRY._options = None - _TESTMAP_INT64MAPENTRY._serialized_options = b'8\001' - _TESTMAP_UINT32MAPENTRY._options = None - _TESTMAP_UINT32MAPENTRY._serialized_options = b'8\001' - _TESTMAP_UINT64MAPENTRY._options = None - _TESTMAP_UINT64MAPENTRY._serialized_options = b'8\001' - _TESTMAP_STRINGMAPENTRY._options = None - _TESTMAP_STRINGMAPENTRY._serialized_options = b'8\001' - _TESTNESTEDMAP_BOOLMAPENTRY._options = None - _TESTNESTEDMAP_BOOLMAPENTRY._serialized_options = b'8\001' - _TESTNESTEDMAP_INT32MAPENTRY._options = None - _TESTNESTEDMAP_INT32MAPENTRY._serialized_options = b'8\001' - _TESTNESTEDMAP_INT64MAPENTRY._options = None - _TESTNESTEDMAP_INT64MAPENTRY._serialized_options = b'8\001' - _TESTNESTEDMAP_UINT32MAPENTRY._options = None - _TESTNESTEDMAP_UINT32MAPENTRY._serialized_options = b'8\001' - _TESTNESTEDMAP_UINT64MAPENTRY._options = None - _TESTNESTEDMAP_UINT64MAPENTRY._serialized_options = b'8\001' - _TESTNESTEDMAP_STRINGMAPENTRY._options = None - _TESTNESTEDMAP_STRINGMAPENTRY._serialized_options = b'8\001' - _TESTNESTEDMAP_MAPMAPENTRY._options = None - _TESTNESTEDMAP_MAPMAPENTRY._serialized_options = b'8\001' - _TESTSTRINGMAP_STRINGMAPENTRY._options = None - _TESTSTRINGMAP_STRINGMAPENTRY._serialized_options = b'8\001' - _TESTBOOLVALUE_BOOLMAPENTRY._options = None - _TESTBOOLVALUE_BOOLMAPENTRY._serialized_options = b'8\001' - _ENUMTYPE._serialized_start=4849 - _ENUMTYPE._serialized_end=4877 - _MESSAGETYPE._serialized_start=277 - _MESSAGETYPE._serialized_end=305 - _TESTMESSAGE._serialized_start=308 - _TESTMESSAGE._serialized_end=968 - _TESTONEOF._serialized_start=971 - _TESTONEOF._serialized_end=1239 - _TESTMAP._serialized_start=1242 - _TESTMAP._serialized_end=1851 - _TESTMAP_BOOLMAPENTRY._serialized_start=1557 - _TESTMAP_BOOLMAPENTRY._serialized_end=1603 - _TESTMAP_INT32MAPENTRY._serialized_start=1605 - _TESTMAP_INT32MAPENTRY._serialized_end=1652 - _TESTMAP_INT64MAPENTRY._serialized_start=1654 - _TESTMAP_INT64MAPENTRY._serialized_end=1701 - _TESTMAP_UINT32MAPENTRY._serialized_start=1703 - _TESTMAP_UINT32MAPENTRY._serialized_end=1751 - _TESTMAP_UINT64MAPENTRY._serialized_start=1753 - _TESTMAP_UINT64MAPENTRY._serialized_end=1801 - _TESTMAP_STRINGMAPENTRY._serialized_start=1803 - _TESTMAP_STRINGMAPENTRY._serialized_end=1851 - _TESTNESTEDMAP._serialized_start=1854 - _TESTNESTEDMAP._serialized_end=2627 - _TESTNESTEDMAP_BOOLMAPENTRY._serialized_start=1557 - _TESTNESTEDMAP_BOOLMAPENTRY._serialized_end=1603 - _TESTNESTEDMAP_INT32MAPENTRY._serialized_start=1605 - _TESTNESTEDMAP_INT32MAPENTRY._serialized_end=1652 - _TESTNESTEDMAP_INT64MAPENTRY._serialized_start=1654 - _TESTNESTEDMAP_INT64MAPENTRY._serialized_end=1701 - _TESTNESTEDMAP_UINT32MAPENTRY._serialized_start=1703 - _TESTNESTEDMAP_UINT32MAPENTRY._serialized_end=1751 - _TESTNESTEDMAP_UINT64MAPENTRY._serialized_start=1753 - _TESTNESTEDMAP_UINT64MAPENTRY._serialized_end=1801 - _TESTNESTEDMAP_STRINGMAPENTRY._serialized_start=1803 - _TESTNESTEDMAP_STRINGMAPENTRY._serialized_end=1851 - _TESTNESTEDMAP_MAPMAPENTRY._serialized_start=2559 - _TESTNESTEDMAP_MAPMAPENTRY._serialized_end=2627 - _TESTSTRINGMAP._serialized_start=2629 - _TESTSTRINGMAP._serialized_end=2752 - _TESTSTRINGMAP_STRINGMAPENTRY._serialized_start=2704 - _TESTSTRINGMAP_STRINGMAPENTRY._serialized_end=2752 - _TESTWRAPPER._serialized_start=2755 - _TESTWRAPPER._serialized_end=3761 - _TESTTIMESTAMP._serialized_start=3763 - _TESTTIMESTAMP._serialized_end=3873 - _TESTDURATION._serialized_start=3875 - _TESTDURATION._serialized_end=3982 - _TESTFIELDMASK._serialized_start=3984 - _TESTFIELDMASK._serialized_end=4042 - _TESTSTRUCT._serialized_start=4044 - _TESTSTRUCT._serialized_end=4145 - _TESTANY._serialized_start=4147 - _TESTANY._serialized_end=4239 - _TESTVALUE._serialized_start=4241 - _TESTVALUE._serialized_end=4339 - _TESTLISTVALUE._serialized_start=4341 - _TESTLISTVALUE._serialized_end=4451 - _TESTBOOLVALUE._serialized_start=4454 - _TESTBOOLVALUE._serialized_end=4591 - _TESTBOOLVALUE_BOOLMAPENTRY._serialized_start=1557 - _TESTBOOLVALUE_BOOLMAPENTRY._serialized_end=1603 - _TESTCUSTOMJSONNAME._serialized_start=4593 - _TESTCUSTOMJSONNAME._serialized_end=4636 - _TESTEXTENSIONS._serialized_start=4638 - _TESTEXTENSIONS._serialized_end=4712 - _TESTENUMVALUE._serialized_start=4715 - _TESTENUMVALUE._serialized_end=4847 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/wrappers_pb2.py b/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/wrappers_pb2.py deleted file mode 100644 index e49eb4c15d..0000000000 --- a/server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/wrappers_pb2.py +++ /dev/null @@ -1,42 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/wrappers.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1egoogle/protobuf/wrappers.proto\x12\x0fgoogle.protobuf\"\x1c\n\x0b\x44oubleValue\x12\r\n\x05value\x18\x01 \x01(\x01\"\x1b\n\nFloatValue\x12\r\n\x05value\x18\x01 \x01(\x02\"\x1b\n\nInt64Value\x12\r\n\x05value\x18\x01 \x01(\x03\"\x1c\n\x0bUInt64Value\x12\r\n\x05value\x18\x01 \x01(\x04\"\x1b\n\nInt32Value\x12\r\n\x05value\x18\x01 \x01(\x05\"\x1c\n\x0bUInt32Value\x12\r\n\x05value\x18\x01 \x01(\r\"\x1a\n\tBoolValue\x12\r\n\x05value\x18\x01 \x01(\x08\"\x1c\n\x0bStringValue\x12\r\n\x05value\x18\x01 \x01(\t\"\x1b\n\nBytesValue\x12\r\n\x05value\x18\x01 \x01(\x0c\x42\x83\x01\n\x13\x63om.google.protobufB\rWrappersProtoP\x01Z1google.golang.org/protobuf/types/known/wrapperspb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.wrappers_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.google.protobufB\rWrappersProtoP\001Z1google.golang.org/protobuf/types/known/wrapperspb\370\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' - _DOUBLEVALUE._serialized_start=51 - _DOUBLEVALUE._serialized_end=79 - _FLOATVALUE._serialized_start=81 - _FLOATVALUE._serialized_end=108 - _INT64VALUE._serialized_start=110 - _INT64VALUE._serialized_end=137 - _UINT64VALUE._serialized_start=139 - _UINT64VALUE._serialized_end=167 - _INT32VALUE._serialized_start=169 - _INT32VALUE._serialized_end=196 - _UINT32VALUE._serialized_start=198 - _UINT32VALUE._serialized_end=226 - _BOOLVALUE._serialized_start=228 - _BOOLVALUE._serialized_end=254 - _STRINGVALUE._serialized_start=256 - _STRINGVALUE._serialized_end=284 - _BYTESVALUE._serialized_start=286 - _BYTESVALUE._serialized_end=313 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/hiero/client/ayon_hiero/version.py b/server_addon/hiero/client/ayon_hiero/version.py deleted file mode 100644 index 74ebfba8b0..0000000000 --- a/server_addon/hiero/client/ayon_hiero/version.py +++ /dev/null @@ -1,3 +0,0 @@ -# -*- coding: utf-8 -*- -"""Package declaring AYON addon 'hiero' version.""" -__version__ = "0.2.2" diff --git a/server_addon/hiero/package.py b/server_addon/hiero/package.py deleted file mode 100644 index eba3fb12f4..0000000000 --- a/server_addon/hiero/package.py +++ /dev/null @@ -1,9 +0,0 @@ -name = "hiero" -title = "Hiero" -version = "0.2.2" -client_dir = "ayon_hiero" - -ayon_required_addons = { - "core": ">0.3.2", -} -ayon_compatible_addons = {} diff --git a/server_addon/hiero/server/__init__.py b/server_addon/hiero/server/__init__.py deleted file mode 100644 index 3db78eafd7..0000000000 --- a/server_addon/hiero/server/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -from typing import Type - -from ayon_server.addons import BaseServerAddon - -from .settings import HieroSettings, DEFAULT_VALUES - - -class HieroAddon(BaseServerAddon): - settings_model: Type[HieroSettings] = HieroSettings - - async def get_default_settings(self): - settings_model_cls = self.get_settings_model() - return settings_model_cls(**DEFAULT_VALUES) diff --git a/server_addon/hiero/server/settings/__init__.py b/server_addon/hiero/server/settings/__init__.py deleted file mode 100644 index 246c8203e9..0000000000 --- a/server_addon/hiero/server/settings/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -from .main import ( - HieroSettings, - DEFAULT_VALUES, -) - - -__all__ = ( - "HieroSettings", - "DEFAULT_VALUES", -) diff --git a/server_addon/hiero/server/settings/common.py b/server_addon/hiero/server/settings/common.py deleted file mode 100644 index 7b5e4390c5..0000000000 --- a/server_addon/hiero/server/settings/common.py +++ /dev/null @@ -1,97 +0,0 @@ -from ayon_server.settings import BaseSettingsModel, SettingsField -from ayon_server.types import ( - ColorRGBA_float, - ColorRGB_uint8 -) - - -class Vector2d(BaseSettingsModel): - _layout = "compact" - - x: float = SettingsField(1.0, title="X") - y: float = SettingsField(1.0, title="Y") - - -class Vector3d(BaseSettingsModel): - _layout = "compact" - - x: float = SettingsField(1.0, title="X") - y: float = SettingsField(1.0, title="Y") - z: float = SettingsField(1.0, title="Z") - - -def formatable_knob_type_enum(): - return [ - {"value": "text", "label": "Text"}, - {"value": "number", "label": "Number"}, - {"value": "decimal_number", "label": "Decimal number"}, - {"value": "2d_vector", "label": "2D vector"}, - # "3D vector" - ] - - -class Formatable(BaseSettingsModel): - _layout = "compact" - - template: str = SettingsField( - "", - placeholder="""{{key}} or {{key}};{{key}}""", - title="Template" - ) - to_type: str = SettingsField( - "Text", - title="To Knob type", - enum_resolver=formatable_knob_type_enum, - ) - - -knob_types_enum = [ - {"value": "text", "label": "Text"}, - {"value": "formatable", "label": "Formate from template"}, - {"value": "color_gui", "label": "Color GUI"}, - {"value": "boolean", "label": "Boolean"}, - {"value": "number", "label": "Number"}, - {"value": "decimal_number", "label": "Decimal number"}, - {"value": "vector_2d", "label": "2D vector"}, - {"value": "vector_3d", "label": "3D vector"}, - {"value": "color", "label": "Color"} -] - - -class KnobModel(BaseSettingsModel): - _layout = "expanded" - - type: str = SettingsField( - title="Type", - description="Switch between different knob types", - enum_resolver=lambda: knob_types_enum, - conditionalEnum=True - ) - name: str = SettingsField( - title="Name", - placeholder="Name" - ) - text: str = SettingsField("", title="Value") - color_gui: ColorRGB_uint8 = SettingsField( - (0, 0, 255), - title="RGB Uint8", - ) - boolean: bool = SettingsField(False, title="Value") - number: int = SettingsField(0, title="Value") - decimal_number: float = SettingsField(0.0, title="Value") - vector_2d: Vector2d = SettingsField( - default_factory=Vector2d, - title="Value" - ) - vector_3d: Vector3d = SettingsField( - default_factory=Vector3d, - title="Value" - ) - color: ColorRGBA_float = SettingsField( - (0.0, 0.0, 1.0, 1.0), - title="RGBA Float" - ) - formatable: Formatable = SettingsField( - default_factory=Formatable, - title="Value" - ) diff --git a/server_addon/hiero/server/settings/create_plugins.py b/server_addon/hiero/server/settings/create_plugins.py deleted file mode 100644 index 80e0b67182..0000000000 --- a/server_addon/hiero/server/settings/create_plugins.py +++ /dev/null @@ -1,96 +0,0 @@ -from ayon_server.settings import BaseSettingsModel, SettingsField - - -class CreateShotClipModels(BaseSettingsModel): - hierarchy: str = SettingsField( - "{folder}/{sequence}", - title="Shot parent hierarchy", - section="Shot Hierarchy And Rename Settings" - ) - clipRename: bool = SettingsField( - True, - title="Rename clips" - ) - clipName: str = SettingsField( - "{track}{sequence}{shot}", - title="Clip name template" - ) - countFrom: int = SettingsField( - 10, - title="Count sequence from" - ) - countSteps: int = SettingsField( - 10, - title="Stepping number" - ) - - folder: str = SettingsField( - "shots", - title="{folder}", - section="Shot Template Keywords" - ) - episode: str = SettingsField( - "ep01", - title="{episode}" - ) - sequence: str = SettingsField( - "sq01", - title="{sequence}" - ) - track: str = SettingsField( - "{_track_}", - title="{track}" - ) - shot: str = SettingsField( - "sh###", - title="{shot}" - ) - - vSyncOn: bool = SettingsField( - False, - title="Enable Vertical Sync", - section="Vertical Synchronization Of Attributes" - ) - - workfileFrameStart: int = SettingsField( - 1001, - title="Workfiles Start Frame", - section="Shot Attributes" - ) - handleStart: int = SettingsField( - 10, - title="Handle start (head)" - ) - handleEnd: int = SettingsField( - 10, - title="Handle end (tail)" - ) - - -class CreatorPluginsSettings(BaseSettingsModel): - CreateShotClip: CreateShotClipModels = SettingsField( - default_factory=CreateShotClipModels, - title="Create Shot Clip" - ) - - -DEFAULT_CREATE_SETTINGS = { - "create": { - "CreateShotClip": { - "hierarchy": "{folder}/{sequence}", - "clipRename": True, - "clipName": "{track}{sequence}{shot}", - "countFrom": 10, - "countSteps": 10, - "folder": "shots", - "episode": "ep01", - "sequence": "sq01", - "track": "{_track_}", - "shot": "sh###", - "vSyncOn": False, - "workfileFrameStart": 1001, - "handleStart": 10, - "handleEnd": 10 - } - } -} diff --git a/server_addon/hiero/server/settings/filters.py b/server_addon/hiero/server/settings/filters.py deleted file mode 100644 index 095d30a004..0000000000 --- a/server_addon/hiero/server/settings/filters.py +++ /dev/null @@ -1,25 +0,0 @@ -from pydantic import validator -from ayon_server.settings import ( - BaseSettingsModel, - SettingsField, - ensure_unique_names, -) - - -class PublishGUIFilterItemModel(BaseSettingsModel): - _layout = "compact" - name: str = SettingsField(title="Name") - value: bool = SettingsField(True, title="Active") - - -class PublishGUIFiltersModel(BaseSettingsModel): - _layout = "compact" - name: str = SettingsField(title="Name") - value: list[PublishGUIFilterItemModel] = SettingsField( - default_factory=list - ) - - @validator("value") - def validate_unique_outputs(cls, value): - ensure_unique_names(value) - return value diff --git a/server_addon/hiero/server/settings/imageio.py b/server_addon/hiero/server/settings/imageio.py deleted file mode 100644 index 83ae7024f9..0000000000 --- a/server_addon/hiero/server/settings/imageio.py +++ /dev/null @@ -1,185 +0,0 @@ -from pydantic import validator - -from ayon_server.settings import ( - BaseSettingsModel, - SettingsField, - ensure_unique_names, -) - - -def ocio_configs_switcher_enum(): - return [ - {"value": "nuke-default", "label": "nuke-default"}, - {"value": "spi-vfx", "label": "spi-vfx"}, - {"value": "spi-anim", "label": "spi-anim"}, - {"value": "aces_0.1.1", "label": "aces_0.1.1"}, - {"value": "aces_0.7.1", "label": "aces_0.7.1"}, - {"value": "aces_1.0.1", "label": "aces_1.0.1"}, - {"value": "aces_1.0.3", "label": "aces_1.0.3"}, - {"value": "aces_1.1", "label": "aces_1.1"}, - {"value": "aces_1.2", "label": "aces_1.2"}, - {"value": "aces_1.3", "label": "aces_1.3"}, - {"value": "custom", "label": "custom"} - ] - - -class WorkfileColorspaceSettings(BaseSettingsModel): - """Hiero workfile colorspace preset. """ - """# TODO: enhance settings with host api: - we need to add mapping to resolve properly keys. - Hiero is excpecting camel case key names, - but for better code consistency we are using snake_case: - - ocio_config = ocioConfigName - working_space_name = workingSpace - int_16_name = sixteenBitLut - int_8_name = eightBitLut - float_name = floatLut - log_name = logLut - viewer_name = viewerLut - thumbnail_name = thumbnailLut - """ - - ocioConfigName: str = SettingsField( - title="OpenColorIO Config", - description="Switch between OCIO configs", - enum_resolver=ocio_configs_switcher_enum, - conditionalEnum=True - ) - workingSpace: str = SettingsField( - title="Working Space" - ) - viewerLut: str = SettingsField( - title="Viewer" - ) - eightBitLut: str = SettingsField( - title="8-bit files" - ) - sixteenBitLut: str = SettingsField( - title="16-bit files" - ) - logLut: str = SettingsField( - title="Log files" - ) - floatLut: str = SettingsField( - title="Float files" - ) - thumbnailLut: str = SettingsField( - title="Thumnails" - ) - monitorOutLut: str = SettingsField( - title="Monitor" - ) - - -class ClipColorspaceRulesItems(BaseSettingsModel): - _layout = "expanded" - - regex: str = SettingsField("", title="Regex expression") - colorspace: str = SettingsField("", title="Colorspace") - - -class RegexInputsModel(BaseSettingsModel): - inputs: list[ClipColorspaceRulesItems] = SettingsField( - default_factory=list, - title="Inputs" - ) - - -class ImageIOConfigModel(BaseSettingsModel): - """[DEPRECATED] Addon OCIO config settings. Please set the OCIO config - path in the Core addon profiles here - (ayon+settings://core/imageio/ocio_config_profiles). - """ - - override_global_config: bool = SettingsField( - False, - title="Override global OCIO config", - description=( - "DEPRECATED functionality. Please set the OCIO config path in the " - "Core addon profiles here (ayon+settings://core/imageio/" - "ocio_config_profiles)." - ), - ) - filepath: list[str] = SettingsField( - default_factory=list, - title="Config path", - description=( - "DEPRECATED functionality. Please set the OCIO config path in the " - "Core addon profiles here (ayon+settings://core/imageio/" - "ocio_config_profiles)." - ), - ) - - -class ImageIOFileRuleModel(BaseSettingsModel): - name: str = SettingsField("", title="Rule name") - pattern: str = SettingsField("", title="Regex pattern") - colorspace: str = SettingsField("", title="Colorspace name") - ext: str = SettingsField("", title="File extension") - - -class ImageIOFileRulesModel(BaseSettingsModel): - activate_host_rules: bool = SettingsField(False) - rules: list[ImageIOFileRuleModel] = SettingsField( - default_factory=list, - title="Rules" - ) - - @validator("rules") - def validate_unique_outputs(cls, value): - ensure_unique_names(value) - return value - - -class ImageIOSettings(BaseSettingsModel): - """Hiero color management project settings. """ - _isGroup: bool = True - activate_host_color_management: bool = SettingsField( - True, title="Enable Color Management" - ) - ocio_config: ImageIOConfigModel = SettingsField( - default_factory=ImageIOConfigModel, - title="OCIO config" - ) - file_rules: ImageIOFileRulesModel = SettingsField( - default_factory=ImageIOFileRulesModel, - title="File Rules" - ) - workfile: WorkfileColorspaceSettings = SettingsField( - default_factory=WorkfileColorspaceSettings, - title="Workfile" - ) - """# TODO: enhance settings with host api: - - old settings are using `regexInputs` key but we - need to rename to `regex_inputs` - - no need for `inputs` middle part. It can stay - directly on `regex_inputs` - """ - regexInputs: RegexInputsModel = SettingsField( - default_factory=RegexInputsModel, - title="Assign colorspace to clips via rules" - ) - - -DEFAULT_IMAGEIO_SETTINGS = { - "workfile": { - "ocioConfigName": "aces_1.2", - "workingSpace": "role_scene_linear", - "viewerLut": "ACES/sRGB", - "eightBitLut": "role_matte_paint", - "sixteenBitLut": "role_texture_paint", - "logLut": "role_compositing_log", - "floatLut": "role_scene_linear", - "thumbnailLut": "ACES/sRGB", - "monitorOutLut": "ACES/sRGB" - }, - "regexInputs": { - "inputs": [ - { - "regex": "[^-a-zA-Z0-9](plateRef).*(?=mp4)", - "colorspace": "sRGB" - } - ] - } -} diff --git a/server_addon/hiero/server/settings/loader_plugins.py b/server_addon/hiero/server/settings/loader_plugins.py deleted file mode 100644 index 682f9fd2d9..0000000000 --- a/server_addon/hiero/server/settings/loader_plugins.py +++ /dev/null @@ -1,37 +0,0 @@ -from ayon_server.settings import BaseSettingsModel, SettingsField - - -class LoadClipModel(BaseSettingsModel): - enabled: bool = SettingsField( - True, - title="Enabled" - ) - product_types: list[str] = SettingsField( - default_factory=list, - title="Product types" - ) - clip_name_template: str = SettingsField( - title="Clip name template" - ) - - -class LoaderPluginsModel(BaseSettingsModel): - LoadClip: LoadClipModel = SettingsField( - default_factory=LoadClipModel, - title="Load Clip" - ) - - -DEFAULT_LOADER_PLUGINS_SETTINGS = { - "LoadClip": { - "enabled": True, - "product_types": [ - "render2d", - "source", - "plate", - "render", - "review" - ], - "clip_name_template": "{folder[name]}_{product[name]}_{representation}" - } -} diff --git a/server_addon/hiero/server/settings/main.py b/server_addon/hiero/server/settings/main.py deleted file mode 100644 index 378af6a539..0000000000 --- a/server_addon/hiero/server/settings/main.py +++ /dev/null @@ -1,62 +0,0 @@ -from ayon_server.settings import BaseSettingsModel, SettingsField - -from .imageio import ( - ImageIOSettings, - DEFAULT_IMAGEIO_SETTINGS -) -from .create_plugins import ( - CreatorPluginsSettings, - DEFAULT_CREATE_SETTINGS -) -from .loader_plugins import ( - LoaderPluginsModel, - DEFAULT_LOADER_PLUGINS_SETTINGS -) -from .publish_plugins import ( - PublishPluginsModel, - DEFAULT_PUBLISH_PLUGIN_SETTINGS -) -from .scriptsmenu import ( - ScriptsmenuSettings, - DEFAULT_SCRIPTSMENU_SETTINGS -) -from .filters import PublishGUIFilterItemModel - - -class HieroSettings(BaseSettingsModel): - """Nuke addon settings.""" - - imageio: ImageIOSettings = SettingsField( - default_factory=ImageIOSettings, - title="Color Management (imageio)", - ) - - create: CreatorPluginsSettings = SettingsField( - default_factory=CreatorPluginsSettings, - title="Creator Plugins", - ) - load: LoaderPluginsModel = SettingsField( - default_factory=LoaderPluginsModel, - title="Loader plugins" - ) - publish: PublishPluginsModel = SettingsField( - default_factory=PublishPluginsModel, - title="Publish plugins" - ) - scriptsmenu: ScriptsmenuSettings = SettingsField( - default_factory=ScriptsmenuSettings, - title="Scripts Menu Definition", - ) - filters: list[PublishGUIFilterItemModel] = SettingsField( - default_factory=list - ) - - -DEFAULT_VALUES = { - "imageio": DEFAULT_IMAGEIO_SETTINGS, - "create": DEFAULT_CREATE_SETTINGS, - "load": DEFAULT_LOADER_PLUGINS_SETTINGS, - "publish": DEFAULT_PUBLISH_PLUGIN_SETTINGS, - "scriptsmenu": DEFAULT_SCRIPTSMENU_SETTINGS, - "filters": [], -} diff --git a/server_addon/hiero/server/settings/publish_plugins.py b/server_addon/hiero/server/settings/publish_plugins.py deleted file mode 100644 index 0e746d1cc1..0000000000 --- a/server_addon/hiero/server/settings/publish_plugins.py +++ /dev/null @@ -1,56 +0,0 @@ -from pydantic import validator -from ayon_server.settings import ( - BaseSettingsModel, - SettingsField, - ensure_unique_names, - normalize_name, -) - - -class CollectClipEffectsDefModel(BaseSettingsModel): - _layout = "expanded" - name: str = SettingsField("", title="Name") - effect_classes: list[str] = SettingsField( - default_factory=list, title="Effect Classes" - ) - - @validator("name") - def validate_name(cls, value): - """Ensure name does not contain weird characters""" - return normalize_name(value) - - -class CollectClipEffectsTracksModel(BaseSettingsModel): - _layout = "expanded" - name: str = SettingsField("", title="Name") - track_names: list[str] = SettingsField("", title="Track Names") - - -class CollectClipEffectsModel(BaseSettingsModel): - effect_categories: list[CollectClipEffectsDefModel] = SettingsField( - default_factory=list, title="Effect Categories" - ) - - effect_tracks: list[CollectClipEffectsTracksModel] = SettingsField( - default_factory=list, title="Effect Tracks" - ) - - @validator("effect_categories") - def validate_unique_outputs(cls, value): - ensure_unique_names(value) - return value - - -class PublishPluginsModel(BaseSettingsModel): - CollectClipEffects: CollectClipEffectsModel = SettingsField( - default_factory=CollectClipEffectsModel, - title="Collect Clip Effects" - ) - - -DEFAULT_PUBLISH_PLUGIN_SETTINGS = { - "CollectClipEffectsModel": { - "effect_categories": [], - "effect_tracks": [] - } -} diff --git a/server_addon/hiero/server/settings/scriptsmenu.py b/server_addon/hiero/server/settings/scriptsmenu.py deleted file mode 100644 index a627da9643..0000000000 --- a/server_addon/hiero/server/settings/scriptsmenu.py +++ /dev/null @@ -1,40 +0,0 @@ -from ayon_server.settings import BaseSettingsModel, SettingsField - - -class ScriptsmenuSubmodel(BaseSettingsModel): - """Item Definition""" - _isGroup = True - - type: str = SettingsField(title="Type") - command: str = SettingsField(title="Command") - sourcetype: str = SettingsField(title="Source Type") - title: str = SettingsField(title="Title") - tooltip: str = SettingsField(title="Tooltip") - - -class ScriptsmenuSettings(BaseSettingsModel): - """Nuke script menu project settings.""" - _isGroup = True - - """# TODO: enhance settings with host api: - - in api rename key `name` to `menu_name` - """ - name: str = SettingsField(title="Menu name") - definition: list[ScriptsmenuSubmodel] = SettingsField( - default_factory=list, - title="Definition", - description="Scriptmenu Items Definition") - - -DEFAULT_SCRIPTSMENU_SETTINGS = { - "name": "Custom Tools", - "definition": [ - { - "type": "action", - "sourcetype": "python", - "title": "Ayon Hiero Docs", - "command": "import webbrowser;webbrowser.open(url='https://ayon.ynput.io/docs/addon_hiero_artist')", # noqa - "tooltip": "Open the Ayon Hiero user doc page" - } - ] -} diff --git a/server_addon/jobqueue/client/ayon_jobqueue/__init__.py b/server_addon/jobqueue/client/ayon_jobqueue/__init__.py deleted file mode 100644 index 041782dd29..0000000000 --- a/server_addon/jobqueue/client/ayon_jobqueue/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -from .version import __version__ -from .addon import JobQueueAddon - - -__all__ = ( - "__version__", - - "JobQueueAddon", -) diff --git a/server_addon/jobqueue/client/ayon_jobqueue/addon.py b/server_addon/jobqueue/client/ayon_jobqueue/addon.py deleted file mode 100644 index ffd32feb89..0000000000 --- a/server_addon/jobqueue/client/ayon_jobqueue/addon.py +++ /dev/null @@ -1,234 +0,0 @@ -"""Job queue AYON addon was created for remote execution of commands. - -## Why is needed -Primarily created for hosts which are not easilly controlled from command line -or in headless mode and is easier to keep one process of host running listening -for jobs to do. - -### Example -One of examples is TVPaint which does not have headless mode, can run only one -process at one time and it's impossible to know what should be executed inside -TVPaint before we know all data about the file that should be processed. - -## Idea -Idea is that there is a server, workers and workstation/s which need to process -something on a worker. - -Workers and workstation/s must have access to server through adress to it's -running instance. Workers use WebSockets and workstations are using HTTP calls. -Also both of them must have access to job queue root which is set in -settings. Root is used as temp where files needed for job can be stored before -sending the job or where result files are stored when job is done. - -Server's address must be set in settings when is running so workers and -workstations know where to send or receive jobs. - -## Command line commands -### start_server -- start server which is handles jobs -- it is possible to specify port and host address (default is localhost:8079) - -### start_worker -- start worker which will process jobs -- has required possitional argument which is application name from AYON - settings e.g. 'tvpaint/11-5' ('tvpaint' is group '11-5' is variant) -- it is possible to specify server url but url from settings is used when not - passed (this is added mainly for developing purposes) -""" - -import json -import copy -import platform -from urllib.parse import urlsplit, urlunsplit - -import requests - -from ayon_core.addon import AYONAddon, click_wrap -from ayon_core.settings import get_studio_settings - -from .version import __version__ - - -class JobQueueAddon(AYONAddon): - name = "jobqueue" - version = __version__ - - def initialize(self, studio_settings): - addon_settings = studio_settings.get(self.name) or {} - server_url = addon_settings.get("server_url") or "" - - self._server_url = self.url_conversion(server_url) - jobs_root_mapping = self._roots_mapping_conversion( - addon_settings.get("jobs_root") - ) - - self._jobs_root_mapping = jobs_root_mapping - - @classmethod - def _root_conversion(cls, root_path): - """Make sure root path does not end with slash.""" - # Return empty string if path is invalid - if not root_path: - return "" - - # Remove all slashes - while root_path.endswith("/") or root_path.endswith("\\"): - root_path = root_path[:-1] - return root_path - - @classmethod - def _roots_mapping_conversion(cls, roots_mapping): - roots_mapping = roots_mapping or {} - for platform_name in ("windows", "linux", "darwin"): - roots_mapping[platform_name] = cls._root_conversion( - roots_mapping.get(platform_name) - ) - return roots_mapping - - @staticmethod - def url_conversion(url, ws=False): - if not url: - return url - - url_parts = list(urlsplit(url)) - scheme = url_parts[0] - if not scheme: - if ws: - url = "ws://{}".format(url) - else: - url = "http://{}".format(url) - url_parts = list(urlsplit(url)) - - elif ws: - if scheme not in ("ws", "wss"): - if scheme == "https": - url_parts[0] = "wss" - else: - url_parts[0] = "ws" - - elif scheme not in ("http", "https"): - if scheme == "wss": - url_parts[0] = "https" - else: - url_parts[0] = "http" - - return urlunsplit(url_parts) - - def get_jobs_root_mapping(self): - return copy.deepcopy(self._jobs_root_mapping) - - def get_jobs_root(self): - return self._jobs_root_mapping.get(platform.system().lower()) - - @classmethod - def get_jobs_root_from_settings(cls): - studio_settings = get_studio_settings() - jobs_root_mapping = studio_settings.get(cls.name, {}).get("jobs_root") - converted_mapping = cls._roots_mapping_conversion(jobs_root_mapping) - - return converted_mapping[platform.system().lower()] - - @property - def server_url(self): - return self._server_url - - def send_job(self, host_name, job_data): - job_data = job_data or {} - job_data["host_name"] = host_name - api_path = "{}/api/jobs".format(self._server_url) - post_request = requests.post(api_path, data=json.dumps(job_data)) - return str(post_request.content.decode()) - - def get_job_status(self, job_id): - api_path = "{}/api/jobs/{}".format(self._server_url, job_id) - return requests.get(api_path).json() - - def cli(self, click_group): - click_group.add_command(cli_main.to_click_obj()) - - @classmethod - def get_server_url_from_settings(cls): - studio_settings = get_studio_settings() - return cls.url_conversion( - studio_settings - .get(cls.name, {}) - .get("server_url") - ) - - @classmethod - def start_server(cls, port=None, host=None): - from .job_server import main - - return main(port, host) - - @classmethod - def start_worker(cls, app_name, server_url=None): - from ayon_applications import ApplicationManager - - if not server_url: - server_url = cls.get_server_url_from_settings() - - if not server_url: - raise ValueError("Server url is not set.") - - http_server_url = cls.url_conversion(server_url) - - # Validate url - requests.get(http_server_url) - - ws_server_url = cls.url_conversion(server_url) + "/ws" - - app_manager = ApplicationManager() - app = app_manager.applications.get(app_name) - if app is None: - raise ValueError( - "Didn't find application \"{}\" in settings.".format(app_name) - ) - - if app.host_name == "tvpaint": - return cls._start_tvpaint_worker(app, ws_server_url) - raise ValueError("Unknown host \"{}\"".format(app.host_name)) - - @classmethod - def _start_tvpaint_worker(cls, app, server_url): - from ayon_tvpaint.worker import main - - executable = app.find_executable() - if not executable: - raise ValueError(( - "Executable for app \"{}\" is not set" - " or accessible on this workstation." - ).format(app.full_name)) - - return main(str(executable), server_url) - - -@click_wrap.group( - JobQueueAddon.name, - help="Application job server. Can be used as render farm." -) -def cli_main(): - pass - - -@cli_main.command( - "start_server", - help="Start server handling workers and their jobs." -) -@click_wrap.option("--port", help="Server port") -@click_wrap.option("--host", help="Server host (ip address)") -def cli_start_server(port, host): - JobQueueAddon.start_server(port, host) - - -@cli_main.command( - "start_worker", help=( - "Start a worker for a specific application. (e.g. \"tvpaint/11.5\")" - ) -) -@click_wrap.argument("app_name") -@click_wrap.option( - "--server_url", - help="Server url which handle workers and jobs.") -def cli_start_worker(app_name, server_url): - JobQueueAddon.start_worker(app_name, server_url) diff --git a/server_addon/jobqueue/client/ayon_jobqueue/job_server/__init__.py b/server_addon/jobqueue/client/ayon_jobqueue/job_server/__init__.py deleted file mode 100644 index c73d830257..0000000000 --- a/server_addon/jobqueue/client/ayon_jobqueue/job_server/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -from .server import WebServerManager -from .utils import main - - -__all__ = ( - "WebServerManager", - "main" -) diff --git a/server_addon/jobqueue/client/ayon_jobqueue/job_server/job_queue_route.py b/server_addon/jobqueue/client/ayon_jobqueue/job_server/job_queue_route.py deleted file mode 100644 index 8929e64dc5..0000000000 --- a/server_addon/jobqueue/client/ayon_jobqueue/job_server/job_queue_route.py +++ /dev/null @@ -1,62 +0,0 @@ -import json - -from aiohttp.web_response import Response - - -class JobQueueResource: - def __init__(self, job_queue, server_manager): - self.server_manager = server_manager - - self._prefix = "/api" - - self._job_queue = job_queue - - self.endpoint_defs = ( - ("POST", "/jobs", self.post_job), - ("GET", "/jobs", self.get_jobs), - ("GET", "/jobs/{job_id}", self.get_job) - ) - - self.register() - - def register(self): - for methods, url, callback in self.endpoint_defs: - final_url = self._prefix + url - self.server_manager.add_route( - methods, final_url, callback - ) - - async def get_jobs(self, request): - jobs_data = [] - for job in self._job_queue.get_jobs(): - jobs_data.append(job.status()) - return Response(status=200, body=self.encode(jobs_data)) - - async def post_job(self, request): - data = await request.json() - host_name = data.get("host_name") - if not host_name: - return Response( - status=400, message="Key \"host_name\" not filled." - ) - - job = self._job_queue.create_job(host_name, data) - return Response(status=201, text=job.id) - - async def get_job(self, request): - job_id = request.match_info["job_id"] - content = self._job_queue.get_job_status(job_id) - if content is None: - content = {} - return Response( - status=200, - body=self.encode(content), - content_type="application/json" - ) - - @classmethod - def encode(cls, data): - return json.dumps( - data, - indent=4 - ).encode("utf-8") diff --git a/server_addon/jobqueue/client/ayon_jobqueue/job_server/jobs.py b/server_addon/jobqueue/client/ayon_jobqueue/job_server/jobs.py deleted file mode 100644 index 0fc3c381d4..0000000000 --- a/server_addon/jobqueue/client/ayon_jobqueue/job_server/jobs.py +++ /dev/null @@ -1,240 +0,0 @@ -import datetime -import collections -from uuid import uuid4 - - -class Job: - """Job related to specific host name. - - Data must contain everything needed to finish the job. - """ - # Remove done jobs each n days to clear memory - keep_in_memory_days = 3 - - def __init__(self, host_name, data, job_id=None, created_time=None): - if job_id is None: - job_id = str(uuid4()) - self._id = job_id - if created_time is None: - created_time = datetime.datetime.now() - self._created_time = created_time - self._started_time = None - self._done_time = None - self.host_name = host_name - self.data = data - self._result_data = None - - self._started = False - self._done = False - self._errored = False - self._message = None - self._deleted = False - - self._worker = None - - def keep_in_memory(self): - if self._done_time is None: - return True - - now = datetime.datetime.now() - delta = now - self._done_time - return delta.days < self.keep_in_memory_days - - @property - def id(self): - return self._id - - @property - def done(self): - return self._done - - def reset(self): - self._started = False - self._started_time = None - self._done = False - self._done_time = None - self._errored = False - self._message = None - - self._worker = None - - @property - def started(self): - return self._started - - @property - def deleted(self): - return self._deleted - - def set_deleted(self): - self._deleted = True - self.set_worker(None) - - def set_worker(self, worker): - if worker is self._worker: - return - - if self._worker is not None: - self._worker.set_current_job(None) - - self._worker = worker - if worker is not None: - worker.set_current_job(self) - - def set_started(self): - self._started_time = datetime.datetime.now() - self._started = True - - def set_done(self, success=True, message=None, data=None): - self._done = True - self._done_time = datetime.datetime.now() - self._errored = not success - self._message = message - self._result_data = data - if self._worker is not None: - self._worker.set_current_job(None) - - def status(self): - worker_id = None - if self._worker is not None: - worker_id = self._worker.id - output = { - "id": self.id, - "worker_id": worker_id, - "done": self._done - } - output["message"] = self._message or None - - state = "waiting" - if self._deleted: - state = "deleted" - elif self._errored: - state = "error" - elif self._done: - state = "done" - elif self._started: - state = "started" - - output["result"] = self._result_data - - output["state"] = state - - return output - - -class JobQueue: - """Queue holds jobs that should be done and workers that can do them. - - Also asign jobs to a worker. - """ - old_jobs_check_minutes_interval = 30 - - def __init__(self): - self._last_old_jobs_check = datetime.datetime.now() - self._jobs_by_id = {} - self._job_queue_by_host_name = collections.defaultdict( - collections.deque - ) - self._workers_by_id = {} - self._workers_by_host_name = collections.defaultdict(list) - - def workers(self): - """All currently registered workers.""" - return self._workers_by_id.values() - - def add_worker(self, worker): - host_name = worker.host_name - print("Added new worker for \"{}\"".format(host_name)) - self._workers_by_id[worker.id] = worker - self._workers_by_host_name[host_name].append(worker) - - def get_worker(self, worker_id): - return self._workers_by_id.get(worker_id) - - def remove_worker(self, worker): - # Look if worker had assigned job to do - job = worker.current_job - if job is not None and not job.done: - # Reset job - job.set_worker(None) - job.reset() - # Add job back to queue - self._job_queue_by_host_name[job.host_name].appendleft(job) - - # Remove worker from registered workers - self._workers_by_id.pop(worker.id, None) - host_name = worker.host_name - if worker in self._workers_by_host_name[host_name]: - self._workers_by_host_name[host_name].remove(worker) - - print("Removed worker for \"{}\"".format(host_name)) - - def assign_jobs(self): - """Try to assign job for each idle worker. - - Error all jobs without needed worker. - """ - available_host_names = set() - for worker in self._workers_by_id.values(): - host_name = worker.host_name - available_host_names.add(host_name) - if worker.is_idle(): - jobs = self._job_queue_by_host_name[host_name] - while jobs: - job = jobs.popleft() - if not job.deleted: - worker.set_current_job(job) - break - - for host_name in tuple(self._job_queue_by_host_name.keys()): - if host_name in available_host_names: - continue - - jobs_deque = self._job_queue_by_host_name[host_name] - message = ("Not available workers for \"{}\"").format(host_name) - while jobs_deque: - job = jobs_deque.popleft() - if not job.deleted: - job.set_done(False, message) - self._remove_old_jobs() - - def get_jobs(self): - return self._jobs_by_id.values() - - def get_job(self, job_id): - """Job by it's id.""" - return self._jobs_by_id.get(job_id) - - def create_job(self, host_name, job_data): - """Create new job from passed data and add it to queue.""" - job = Job(host_name, job_data) - self._jobs_by_id[job.id] = job - self._job_queue_by_host_name[host_name].append(job) - return job - - def _remove_old_jobs(self): - """Once in specific time look if should remove old finished jobs.""" - delta = datetime.datetime.now() - self._last_old_jobs_check - if delta.seconds < self.old_jobs_check_minutes_interval: - return - - for job_id in tuple(self._jobs_by_id.keys()): - job = self._jobs_by_id[job_id] - if not job.keep_in_memory(): - self._jobs_by_id.pop(job_id) - - def remove_job(self, job_id): - """Delete job and eventually stop it.""" - job = self._jobs_by_id.get(job_id) - if job is None: - return - - job.set_deleted() - self._jobs_by_id.pop(job.id) - - def get_job_status(self, job_id): - """Job's status based on id.""" - job = self._jobs_by_id.get(job_id) - if job is None: - return {} - return job.status() diff --git a/server_addon/jobqueue/client/ayon_jobqueue/job_server/server.py b/server_addon/jobqueue/client/ayon_jobqueue/job_server/server.py deleted file mode 100644 index cc0968b6b6..0000000000 --- a/server_addon/jobqueue/client/ayon_jobqueue/job_server/server.py +++ /dev/null @@ -1,154 +0,0 @@ -import threading -import asyncio -import logging - -from aiohttp import web - -from .jobs import JobQueue -from .job_queue_route import JobQueueResource -from .workers_rpc_route import WorkerRpc - -log = logging.getLogger(__name__) - - -class WebServerManager: - """Manger that care about web server thread.""" - def __init__(self, port, host, loop=None): - self.port = port - self.host = host - self.app = web.Application() - if loop is None: - loop = asyncio.new_event_loop() - - # add route with multiple methods for single "external app" - self.webserver_thread = WebServerThread(self, loop) - - @property - def url(self): - return "http://{}:{}".format(self.host, self.port) - - def add_route(self, *args, **kwargs): - self.app.router.add_route(*args, **kwargs) - - def add_static(self, *args, **kwargs): - self.app.router.add_static(*args, **kwargs) - - def start_server(self): - if self.webserver_thread and not self.webserver_thread.is_alive(): - self.webserver_thread.start() - - def stop_server(self): - if not self.is_running: - return - - try: - log.debug("Stopping Web server") - self.webserver_thread.stop() - - except Exception as exc: - print("Errored", str(exc)) - log.warning( - "Error has happened during Killing Web server", - exc_info=True - ) - - @property - def is_running(self): - if self.webserver_thread is not None: - return self.webserver_thread.is_running - return False - - -class WebServerThread(threading.Thread): - """ Listener for requests in thread.""" - def __init__(self, manager, loop): - super(WebServerThread, self).__init__() - - self._is_running = False - self._stopped = False - self.manager = manager - self.loop = loop - self.runner = None - self.site = None - - job_queue = JobQueue() - self.job_queue_route = JobQueueResource(job_queue, manager) - self.workers_route = WorkerRpc(job_queue, manager, loop=loop) - - @property - def port(self): - return self.manager.port - - @property - def host(self): - return self.manager.host - - @property - def stopped(self): - return self._stopped - - @property - def is_running(self): - return self._is_running - - def run(self): - self._is_running = True - - try: - log.info("Starting WebServer server") - asyncio.set_event_loop(self.loop) - self.loop.run_until_complete(self.start_server()) - - asyncio.ensure_future(self.check_shutdown(), loop=self.loop) - self.loop.run_forever() - - except Exception: - log.warning( - "Web Server service has failed", exc_info=True - ) - finally: - self.loop.close() - - self._is_running = False - log.info("Web server stopped") - - async def start_server(self): - """ Starts runner and TCPsite """ - self.runner = web.AppRunner(self.manager.app) - await self.runner.setup() - self.site = web.TCPSite(self.runner, self.host, self.port) - await self.site.start() - - def stop(self): - """Sets _stopped flag to True, 'check_shutdown' shuts server down""" - self._stopped = True - - async def check_shutdown(self): - """ Future that is running and checks if server should be running - periodically. - """ - while not self._stopped: - await asyncio.sleep(0.5) - - print("Starting shutdown") - if self.workers_route: - await self.workers_route.stop() - - print("Stopping site") - await self.site.stop() - print("Site stopped") - await self.runner.cleanup() - - print("Runner stopped") - tasks = [ - task - for task in asyncio.all_tasks() - if task is not asyncio.current_task() - ] - list(map(lambda task: task.cancel(), tasks)) # cancel all the tasks - results = await asyncio.gather(*tasks, return_exceptions=True) - log.debug(f'Finished awaiting cancelled tasks, results: {results}...') - await self.loop.shutdown_asyncgens() - # to really make sure everything else has time to stop - await asyncio.sleep(0.07) - self.loop.stop() diff --git a/server_addon/jobqueue/client/ayon_jobqueue/job_server/utils.py b/server_addon/jobqueue/client/ayon_jobqueue/job_server/utils.py deleted file mode 100644 index 127ca5f090..0000000000 --- a/server_addon/jobqueue/client/ayon_jobqueue/job_server/utils.py +++ /dev/null @@ -1,51 +0,0 @@ -import sys -import signal -import time -import socket - -from .server import WebServerManager - - -class SharedObjects: - stopped = False - - @classmethod - def stop(cls): - cls.stopped = True - - -def main(port=None, host=None): - def signal_handler(sig, frame): - print("Signal to kill process received. Termination starts.") - SharedObjects.stop() - - signal.signal(signal.SIGINT, signal_handler) - signal.signal(signal.SIGTERM, signal_handler) - - port = int(port or 8079) - host = str(host or "localhost") - - with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as con: - result_of_check = con.connect_ex((host, port)) - - if result_of_check == 0: - print(( - "Server {}:{} is already running or address is occupied." - ).format(host, port)) - return 1 - - print("Running server {}:{}".format(host, port)) - manager = WebServerManager(port, host) - manager.start_server() - - stopped = False - while manager.is_running: - if not stopped and SharedObjects.stopped: - stopped = True - manager.stop_server() - time.sleep(0.1) - return 0 - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/server_addon/jobqueue/client/ayon_jobqueue/job_server/workers.py b/server_addon/jobqueue/client/ayon_jobqueue/job_server/workers.py deleted file mode 100644 index 28ca649c03..0000000000 --- a/server_addon/jobqueue/client/ayon_jobqueue/job_server/workers.py +++ /dev/null @@ -1,122 +0,0 @@ -import asyncio -from uuid import uuid4 -from aiohttp import WSCloseCode -from aiohttp_json_rpc.protocol import encode_request - - -class WorkerState: - IDLE = object() - JOB_ASSIGNED = object() - JOB_SENT = object() - - -class Worker: - """Worker that can handle jobs of specific host.""" - def __init__(self, host_name, http_request): - self._id = None - self.host_name = host_name - self._http_request = http_request - self._state = WorkerState.IDLE - self._job = None - - # Give ability to send requests to worker - http_request.request_id = str(uuid4()) - http_request.pending_requests = {} - - async def send_job(self): - if self._job is not None: - data = { - "job_id": self._job.id, - "worker_id": self.id, - "data": self._job.data - } - return await self.call("start_job", data) - return False - - async def call(self, method, params=None, timeout=None): - """Call method on worker's side.""" - request_id = self._http_request.request_id - self._http_request.request_id = str(uuid4()) - pending_requests = self._http_request.pending_requests - pending_requests[request_id] = asyncio.Future() - - request = encode_request(method, id=request_id, params=params) - - await self._http_request.ws.send_str(request) - - if timeout: - await asyncio.wait_for( - pending_requests[request_id], - timeout=timeout - ) - - else: - await pending_requests[request_id] - - result = pending_requests[request_id].result() - del pending_requests[request_id] - - return result - - async def close(self): - return await self.ws.close( - code=WSCloseCode.GOING_AWAY, - message="Server shutdown" - ) - - @property - def id(self): - if self._id is None: - self._id = str(uuid4()) - return self._id - - @property - def state(self): - return self._state - - @property - def current_job(self): - return self._job - - @property - def http_request(self): - return self._http_request - - @property - def ws(self): - return self.http_request.ws - - def connection_is_alive(self): - if self.ws.closed or self.ws._writer.transport.is_closing(): - return False - return True - - def is_idle(self): - return self._state is WorkerState.IDLE - - def job_assigned(self): - return ( - self._state is WorkerState.JOB_ASSIGNED - or self._state is WorkerState.JOB_SENT - ) - - def is_working(self): - return self._state is WorkerState.JOB_SENT - - def set_current_job(self, job): - if job is self._job: - return - - self._job = job - if job is None: - self._set_idle() - else: - self._state = WorkerState.JOB_ASSIGNED - job.set_worker(self) - - def _set_idle(self): - self._job = None - self._state = WorkerState.IDLE - - def set_working(self): - self._state = WorkerState.JOB_SENT diff --git a/server_addon/jobqueue/client/ayon_jobqueue/job_server/workers_rpc_route.py b/server_addon/jobqueue/client/ayon_jobqueue/job_server/workers_rpc_route.py deleted file mode 100644 index e3c67fb3c3..0000000000 --- a/server_addon/jobqueue/client/ayon_jobqueue/job_server/workers_rpc_route.py +++ /dev/null @@ -1,124 +0,0 @@ -import asyncio - -import aiohttp -from aiohttp_json_rpc import JsonRpc -from aiohttp_json_rpc.protocol import ( - encode_error, decode_msg, JsonRpcMsgTyp -) -from aiohttp_json_rpc.exceptions import RpcError -from .workers import Worker - - -class WorkerRpc(JsonRpc): - def __init__(self, job_queue, manager, **kwargs): - super().__init__(**kwargs) - - self._job_queue = job_queue - self._manager = manager - - self._stopped = False - - # Register methods - self.add_methods( - ("", self.register_worker), - ("", self.job_done) - ) - asyncio.ensure_future(self._rpc_loop(), loop=self.loop) - - self._manager.add_route( - "*", "/ws", self.handle_request - ) - - # Panel routes for tools - async def register_worker(self, request, host_name): - worker = Worker(host_name, request.http_request) - self._job_queue.add_worker(worker) - return worker.id - - async def _rpc_loop(self): - while self.loop.is_running(): - if self._stopped: - break - - for worker in tuple(self._job_queue.workers()): - if not worker.connection_is_alive(): - self._job_queue.remove_worker(worker) - self._job_queue.assign_jobs() - - await self.send_jobs() - await asyncio.sleep(5) - - async def job_done(self, worker_id, job_id, success, message, data): - worker = self._job_queue.get_worker(worker_id) - if worker is not None: - worker.set_current_job(None) - - job = self._job_queue.get_job(job_id) - if job is not None: - job.set_done(success, message, data) - return True - - async def send_jobs(self): - invalid_workers = [] - for worker in self._job_queue.workers(): - if worker.job_assigned() and not worker.is_working(): - try: - await worker.send_job() - - except ConnectionResetError: - invalid_workers.append(worker) - - for worker in invalid_workers: - self._job_queue.remove_worker(worker) - - async def handle_websocket_request(self, http_request): - """Override this method to catch CLOSING messages.""" - http_request.msg_id = 0 - http_request.pending = {} - - # prepare and register websocket - ws = aiohttp.web_ws.WebSocketResponse() - await ws.prepare(http_request) - http_request.ws = ws - self.clients.append(http_request) - - while not ws.closed: - self.logger.debug('waiting for messages') - raw_msg = await ws.receive() - - if raw_msg.type == aiohttp.WSMsgType.TEXT: - self.logger.debug('raw msg received: %s', raw_msg.data) - self.loop.create_task( - self._handle_rpc_msg(http_request, raw_msg) - ) - - elif raw_msg.type == aiohttp.WSMsgType.CLOSING: - break - - self.clients.remove(http_request) - return ws - - async def _handle_rpc_msg(self, http_request, raw_msg): - # This is duplicated code from super but there is no way how to do it - # to be able handle server->client requests - try: - _raw_message = raw_msg.data - msg = decode_msg(_raw_message) - - except RpcError as error: - await self._ws_send_str(http_request, encode_error(error)) - return - - if msg.type in (JsonRpcMsgTyp.RESULT, JsonRpcMsgTyp.ERROR): - request_id = msg.data["id"] - if request_id in http_request.pending_requests: - future = http_request.pending_requests[request_id] - future.set_result(msg.data["result"]) - return - - return await super()._handle_rpc_msg(http_request, raw_msg) - - async def stop(self): - self._stopped = True - for worker in tuple(self._job_queue.workers()): - await worker.close() diff --git a/server_addon/jobqueue/client/ayon_jobqueue/job_workers/__init__.py b/server_addon/jobqueue/client/ayon_jobqueue/job_workers/__init__.py deleted file mode 100644 index f771797aea..0000000000 --- a/server_addon/jobqueue/client/ayon_jobqueue/job_workers/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -from .base_worker import WorkerJobsConnection - -__all__ = ( - "WorkerJobsConnection", -) diff --git a/server_addon/jobqueue/client/ayon_jobqueue/job_workers/base_worker.py b/server_addon/jobqueue/client/ayon_jobqueue/job_workers/base_worker.py deleted file mode 100644 index 85506565f4..0000000000 --- a/server_addon/jobqueue/client/ayon_jobqueue/job_workers/base_worker.py +++ /dev/null @@ -1,190 +0,0 @@ -import sys -import datetime -import asyncio -import traceback - -from aiohttp_json_rpc import JsonRpcClient - - -class WorkerClient(JsonRpcClient): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - - self.add_methods( - ("", self.start_job), - ) - self.current_job = None - self._id = None - - def set_id(self, worker_id): - self._id = worker_id - - async def start_job(self, job_data): - if self.current_job is not None: - return False - - print("Got new job {}".format(str(job_data))) - self.current_job = job_data - return True - - def finish_job(self, success, message, data): - asyncio.ensure_future( - self._finish_job(success, message, data), - loop=self._loop - ) - - async def _finish_job(self, success, message, data): - print("Current job", self.current_job) - job_id = self.current_job["job_id"] - self.current_job = None - - return await self.call( - "job_done", [self._id, job_id, success, message, data] - ) - - -class WorkerJobsConnection: - """WS connection to Job server. - - Helper class to create a connection to process jobs from job server. - - To be able receive jobs is needed to create a connection and then register - as worker for specific host. - """ - retry_time_seconds = 5 - - def __init__(self, server_url, host_name, loop=None): - self.client = None - self._loop = loop - - self._host_name = host_name - self._server_url = server_url - - self._is_running = False - self._connecting = False - self._connected = False - self._stopped = False - - def stop(self): - print("Stopping worker") - self._stopped = True - - @property - def is_running(self): - return self._is_running - - @property - def current_job(self): - if self.client is not None: - return self.client.current_job - return None - - def finish_job(self, success=True, message=None, data=None): - """Worker finished job and sets the result which is send to server.""" - if self.client is None: - print(( - "Couldn't sent job status to server because" - " client is not connected." - )) - else: - self.client.finish_job(success, message, data) - - async def main_loop(self, register_worker=True): - """Main loop of connection which keep connection to server alive.""" - self._is_running = True - - while not self._stopped: - start_time = datetime.datetime.now() - await self._connection_loop(register_worker) - delta = datetime.datetime.now() - start_time - print("Connection loop took {}s".format(str(delta))) - # Check if was stopped and stop while loop in that case - if self._stopped: - break - - if delta.seconds < 60: - print(( - "Can't connect to server will try in {} seconds." - ).format(self.retry_time_seconds)) - - await asyncio.sleep(self.retry_time_seconds) - self._is_running = False - - async def _connect(self): - self.client = WorkerClient() - print("Connecting to {}".format(self._server_url)) - try: - await self.client.connect_url(self._server_url) - except KeyboardInterrupt: - raise - except Exception: - traceback.print_exception(*sys.exc_info()) - - async def _connection_loop(self, register_worker): - self._connecting = True - future = asyncio.run_coroutine_threadsafe( - self._connect(), loop=self._loop - ) - - while self._connecting: - if not future.done(): - await asyncio.sleep(0.07) - continue - - session = getattr(self.client, "_session", None) - ws = getattr(self.client, "_ws", None) - if session is not None: - if session.closed: - self._connecting = False - self._connected = False - break - - elif ws is not None: - self._connecting = False - self._connected = True - - if self._stopped: - break - - await asyncio.sleep(0.07) - - if not self._connected: - self.client = None - return - - print("Connected to job queue server") - if register_worker: - self.register_as_worker() - - while self._connected and self._loop.is_running(): - if self._stopped or ws.closed: - break - - await asyncio.sleep(0.3) - - await self._stop_cleanup() - - def register_as_worker(self): - """Register as worker ready to work on server side.""" - asyncio.ensure_future(self._register_as_worker(), loop=self._loop) - - async def _register_as_worker(self): - worker_id = await self.client.call( - "register_worker", [self._host_name] - ) - self.client.set_id(worker_id) - print( - "Registered as worker with id {}".format(worker_id) - ) - - async def disconnect(self): - await self._stop_cleanup() - - async def _stop_cleanup(self): - print("Cleanup after stop") - if self.client is not None and hasattr(self.client, "_ws"): - await self.client.disconnect() - - self.client = None - self._connecting = False - self._connected = False diff --git a/server_addon/jobqueue/client/ayon_jobqueue/version.py b/server_addon/jobqueue/client/ayon_jobqueue/version.py deleted file mode 100644 index b29847c090..0000000000 --- a/server_addon/jobqueue/client/ayon_jobqueue/version.py +++ /dev/null @@ -1,3 +0,0 @@ -# -*- coding: utf-8 -*- -"""Package declaring AYON addon 'jobqueue' version.""" -__version__ = "1.1.0" diff --git a/server_addon/jobqueue/client/pyproject.toml b/server_addon/jobqueue/client/pyproject.toml deleted file mode 100644 index f15d4baa92..0000000000 --- a/server_addon/jobqueue/client/pyproject.toml +++ /dev/null @@ -1,6 +0,0 @@ -[project] -name="jobqueue" -description="AYON JobQueue addon." - -[ayon.runtimeDependencies] -aiohttp_json_rpc = "*" diff --git a/server_addon/jobqueue/package.py b/server_addon/jobqueue/package.py deleted file mode 100644 index 75a7572c4e..0000000000 --- a/server_addon/jobqueue/package.py +++ /dev/null @@ -1,11 +0,0 @@ -name = "jobqueue" -title = "JobQueue" -version = "1.1.0" -client_dir = "ayon_jobqueue" - -ayon_required_addons = { - "core": ">0.3.2", -} -ayon_compatible_addons = { - "tvpaint": ">=0.2.0", -} diff --git a/server_addon/jobqueue/server/__init__.py b/server_addon/jobqueue/server/__init__.py deleted file mode 100644 index 9ec74fce53..0000000000 --- a/server_addon/jobqueue/server/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -from ayon_server.addons import BaseServerAddon - - -class JobQueueAddon(BaseServerAddon): - pass diff --git a/server_addon/nuke/client/ayon_nuke/__init__.py b/server_addon/nuke/client/ayon_nuke/__init__.py deleted file mode 100644 index 29ea039739..0000000000 --- a/server_addon/nuke/client/ayon_nuke/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -from .version import __version__ -from .addon import ( - NUKE_ROOT_DIR, - NukeAddon, -) - - -__all__ = ( - "__version__", - - "NUKE_ROOT_DIR", - "NukeAddon", -) diff --git a/server_addon/nuke/client/ayon_nuke/addon.py b/server_addon/nuke/client/ayon_nuke/addon.py deleted file mode 100644 index ccb7379c0f..0000000000 --- a/server_addon/nuke/client/ayon_nuke/addon.py +++ /dev/null @@ -1,74 +0,0 @@ -import os -import platform -from ayon_core.addon import AYONAddon, IHostAddon - -from .version import __version__ - -NUKE_ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) - - -class NukeAddon(AYONAddon, IHostAddon): - name = "nuke" - version = __version__ - host_name = "nuke" - - def add_implementation_envs(self, env, _app): - # Add requirements to NUKE_PATH - new_nuke_paths = [ - os.path.join(NUKE_ROOT_DIR, "startup") - ] - old_nuke_path = env.get("NUKE_PATH") or "" - for path in old_nuke_path.split(os.pathsep): - if not path: - continue - - norm_path = os.path.normpath(path) - if norm_path not in new_nuke_paths: - new_nuke_paths.append(norm_path) - - env["NUKE_PATH"] = os.pathsep.join(new_nuke_paths) - # Remove auto screen scale factor for Qt - # - let Nuke decide it's value - env.pop("QT_AUTO_SCREEN_SCALE_FACTOR", None) - # Remove tkinter library paths if are set - env.pop("TK_LIBRARY", None) - env.pop("TCL_LIBRARY", None) - - # Add vendor to PYTHONPATH - python_path = env["PYTHONPATH"] - python_path_parts = [] - if python_path: - python_path_parts = python_path.split(os.pathsep) - vendor_path = os.path.join(NUKE_ROOT_DIR, "vendor") - python_path_parts.insert(0, vendor_path) - env["PYTHONPATH"] = os.pathsep.join(python_path_parts) - - # Set default values if are not already set via settings - defaults = { - "LOGLEVEL": "DEBUG" - } - for key, value in defaults.items(): - if not env.get(key): - env[key] = value - - # Try to add QuickTime to PATH - quick_time_path = "C:/Program Files (x86)/QuickTime/QTSystem" - if platform.system() == "windows" and os.path.exists(quick_time_path): - path_value = env.get("PATH") or "" - path_paths = [ - path - for path in path_value.split(os.pathsep) - if path - ] - path_paths.append(quick_time_path) - env["PATH"] = os.pathsep.join(path_paths) - - def get_launch_hook_paths(self, app): - if app.host_name != self.host_name: - return [] - return [ - os.path.join(NUKE_ROOT_DIR, "hooks") - ] - - def get_workfile_extensions(self): - return [".nk"] diff --git a/server_addon/nuke/client/ayon_nuke/api/__init__.py b/server_addon/nuke/client/ayon_nuke/api/__init__.py deleted file mode 100644 index caefba766f..0000000000 --- a/server_addon/nuke/client/ayon_nuke/api/__init__.py +++ /dev/null @@ -1,104 +0,0 @@ -from .workio import ( - file_extensions, - has_unsaved_changes, - save_file, - open_file, - current_file, - work_root, -) -from .command import ( - viewer_update_and_undo_stop -) -from .plugin import ( - NukeCreator, - NukeWriteCreator, - NukeCreatorError, - get_instance_group_node_childs, - get_colorspace_from_node -) -from .pipeline import ( - NukeHost, - - ls, - - list_instances, - remove_instance, - select_instance, - - containerise, - parse_container, - update_container, - -) -from .lib import ( - INSTANCE_DATA_KNOB, - ROOT_DATA_KNOB, - maintained_selection, - reset_selection, - select_nodes, - get_view_process_node, - duplicate_node, - convert_knob_value_to_correct_type, - get_node_data, - set_node_data, - update_node_data, - create_write_node, - link_knobs -) -from .utils import ( - colorspace_exists_on_node, - get_colorspace_list -) - -from .actions import ( - SelectInvalidAction, - SelectInstanceNodeAction -) - -__all__ = ( - "file_extensions", - "has_unsaved_changes", - "save_file", - "open_file", - "current_file", - "work_root", - - "viewer_update_and_undo_stop", - - "NukeCreator", - "NukeWriteCreator", - "NukeCreatorError", - "NukeHost", - "get_instance_group_node_childs", - "get_colorspace_from_node", - - "ls", - - "list_instances", - "remove_instance", - "select_instance", - - "containerise", - "parse_container", - "update_container", - - "INSTANCE_DATA_KNOB", - "ROOT_DATA_KNOB", - "maintained_selection", - "reset_selection", - "select_nodes", - "get_view_process_node", - "duplicate_node", - "convert_knob_value_to_correct_type", - "get_node_data", - "set_node_data", - "update_node_data", - "create_write_node", - "link_knobs", - - "colorspace_exists_on_node", - "get_colorspace_list", - - "SelectInvalidAction", - "SelectInstanceNodeAction" -) diff --git a/server_addon/nuke/client/ayon_nuke/api/actions.py b/server_addon/nuke/client/ayon_nuke/api/actions.py deleted file mode 100644 index a7bcb5b44f..0000000000 --- a/server_addon/nuke/client/ayon_nuke/api/actions.py +++ /dev/null @@ -1,77 +0,0 @@ -import pyblish.api - -from ayon_core.pipeline.publish import get_errored_instances_from_context -from .lib import ( - reset_selection, - select_nodes -) - - -class SelectInvalidAction(pyblish.api.Action): - """Select invalid nodes in Nuke when plug-in failed. - - To retrieve the invalid nodes this assumes a static `get_invalid()` - method is available on the plugin. - - """ - label = "Select invalid nodes" - on = "failed" # This action is only available on a failed plug-in - icon = "search" # Icon from Awesome Icon - - def process(self, context, plugin): - - errored_instances = get_errored_instances_from_context(context, - plugin=plugin) - - # Get the invalid nodes for the plug-ins - self.log.info("Finding invalid nodes..") - invalid = set() - for instance in errored_instances: - invalid_nodes = plugin.get_invalid(instance) - - if invalid_nodes: - if isinstance(invalid_nodes, (list, tuple)): - invalid.update(invalid_nodes) - else: - self.log.warning("Plug-in returned to be invalid, " - "but has no selectable nodes.") - - if invalid: - self.log.info("Selecting invalid nodes: {}".format(invalid)) - reset_selection() - select_nodes(invalid) - else: - self.log.info("No invalid nodes found.") - - -class SelectInstanceNodeAction(pyblish.api.Action): - """Select instance node for failed plugin.""" - label = "Select instance node" - on = "failed" # This action is only available on a failed plug-in - icon = "mdi.cursor-default-click" - - def process(self, context, plugin): - - # Get the errored instances for the plug-in - errored_instances = get_errored_instances_from_context( - context, plugin) - - # Get the invalid nodes for the plug-ins - self.log.info("Finding instance nodes..") - nodes = set() - for instance in errored_instances: - instance_node = instance.data.get("transientData", {}).get("node") - if not instance_node: - raise RuntimeError( - "No transientData['node'] found on instance: {}".format( - instance - ) - ) - nodes.add(instance_node) - - if nodes: - self.log.info("Selecting instance nodes: {}".format(nodes)) - reset_selection() - select_nodes(nodes) - else: - self.log.info("No instance nodes found.") diff --git a/server_addon/nuke/client/ayon_nuke/api/command.py b/server_addon/nuke/client/ayon_nuke/api/command.py deleted file mode 100644 index 2f772469d8..0000000000 --- a/server_addon/nuke/client/ayon_nuke/api/command.py +++ /dev/null @@ -1,21 +0,0 @@ -import logging -import contextlib -import nuke - -log = logging.getLogger(__name__) - - -@contextlib.contextmanager -def viewer_update_and_undo_stop(): - """Lock viewer from updating and stop recording undo steps""" - try: - # stop active viewer to update any change - viewer = nuke.activeViewer() - if viewer: - viewer.stop() - else: - log.warning("No available active Viewer") - nuke.Undo.disable() - yield - finally: - nuke.Undo.enable() diff --git a/server_addon/nuke/client/ayon_nuke/api/constants.py b/server_addon/nuke/client/ayon_nuke/api/constants.py deleted file mode 100644 index 110199720f..0000000000 --- a/server_addon/nuke/client/ayon_nuke/api/constants.py +++ /dev/null @@ -1,4 +0,0 @@ -import os - - -ASSIST = bool(os.getenv("NUKEASSIST")) diff --git a/server_addon/nuke/client/ayon_nuke/api/gizmo_menu.py b/server_addon/nuke/client/ayon_nuke/api/gizmo_menu.py deleted file mode 100644 index 435e4a5806..0000000000 --- a/server_addon/nuke/client/ayon_nuke/api/gizmo_menu.py +++ /dev/null @@ -1,92 +0,0 @@ -import os -import re -import nuke - -from ayon_core.lib import Logger - -log = Logger.get_logger(__name__) - - -class GizmoMenu(): - def __init__(self, title, icon=None): - - self.toolbar = self._create_toolbar_menu( - title, - icon=icon - ) - - self._script_actions = [] - - def _create_toolbar_menu(self, name, icon=None): - nuke_node_menu = nuke.menu("Nodes") - return nuke_node_menu.addMenu( - name, - icon=icon - ) - - def _make_menu_path(self, path, icon=None): - parent = self.toolbar - for folder in re.split(r"/|\\", path): - if not folder: - continue - existing_menu = parent.findItem(folder) - if existing_menu: - parent = existing_menu - else: - parent = parent.addMenu(folder, icon=icon) - - return parent - - def build_from_configuration(self, configuration): - for menu in configuration: - # Construct parent path else parent is toolbar - parent = self.toolbar - gizmo_toolbar_path = menu.get("gizmo_toolbar_path") - if gizmo_toolbar_path: - parent = self._make_menu_path(gizmo_toolbar_path) - - for item in menu["sub_gizmo_list"]: - assert isinstance(item, dict), "Configuration is wrong!" - - if not item.get("title"): - continue - - item_type = item.get("sourcetype") - - if item_type == "python": - parent.addCommand( - item["title"], - command=str(item["command"]), - icon=item.get("icon"), - shortcut=item.get("shortcut") - ) - elif item_type == "file": - parent.addCommand( - item['title'], - "nuke.createNode('{}')".format(item.get('file_name')), - shortcut=item.get('shortcut') - ) - - # add separator - # Special behavior for separators - elif item_type == "separator": - parent.addSeparator() - - # add submenu - # items should hold a collection of submenu items (dict) - elif item_type == "menu": - # assert "items" in item, "Menu is missing 'items' key" - parent.addMenu( - item['title'], - icon=item.get('icon') - ) - - def add_gizmo_path(self, gizmo_paths): - for gizmo_path in gizmo_paths: - if os.path.isdir(gizmo_path): - for folder in os.listdir(gizmo_path): - if os.path.isdir(os.path.join(gizmo_path, folder)): - nuke.pluginAddPath(os.path.join(gizmo_path, folder)) - nuke.pluginAddPath(gizmo_path) - else: - log.warning("This path doesn't exist: {}".format(gizmo_path)) diff --git a/server_addon/nuke/client/ayon_nuke/api/lib.py b/server_addon/nuke/client/ayon_nuke/api/lib.py deleted file mode 100644 index 6caaed3801..0000000000 --- a/server_addon/nuke/client/ayon_nuke/api/lib.py +++ /dev/null @@ -1,2967 +0,0 @@ -import os -import re -import json -import six -import functools -import warnings -import platform -import tempfile -import contextlib -from collections import OrderedDict - -import nuke -from qtpy import QtCore, QtWidgets -import ayon_api - -from ayon_core.host import HostDirmap -from ayon_core.tools.utils import host_tools -from ayon_core.pipeline.workfile.workfile_template_builder import ( - TemplateProfileNotFound -) -from ayon_core.lib import ( - env_value_to_bool, - Logger, - get_version_from_path, - StringTemplate, -) - -from ayon_core.settings import ( - get_project_settings, - get_current_project_settings, -) -from ayon_core.addon import AddonsManager -from ayon_core.pipeline.template_data import get_template_data_with_names -from ayon_core.pipeline import ( - Anatomy, - get_current_host_name, - get_current_project_name, - get_current_folder_path, - get_current_task_name, - AYON_INSTANCE_ID, - AVALON_INSTANCE_ID, -) -from ayon_core.pipeline.context_tools import ( - get_current_context_custom_workfile_template -) -from ayon_core.pipeline.colorspace import ( - get_current_context_imageio_config_preset -) -from ayon_core.pipeline.workfile import BuildWorkfile -from . import gizmo_menu -from .constants import ASSIST - -from .workio import save_file -from .utils import get_node_outputs - -log = Logger.get_logger(__name__) - -MENU_LABEL = os.getenv("AYON_MENU_LABEL") or "AYON" -NODE_TAB_NAME = MENU_LABEL -DATA_GROUP_KEY = "{}DataGroup".format(MENU_LABEL.capitalize()) -EXCLUDED_KNOB_TYPE_ON_READ = ( - 20, # Tab Knob - 26, # Text Knob (But for backward compatibility, still be read - # if value is not an empty string.) -) -JSON_PREFIX = "JSON:::" -ROOT_DATA_KNOB = "publish_context" -INSTANCE_DATA_KNOB = "publish_instance" - - -class DeprecatedWarning(DeprecationWarning): - pass - - -def deprecated(new_destination): - """Mark functions as deprecated. - - It will result in a warning being emitted when the function is used. - """ - - func = None - if callable(new_destination): - func = new_destination - new_destination = None - - def _decorator(decorated_func): - if new_destination is None: - warning_message = ( - " Please check content of deprecated function to figure out" - " possible replacement." - ) - else: - warning_message = " Please replace your usage with '{}'.".format( - new_destination - ) - - @functools.wraps(decorated_func) - def wrapper(*args, **kwargs): - warnings.simplefilter("always", DeprecatedWarning) - warnings.warn( - ( - "Call to deprecated function '{}'" - "\nFunction was moved or removed.{}" - ).format(decorated_func.__name__, warning_message), - category=DeprecatedWarning, - stacklevel=4 - ) - return decorated_func(*args, **kwargs) - return wrapper - - if func is None: - return _decorator - return _decorator(func) - - -class Context: - main_window = None - context_action_item = None - project_name = os.getenv("AYON_PROJECT_NAME") - # Workfile related code - workfiles_launched = False - workfiles_tool_timer = None - - # Seems unused - _project_entity = None - - -def get_main_window(): - """Acquire Nuke's main window""" - if Context.main_window is None: - - top_widgets = QtWidgets.QApplication.topLevelWidgets() - name = "Foundry::UI::DockMainWindow" - for widget in top_widgets: - if ( - widget.inherits("QMainWindow") - and widget.metaObject().className() == name - ): - Context.main_window = widget - break - return Context.main_window - - -def set_node_data(node, knobname, data): - """Write data to node invisible knob - - Will create new in case it doesn't exists - or update the one already created. - - Args: - node (nuke.Node): node object - knobname (str): knob name - data (dict): data to be stored in knob - """ - # if exists then update data - if knobname in node.knobs(): - update_node_data(node, knobname, data) - return - - # else create new - knob_value = JSON_PREFIX + json.dumps(data) - knob = nuke.String_Knob(knobname) - knob.setValue(knob_value) - knob.setFlag(nuke.INVISIBLE) - node.addKnob(knob) - - -def get_node_data(node, knobname): - """Read data from node. - - Args: - node (nuke.Node): node object - knobname (str): knob name - - Returns: - dict: data stored in knob - """ - if knobname not in node.knobs(): - return - - rawdata = node[knobname].getValue() - if ( - isinstance(rawdata, six.string_types) - and rawdata.startswith(JSON_PREFIX) - ): - try: - return json.loads(rawdata[len(JSON_PREFIX):]) - except json.JSONDecodeError: - return - - -def update_node_data(node, knobname, data): - """Update already present data. - - Args: - node (nuke.Node): node object - knobname (str): knob name - data (dict): data to update knob value - """ - knob = node[knobname] - node_data = get_node_data(node, knobname) or {} - node_data.update(data) - knob_value = JSON_PREFIX + json.dumps(node_data) - knob.setValue(knob_value) - - -class Knobby(object): - """[DEPRECATED] For creating knob which it's type isn't - mapped in `create_knobs` - - Args: - type (string): Nuke knob type name - value: Value to be set with `Knob.setValue`, put `None` if not required - flags (list, optional): Knob flags to be set with `Knob.setFlag` - *args: Args other than knob name for initializing knob class - - """ - - def __init__(self, type, value, flags=None, *args): - self.type = type - self.value = value - self.flags = flags or [] - self.args = args - - def create(self, name, nice=None): - knob_cls = getattr(nuke, self.type) - knob = knob_cls(name, nice, *self.args) - if self.value is not None: - knob.setValue(self.value) - for flag in self.flags: - knob.setFlag(flag) - return knob - - @staticmethod - def nice_naming(key): - """Convert camelCase name into UI Display Name""" - words = re.findall('[A-Z][^A-Z]*', key[0].upper() + key[1:]) - return " ".join(words) - - -def create_knobs(data, tab=None): - """Create knobs by data - - Depending on the type of each dict value and creates the correct Knob. - - Mapped types: - bool: nuke.Boolean_Knob - int: nuke.Int_Knob - float: nuke.Double_Knob - list: nuke.Enumeration_Knob - six.string_types: nuke.String_Knob - - dict: If it's a nested dict (all values are dict), will turn into - A tabs group. Or just a knobs group. - - Args: - data (dict): collection of attributes and their value - tab (string, optional): Knobs' tab name - - Returns: - list: A list of `nuke.Knob` objects - - """ - def nice_naming(key): - """Convert camelCase name into UI Display Name""" - words = re.findall('[A-Z][^A-Z]*', key[0].upper() + key[1:]) - return " ".join(words) - - # Turn key-value pairs into knobs - knobs = list() - - if tab: - knobs.append(nuke.Tab_Knob(tab)) - - for key, value in data.items(): - # Knob name - if isinstance(key, tuple): - name, nice = key - else: - name, nice = key, nice_naming(key) - - # Create knob by value type - if isinstance(value, Knobby): - knobby = value - knob = knobby.create(name, nice) - - elif isinstance(value, float): - knob = nuke.Double_Knob(name, nice) - knob.setValue(value) - - elif isinstance(value, bool): - knob = nuke.Boolean_Knob(name, nice) - knob.setValue(value) - knob.setFlag(nuke.STARTLINE) - - elif isinstance(value, int): - knob = nuke.Int_Knob(name, nice) - knob.setValue(value) - - elif isinstance(value, six.string_types): - knob = nuke.String_Knob(name, nice) - knob.setValue(value) - - elif isinstance(value, list): - knob = nuke.Enumeration_Knob(name, nice, value) - - elif isinstance(value, dict): - if all(isinstance(v, dict) for v in value.values()): - # Create a group of tabs - begain = nuke.BeginTabGroup_Knob() - end = nuke.EndTabGroup_Knob() - begain.setName(name) - end.setName(name + "_End") - knobs.append(begain) - for k, v in value.items(): - knobs += create_knobs(v, tab=k) - knobs.append(end) - else: - # Create a group of knobs - knobs.append(nuke.Tab_Knob( - name, nice, nuke.TABBEGINCLOSEDGROUP)) - knobs += create_knobs(value) - knobs.append( - nuke.Tab_Knob(name + "_End", nice, nuke.TABENDGROUP)) - continue - - else: - raise TypeError("Unsupported type: %r" % type(value)) - - knobs.append(knob) - - return knobs - - -def imprint(node, data, tab=None): - """Store attributes with value on node - - Parse user data into Node knobs. - Use `collections.OrderedDict` to ensure knob order. - - Args: - node(nuke.Node): node object from Nuke - data(dict): collection of attributes and their value - - Returns: - None - - Examples: - ``` - import nuke - from ayon_nuke.api import lib - - node = nuke.createNode("NoOp") - data = { - # Regular type of attributes - "myList": ["x", "y", "z"], - "myBool": True, - "myFloat": 0.1, - "myInt": 5, - - # Creating non-default imprint type of knob - "MyFilePath": lib.Knobby("File_Knob", "/file/path"), - "divider": lib.Knobby("Text_Knob", ""), - - # Manual nice knob naming - ("my_knob", "Nice Knob Name"): "some text", - - # dict type will be created as knob group - "KnobGroup": { - "knob1": 5, - "knob2": "hello", - "knob3": ["a", "b"], - }, - - # Nested dict will be created as tab group - "TabGroup": { - "tab1": {"count": 5}, - "tab2": {"isGood": True}, - "tab3": {"direction": ["Left", "Right"]}, - }, - } - lib.imprint(node, data, tab="Demo") - - ``` - - """ - for knob in create_knobs(data, tab): - # If knob name exists we set the value. Technically there could be - # multiple knobs with the same name, but the intent is not to have - # duplicated knobs so we do not account for that. - if knob.name() in node.knobs().keys(): - node[knob.name()].setValue(knob.value()) - else: - node.addKnob(knob) - - -@deprecated -def add_publish_knob(node): - """[DEPRECATED] Add Publish knob to node - - Arguments: - node (nuke.Node): nuke node to be processed - - Returns: - node (nuke.Node): processed nuke node - - """ - if "publish" not in node.knobs(): - body = OrderedDict() - body[("divd", "Publishing")] = Knobby("Text_Knob", '') - body["publish"] = True - imprint(node, body) - return node - - -@deprecated("ayon_nuke.api.lib.set_node_data") -def set_avalon_knob_data(node, data=None, prefix="avalon:"): - """[DEPRECATED] Sets data into nodes's avalon knob - - This function is still used but soon will be deprecated. - Use `set_node_data` instead. - - Arguments: - node (nuke.Node): Nuke node to imprint with data, - data (dict, optional): Data to be imprinted into AvalonTab - prefix (str, optional): filtering prefix - - Returns: - node (nuke.Node) - - Examples: - data = { - 'folderPath': 'sq020sh0280', - 'productType': 'render', - 'productName': 'productMain' - } - """ - data = data or dict() - create = OrderedDict() - - tab_name = NODE_TAB_NAME - editable = ["folderPath", "productName", "name", "namespace"] - - existed_knobs = node.knobs() - - for key, value in data.items(): - knob_name = prefix + key - gui_name = key - - if knob_name in existed_knobs: - # Set value - try: - node[knob_name].setValue(value) - except TypeError: - node[knob_name].setValue(str(value)) - else: - # New knob - name = (knob_name, gui_name) # Hide prefix on GUI - if key in editable: - create[name] = value - else: - create[name] = Knobby("String_Knob", - str(value), - flags=[nuke.READ_ONLY]) - if tab_name in existed_knobs: - tab_name = None - else: - tab = OrderedDict() - warn = Knobby("Text_Knob", "Warning! Do not change following data!") - divd = Knobby("Text_Knob", "") - head = [ - (("warn", ""), warn), - (("divd", ""), divd), - ] - tab[DATA_GROUP_KEY] = OrderedDict(head + list(create.items())) - create = tab - - imprint(node, create, tab=tab_name) - return node - - -@deprecated("ayon_nuke.api.lib.get_node_data") -def get_avalon_knob_data(node, prefix="avalon:", create=True): - """[DEPRECATED] Gets a data from nodes's avalon knob - - This function is still used but soon will be deprecated. - Use `get_node_data` instead. - - Arguments: - node (obj): Nuke node to search for data, - prefix (str, optional): filtering prefix - - Returns: - data (dict) - """ - - data = {} - if NODE_TAB_NAME not in node.knobs(): - return data - - # check if lists - if not isinstance(prefix, list): - prefix = [prefix] - - # loop prefix - for p in prefix: - # check if the node is avalon tracked - try: - # check if data available on the node - _ = node[DATA_GROUP_KEY].value() - except NameError: - # if it doesn't then create it - if create: - node = set_avalon_knob_data(node) - return get_avalon_knob_data(node) - return {} - - # get data from filtered knobs - data.update({k.replace(p, ''): node[k].value() - for k in node.knobs().keys() - if p in k}) - - return data - - -def add_write_node(name, file_path, knobs, **kwarg): - """Adding nuke write node - - Arguments: - name (str): nuke node name - kwarg (attrs): data for nuke knobs - - Returns: - node (obj): nuke write node - """ - use_range_limit = kwarg.get("use_range_limit", None) - - w = nuke.createNode( - "Write", - "name {}".format(name), - inpanel=False - ) - - w["file"].setValue(file_path) - - # finally add knob overrides - set_node_knobs_from_settings(w, knobs, **kwarg) - - if use_range_limit: - w["use_limit"].setValue(True) - w["first"].setValue(kwarg["frame_range"][0]) - w["last"].setValue(kwarg["frame_range"][1]) - - return w - - -def read_avalon_data(node): - """Return user-defined knobs from given `node` - - Args: - node (nuke.Node): Nuke node object - - Returns: - Dict[str, nuke.Knob]: A dictionary of knob name to nuke.Knob objects - - """ - def compat_prefixed(knob_name): - if knob_name.startswith("avalon:"): - return knob_name[len("avalon:"):] - elif knob_name.startswith("ak:"): - return knob_name[len("ak:"):] - - data = dict() - - pattern = ("(?<=addUserKnob {)" - "([0-9]*) (\\S*)" # Matching knob type and knob name - "(?=[ |}])") - tcl_script = node.writeKnobs(nuke.WRITE_USER_KNOB_DEFS) - result = re.search(pattern, tcl_script) - - if result: - first_user_knob = result.group(2) - # Collect user knobs from the end of the knob list - for knob in reversed(node.allKnobs()): - knob_name = knob.name() - if not knob_name: - # Ignore unnamed knob - continue - - knob_type = nuke.knob(knob.fullyQualifiedName(), type=True) - value = knob.value() - - if ( - knob_type not in EXCLUDED_KNOB_TYPE_ON_READ or - # For compating read-only string data that imprinted - # by `nuke.Text_Knob`. - (knob_type == 26 and value) - ): - key = compat_prefixed(knob_name) - if key is not None: - data[key] = value - - if knob_name == first_user_knob: - break - - return data - - -def get_node_path(path, padding=4): - """Get filename for the Nuke write with padded number as '#' - - Arguments: - path (str): The path to render to. - - Returns: - Tuple[str, int, str]: head, padding, tail (extension) - - Examples: - >>> get_frame_path("test.exr") - ('test', 4, '.exr') - - >>> get_frame_path("filename.#####.tif") - ('filename.', 5, '.tif') - - >>> get_frame_path("foobar##.tif") - ('foobar', 2, '.tif') - - >>> get_frame_path("foobar_%08d.tif") - ('foobar_', 8, '.tif') - """ - filename, ext = os.path.splitext(path) - - # Find a final number group - if '%' in filename: - match = re.match('.*?(%[0-9]+d)$', filename) - if match: - padding = int(match.group(1).replace('%', '').replace('d', '')) - # remove number from end since fusion - # will swap it with the frame number - filename = filename.replace(match.group(1), '') - elif '#' in filename: - match = re.match('.*?(#+)$', filename) - - if match: - padding = len(match.group(1)) - # remove number from end since fusion - # will swap it with the frame number - filename = filename.replace(match.group(1), '') - - return filename, padding, ext - - -def get_nuke_imageio_settings(): - return get_project_settings(Context.project_name)["nuke"]["imageio"] - - -def get_imageio_node_setting(node_class, plugin_name, product_name): - """Get preset data for dataflow (fileType, compression, bitDepth)""" - imageio_nodes = get_nuke_imageio_settings()["nodes"] - required_nodes = imageio_nodes["required_nodes"] - - imageio_node = None - for node in required_nodes: - log.info(node) - if ( - node_class in node["nuke_node_class"] - and plugin_name in node["plugins"] - ): - imageio_node = node - break - - if not imageio_node: - return - - # find overrides and update knobs with them - get_imageio_node_override_setting( - node_class, - plugin_name, - product_name, - imageio_node["knobs"] - ) - return imageio_node - - -def get_imageio_node_override_setting( - node_class, plugin_name, product_name, knobs_settings -): - """ Get imageio node overrides from settings - """ - imageio_nodes = get_nuke_imageio_settings()["nodes"] - override_nodes = imageio_nodes["override_nodes"] - - # find matching override node - override_imageio_node = None - for onode in override_nodes: - if node_class not in onode["nuke_node_class"]: - continue - - if plugin_name not in onode["plugins"]: - continue - - # TODO change 'subsets' to 'product_names' in settings - if ( - onode["subsets"] - and not any( - re.search(s.lower(), product_name.lower()) - for s in onode["subsets"] - ) - ): - continue - - override_imageio_node = onode - break - - # add overrides to imageio_node - if override_imageio_node: - # get all knob names in imageio_node - knob_names = [k["name"] for k in knobs_settings] - - for oknob in override_imageio_node["knobs"]: - oknob_name = oknob["name"] - oknob_type = oknob["type"] - oknob_value = oknob[oknob_type] - for knob in knobs_settings: - # add missing knobs into imageio_node - if oknob_name not in knob_names: - knobs_settings.append(oknob) - knob_names.append(oknob_name) - continue - - if oknob_name != knob["name"]: - continue - - knob_type = knob["type"] - # override matching knob name - if not oknob_value: - # remove original knob if no value found in oknob - knobs_settings.remove(knob) - else: - # override knob value with oknob's - knob[knob_type] = oknob_value - - return knobs_settings - - -def get_imageio_input_colorspace(filename): - """Get input file colorspace based on regex in settings.""" - imageio_regex_inputs = ( - get_nuke_imageio_settings()["regex_inputs"]["inputs"]) - - preset_clrsp = None - for regexInput in imageio_regex_inputs: - if bool(re.search(regexInput["regex"], filename)): - preset_clrsp = str(regexInput["colorspace"]) - - return preset_clrsp - - -def get_view_process_node(): - reset_selection() - - ipn_node = None - for v_ in nuke.allNodes(filter="Viewer"): - ipn = v_['input_process_node'].getValue() - ipn_node = nuke.toNode(ipn) - - # skip if no input node is set - if not ipn: - continue - - if ipn == "VIEWER_INPUT" and not ipn_node: - # since it is set by default we can ignore it - # nobody usually use this but use it if - # it exists in nodes - continue - - if not ipn_node: - # in case a Viewer node is transferred from - # different workfile with old values - raise NameError(( - "Input process node name '{}' set in " - "Viewer '{}' is doesn't exists in nodes" - ).format(ipn, v_.name())) - - ipn_node.setSelected(True) - - if ipn_node: - return duplicate_node(ipn_node) - - -def on_script_load(): - """Callback for ffmpeg support""" - if nuke.env["LINUX"]: - nuke.tcl('load ffmpegReader') - nuke.tcl('load ffmpegWriter') - else: - nuke.tcl('load movReader') - nuke.tcl('load movWriter') - - -def check_inventory_versions(): - """ - Actual version identifier of Loaded containers - - Any time this function is run it will check all nodes and filter only - Loader nodes for its version. It will get all versions from database - and check if the node is having actual version. If not then it will color - it to red. - """ - from .pipeline import parse_container - - # get all Loader nodes by avalon attribute metadata - node_with_repre_id = [] - repre_ids = set() - # Find all containers and collect its node and representation ids - for node in nuke.allNodes(): - container = parse_container(node) - - if container: - node = nuke.toNode(container["objectName"]) - avalon_knob_data = read_avalon_data(node) - repre_id = avalon_knob_data["representation"] - - repre_ids.add(repre_id) - node_with_repre_id.append((node, repre_id)) - - # Skip if nothing was found - if not repre_ids: - return - - project_name = get_current_project_name() - # Find representations based on found containers - repre_entities = ayon_api.get_representations( - project_name, - representation_ids=repre_ids, - fields={"id", "versionId"} - ) - # Store representations by id and collect version ids - repre_entities_by_id = {} - version_ids = set() - for repre_entity in repre_entities: - # Use stringed representation id to match value in containers - repre_id = repre_entity["id"] - repre_entities_by_id[repre_id] = repre_entity - version_ids.add(repre_entity["versionId"]) - - version_entities = ayon_api.get_versions( - project_name, - version_ids=version_ids, - fields={"id", "version", "productId"}, - ) - # Store versions by id and collect product ids - version_entities_by_id = {} - product_ids = set() - for version_entity in version_entities: - version_entities_by_id[version_entity["id"]] = version_entity - product_ids.add(version_entity["productId"]) - - # Query last versions based on product ids - last_versions_by_product_id = ayon_api.get_last_versions( - project_name, product_ids=product_ids, fields={"id", "productId"} - ) - - # Loop through collected container nodes and their representation ids - for item in node_with_repre_id: - # Some python versions of nuke can't unfold tuple in for loop - node, repre_id = item - repre_entity = repre_entities_by_id.get(repre_id) - # Failsafe for not finding the representation. - if not repre_entity: - log.warning(( - "Could not find the representation on node \"{}\"" - ).format(node.name())) - continue - - version_id = repre_entity["versionId"] - version_entity = version_entities_by_id.get(version_id) - if not version_entity: - log.warning(( - "Could not find the version on node \"{}\"" - ).format(node.name())) - continue - - # Get last version based on product id - product_id = version_entity["productId"] - last_version = last_versions_by_product_id[product_id] - # Check if last version is same as current version - if last_version["id"] == version_entity["id"]: - color_value = "0x4ecd25ff" - else: - color_value = "0xd84f20ff" - node["tile_color"].setValue(int(color_value, 16)) - - -def writes_version_sync(): - """Callback synchronizing version of publishable write nodes""" - try: - rootVersion = get_version_from_path(nuke.root().name()) - padding = len(rootVersion) - new_version = "v" + str("{" + ":0>{}".format(padding) + "}").format( - int(rootVersion) - ) - except Exception: - return - - for each in nuke.allNodes(filter="Write"): - # check if the node is avalon tracked - if NODE_TAB_NAME not in each.knobs(): - continue - - avalon_knob_data = read_avalon_data(each) - - try: - if avalon_knob_data["families"] not in ["render"]: - continue - - node_file = each["file"].value() - - node_version = "v" + get_version_from_path(node_file) - - node_new_file = node_file.replace(node_version, new_version) - each["file"].setValue(node_new_file) - if not os.path.isdir(os.path.dirname(node_new_file)): - log.warning("Path does not exist! I am creating it.") - os.makedirs(os.path.dirname(node_new_file)) - except Exception as e: - log.warning( - "Write node: `{}` has no version in path: {}".format( - each.name(), e)) - - -def version_up_script(): - """Raising working script's version""" - import nukescripts - nukescripts.script_and_write_nodes_version_up() - - -def check_product_name_exists(nodes, product_name): - """ - Checking if node is not already created to secure there is no duplicity - - Arguments: - nodes (list): list of nuke.Node objects - product_name (str): name we try to find - - Returns: - bool: True of False - """ - return next((True for n in nodes - if product_name in read_avalon_data(n).get("productName", "")), - False) - - -def format_anatomy(data): - """Helping function for formatting of anatomy paths - - Arguments: - data (dict): dictionary with attributes used for formatting - - Return: - str: Formatted path. - """ - - project_name = get_current_project_name() - anatomy = Anatomy(project_name) - - frame_padding = anatomy.templates_obj.frame_padding - - version = data.get("version") - if version is None: - file = script_name() - data["version"] = get_version_from_path(file) - - folder_path = data["folderPath"] - task_name = data["task"] - host_name = get_current_host_name() - - context_data = get_template_data_with_names( - project_name, folder_path, task_name, host_name - ) - data.update(context_data) - data.update({ - "subset": data["productName"], - "family": data["productType"], - "product": { - "name": data["productName"], - "type": data["productType"], - }, - "frame": "#" * frame_padding, - }) - return anatomy.format(data) - - -def script_name() -> str: - """Returns nuke script path""" - return nuke.root().knob("name").value() - - -def add_button_render_on_farm(node): - name = "renderOnFarm" - label = "Render On Farm" - value = ( - "from ayon_nuke.api.utils import submit_render_on_farm;" - "submit_render_on_farm(nuke.thisNode())" - ) - knob = nuke.PyScript_Knob(name, label, value) - knob.clearFlag(nuke.STARTLINE) - node.addKnob(knob) - - -def add_button_write_to_read(node): - name = "createReadNode" - label = "Read From Rendered" - value = "import write_to_read;\ - write_to_read.write_to_read(nuke.thisNode(), allow_relative=False)" - knob = nuke.PyScript_Knob(name, label, value) - knob.clearFlag(nuke.STARTLINE) - node.addKnob(knob) - - -def add_button_clear_rendered(node, path): - name = "clearRendered" - label = "Clear Rendered" - value = "import clear_rendered;\ - clear_rendered.clear_rendered(\"{}\")".format(path) - knob = nuke.PyScript_Knob(name, label, value) - node.addKnob(knob) - - -def create_prenodes( - prev_node, - nodes_setting, - plugin_name=None, - product_name=None, - **kwargs -): - last_node = None - for_dependency = {} - for node in nodes_setting: - # get attributes - name = node["name"] - nodeclass = node["nodeclass"] - knobs = node["knobs"] - - # create node - now_node = nuke.createNode( - nodeclass, - "name {}".format(name), - inpanel=False - ) - - # add for dependency linking - for_dependency[name] = { - "node": now_node, - "dependent": node["dependent"] - } - - if all([plugin_name, product_name]): - # find imageio overrides - get_imageio_node_override_setting( - now_node.Class(), - plugin_name, - product_name, - knobs - ) - - # add data to knob - set_node_knobs_from_settings(now_node, knobs, **kwargs) - - # switch actual node to previous - last_node = now_node - - for _node_name, node_prop in for_dependency.items(): - if not node_prop["dependent"]: - node_prop["node"].setInput( - 0, prev_node) - elif node_prop["dependent"] in for_dependency: - _prev_node = for_dependency[node_prop["dependent"]]["node"] - node_prop["node"].setInput( - 0, _prev_node) - else: - log.warning("Dependency has wrong name of node: {}".format( - node_prop - )) - - return last_node - - -def create_write_node( - name, - data, - input=None, - prenodes=None, - linked_knobs=None, - **kwargs -): - """Creating write node which is group node - - Arguments: - name (str): name of node - data (dict): creator write instance data - input (node)[optional]: selected node to connect to - prenodes (Optional[list[dict]]): nodes to be created before write - with dependency - review (bool)[optional]: adding review knob - farm (bool)[optional]: rendering workflow target - kwargs (dict)[optional]: additional key arguments for formatting - - Example: - prenodes = { - "nodeName": { - "nodeclass": "Reformat", - "dependent": [ - following_node_01, - ... - ], - "knobs": [ - { - "type": "text", - "name": "knobname", - "value": "knob value" - }, - ... - ] - }, - ... - } - - - Return: - node (nuke.Node): group node with avalon data as Knobs - """ - # Ensure name does not contain any invalid characters. - special_chars = re.escape("!@#$%^&*()=[]{}|\\;',.<>/?~+-") - special_chars_regex = re.compile(f"[{special_chars}]") - found_special_characters = list(special_chars_regex.findall(name)) - - msg = ( - f"Special characters found in name \"{name}\": " - f"{' '.join(found_special_characters)}" - ) - assert not found_special_characters, msg - - prenodes = prenodes or [] - - # filtering variables - plugin_name = data["creator"] - product_name = data["productName"] - - # get knob settings for write node - imageio_writes = get_imageio_node_setting( - node_class="Write", - plugin_name=plugin_name, - product_name=product_name - ) - - for knob in imageio_writes["knobs"]: - if knob["name"] == "file_type": - knot_type = knob["type"] - ext = knob[knot_type] - - data.update({ - "imageio_writes": imageio_writes, - "ext": ext - }) - anatomy_filled = format_anatomy(data) - - # build file path to workfiles - fdir = str( - anatomy_filled["work"]["default"]["directory"] - ).replace("\\", "/") - data["work"] = fdir - fpath = StringTemplate(data["fpath_template"]).format_strict(data) - - # create directory - if not os.path.isdir(os.path.dirname(fpath)): - log.warning("Path does not exist! I am creating it.") - os.makedirs(os.path.dirname(fpath)) - - GN = nuke.createNode("Group", "name {}".format(name)) - - prev_node = None - with GN: - if input: - input_name = str(input.name()).replace(" ", "") - # if connected input node was defined - prev_node = nuke.createNode( - "Input", - "name {}".format(input_name), - inpanel=False - ) - else: - # generic input node connected to nothing - prev_node = nuke.createNode( - "Input", - "name {}".format("rgba"), - inpanel=False - ) - - # creating pre-write nodes `prenodes` - last_prenode = create_prenodes( - prev_node, - prenodes, - plugin_name, - product_name, - **kwargs - ) - if last_prenode: - prev_node = last_prenode - - # creating write node - write_node = now_node = add_write_node( - "inside_{}".format(name), - fpath, - imageio_writes["knobs"], - **data - ) - # connect to previous node - now_node.setInput(0, prev_node) - - # switch actual node to previous - prev_node = now_node - - now_node = nuke.createNode("Output", "name Output1", inpanel=False) - - # connect to previous node - now_node.setInput(0, prev_node) - - # add divider - GN.addKnob(nuke.Text_Knob('', 'Rendering')) - - # Add linked knobs. - linked_knob_names = [] - - # add input linked knobs and create group only if any input - if linked_knobs: - linked_knob_names.append("_grp-start_") - linked_knob_names.extend(linked_knobs) - linked_knob_names.append("_grp-end_") - - linked_knob_names.append("Render") - - for _k_name in linked_knob_names: - if "_grp-start_" in _k_name: - knob = nuke.Tab_Knob( - "rnd_attr", "Rendering attributes", nuke.TABBEGINCLOSEDGROUP) - GN.addKnob(knob) - elif "_grp-end_" in _k_name: - knob = nuke.Tab_Knob( - "rnd_attr_end", "Rendering attributes", nuke.TABENDGROUP) - GN.addKnob(knob) - else: - if "___" in _k_name: - # add divider - GN.addKnob(nuke.Text_Knob("")) - else: - # add linked knob by _k_name - link = nuke.Link_Knob("") - link.makeLink(write_node.name(), _k_name) - link.setName(_k_name) - - # make render - if "Render" in _k_name: - link.setLabel("Render Local") - link.setFlag(0x1000) - GN.addKnob(link) - - # Adding render farm submission button. - if data.get("render_on_farm", False): - add_button_render_on_farm(GN) - - # adding write to read button - add_button_write_to_read(GN) - - # adding write to read button - add_button_clear_rendered(GN, os.path.dirname(fpath)) - - # set tile color - tile_color = next( - iter( - k[k["type"]] for k in imageio_writes["knobs"] - if "tile_color" in k["name"] - ), [255, 0, 0, 255] - ) - new_tile_color = [] - for c in tile_color: - if isinstance(c, float): - c = int(c * 255) - new_tile_color.append(c) - GN["tile_color"].setValue( - color_gui_to_int(new_tile_color)) - - return GN - - -def set_node_knobs_from_settings(node, knob_settings, **kwargs): - """Overriding knob values from settings - - Using `schema_nuke_knob_inputs` for knob type definitions. - - Args: - node (nuke.Node): nuke node - knob_settings (list): list of dict. Keys are `type`, `name`, `value` - kwargs (dict)[optional]: keys for formattable knob settings - """ - for knob in knob_settings: - knob_name = knob["name"] - if knob_name not in node.knobs(): - continue - - knob_type = knob["type"] - knob_value = knob[knob_type] - if knob_type == "expression": - node[knob_name].setExpression(knob_value) - continue - - # first deal with formattable knob settings - if knob_type == "formatable": - template = knob_value["template"] - to_type = knob_value["to_type"] - try: - knob_value = template.format(**kwargs) - except KeyError as msg: - raise KeyError( - "Not able to format expression: {}".format(msg)) - - # convert value to correct type - if to_type == "2d_vector": - knob_value = knob_value.split(";").split(",") - - knob_type = to_type - - if not knob_value: - continue - - knob_value = convert_knob_value_to_correct_type( - knob_type, knob_value) - - node[knob_name].setValue(knob_value) - - -def convert_knob_value_to_correct_type(knob_type, knob_value): - # Convert 'text' to string to avoid unicode - if knob_type == "text": - return str(knob_value) - - if knob_type == "boolean": - return bool(knob_value) - - if knob_type == "decimal_number": - return float(knob_value) - - if knob_type == "number": - return int(knob_value) - - if knob_type == "color_gui": - new_color = [] - for value in knob_value: - if isinstance(value, float): - value = int(value * 255) - new_color.append(value) - return color_gui_to_int(new_color) - - if knob_type == "box": - return [ - knob_value["x"], knob_value["y"], - knob_value["r"], knob_value["t"] - ] - - if knob_type == "vector_2d": - return [knob_value["x"], knob_value["y"]] - - if knob_type == "vector_3d": - return [knob_value["x"], knob_value["y"], knob_value["z"]] - - return knob_value - - -def color_gui_to_int(color_gui): - # Append alpha channel if not present - if len(color_gui) == 3: - color_gui = list(color_gui) + [255] - hex_value = ( - "0x{0:0>2x}{1:0>2x}{2:0>2x}{3:0>2x}").format(*color_gui) - return int(hex_value, 16) - - -def create_backdrop(label="", color=None, layer=0, - nodes=None): - """Create Backdrop node - - Arguments: - color (str): nuke compatible string with color code - layer (int): layer of node usually used (self.pos_layer - 1) - label (str): the message - nodes (list): list of nodes to be wrapped into backdrop - - Returns: - nuke.Node: The created backdrop node. - - """ - assert isinstance(nodes, list), "`nodes` should be a list of nodes" - - # Calculate bounds for the backdrop node. - bdX = min([node.xpos() for node in nodes]) - bdY = min([node.ypos() for node in nodes]) - bdW = max([node.xpos() + node.screenWidth() for node in nodes]) - bdX - bdH = max([node.ypos() + node.screenHeight() for node in nodes]) - bdY - - # Expand the bounds to leave a little border. Elements are offsets - # for left, top, right and bottom edges respectively - left, top, right, bottom = (-20, -65, 20, 60) - bdX += left - bdY += top - bdW += (right - left) - bdH += (bottom - top) - - bdn = nuke.createNode("BackdropNode") - bdn["z_order"].setValue(layer) - - if color: - bdn["tile_color"].setValue(int(color, 16)) - - bdn["xpos"].setValue(bdX) - bdn["ypos"].setValue(bdY) - bdn["bdwidth"].setValue(bdW) - bdn["bdheight"].setValue(bdH) - - if label: - bdn["label"].setValue(label) - - bdn["note_font_size"].setValue(20) - return bdn - - -class WorkfileSettings(object): - """ - All settings for workfile will be set - - This object is setting all possible root settings to the workfile. - Including Colorspace, Frame ranges, Resolution format. It can set it - to Root node or to any given node. - - Arguments: - root (node): nuke's root node - nodes (list): list of nuke's nodes - nodes_filter (list): filtering classes for nodes - - """ - - def __init__(self, root_node=None, nodes=None, **kwargs): - project_entity = kwargs.get("project") - if project_entity is None: - project_name = get_current_project_name() - project_entity = ayon_api.get_project(project_name) - else: - project_name = project_entity["name"] - - Context._project_entity = project_entity - self._project_name = project_name - self._folder_path = get_current_folder_path() - self._task_name = get_current_task_name() - self._folder_entity = ayon_api.get_folder_by_path( - project_name, self._folder_path - ) - self._root_node = root_node or nuke.root() - self._nodes = self.get_nodes(nodes=nodes) - - context_data = get_template_data_with_names( - project_name, self._folder_path, self._task_name, "nuke" - ) - self.formatting_data = context_data - - def get_nodes(self, nodes=None, nodes_filter=None): - - if not isinstance(nodes, list) and not isinstance(nodes_filter, list): - return [n for n in nuke.allNodes()] - elif not isinstance(nodes, list) and isinstance(nodes_filter, list): - nodes = list() - for filter in nodes_filter: - [nodes.append(n) for n in nuke.allNodes(filter=filter)] - return nodes - elif isinstance(nodes, list) and not isinstance(nodes_filter, list): - return [n for n in self._nodes] - elif isinstance(nodes, list) and isinstance(nodes_filter, list): - for filter in nodes_filter: - return [n for n in self._nodes if filter in n.Class()] - - def set_viewers_colorspace(self, imageio_nuke): - """Adds correct colorspace to viewer - - Arguments: - imageio_nuke (dict): nuke colorspace configurations - - """ - filter_knobs = [ - "viewerProcess", - "wipe_position", - "monitorOutOutputTransform" - ] - viewer_process = self._display_and_view_formatted( - imageio_nuke["viewer"] - ) - output_transform = self._display_and_view_formatted( - imageio_nuke["monitor"] - ) - erased_viewers = [] - for v in nuke.allNodes(filter="Viewer"): - # set viewProcess to preset from settings - v["viewerProcess"].setValue(viewer_process) - - if viewer_process not in v["viewerProcess"].value(): - copy_inputs = v.dependencies() - copy_knobs = { - k: v[k].value() for k in v.knobs() - if k not in filter_knobs - } - - # delete viewer with wrong settings - erased_viewers.append(v["name"].value()) - nuke.delete(v) - - # create new viewer - nv = nuke.createNode("Viewer") - - # connect to original inputs - for i, n in enumerate(copy_inputs): - nv.setInput(i, n) - - # set copied knobs - for k, v in copy_knobs.items(): - nv[k].setValue(v) - - # set viewerProcess - nv["viewerProcess"].setValue(viewer_process) - nv["monitorOutOutputTransform"].setValue(output_transform) - - if erased_viewers: - log.warning( - "Attention! Viewer nodes {} were erased." - "It had wrong color profile".format(erased_viewers)) - - def _display_and_view_formatted(self, view_profile): - """ Format display and view profile string - - Args: - view_profile (dict): view and display profile - - Returns: - str: formatted display and view profile string - """ - display_view = create_viewer_profile_string( - view_profile["view"], view_profile["display"], path_like=False - ) - # format any template tokens used in the string - return StringTemplate(display_view).format_strict(self.formatting_data) - - def set_root_colorspace(self, imageio_host): - """Adds correct colorspace to root - - Arguments: - imageio_host (dict): host colorspace configurations - - """ - config_data = get_current_context_imageio_config_preset() - - workfile_settings = imageio_host["workfile"] - color_management = workfile_settings["color_management"] - native_ocio_config = workfile_settings["native_ocio_config"] - - if not config_data: - # no ocio config found and no custom path used - if self._root_node["colorManagement"].value() \ - not in color_management: - self._root_node["colorManagement"].setValue(color_management) - - # second set ocio version - if self._root_node["OCIO_config"].value() \ - not in native_ocio_config: - self._root_node["OCIO_config"].setValue(native_ocio_config) - - else: - # OCIO config path is defined from prelaunch hook - self._root_node["colorManagement"].setValue("OCIO") - - # print previous settings in case some were found in workfile - residual_path = self._root_node["customOCIOConfigPath"].value() - if residual_path: - log.info("Residual OCIO config path found: `{}`".format( - residual_path - )) - - # set ocio config path - if config_data: - config_path = config_data["path"].replace("\\", "/") - log.info("OCIO config path found: `{}`".format( - config_path)) - - # check if there's a mismatch between environment and settings - correct_settings = self._is_settings_matching_environment( - config_data) - - # if there's no mismatch between environment and settings - if correct_settings: - self._set_ocio_config_path_to_workfile(config_data) - - workfile_settings_output = {} - # get monitor lut from settings respecting Nuke version differences - monitor_lut_data = self._get_monitor_settings( - workfile_settings["monitor_out_lut"], - workfile_settings["monitor_lut"] - ) - workfile_settings_output.update(monitor_lut_data) - workfile_settings_output.update( - { - "workingSpaceLUT": workfile_settings["working_space"], - "int8Lut": workfile_settings["int_8_lut"], - "int16Lut": workfile_settings["int_16_lut"], - "logLut": workfile_settings["log_lut"], - "floatLut": workfile_settings["float_lut"], - } - ) - - # then set the rest - for knob, value_ in workfile_settings_output.items(): - # skip unfilled ocio config path - # it will be dict in value - if isinstance(value_, dict): - continue - # skip empty values - if not value_: - continue - self._root_node[knob].setValue(str(value_)) - - def _get_monitor_settings(self, viewer_lut, monitor_lut): - """ Get monitor settings from viewer and monitor lut - - Args: - viewer_lut (str): viewer lut string - monitor_lut (str): monitor lut string - - Returns: - dict: monitor settings - """ - output_data = {} - m_display, m_viewer = get_viewer_config_from_string(monitor_lut) - v_display, v_viewer = get_viewer_config_from_string(viewer_lut) - - # set monitor lut differently for nuke version 14 - if nuke.NUKE_VERSION_MAJOR >= 14: - output_data["monitorOutLUT"] = create_viewer_profile_string( - m_viewer, m_display, path_like=False) - # monitorLut=thumbnails - viewerProcess makes more sense - output_data["monitorLut"] = create_viewer_profile_string( - v_viewer, v_display, path_like=False) - - if nuke.NUKE_VERSION_MAJOR == 13: - output_data["monitorOutLUT"] = create_viewer_profile_string( - m_viewer, m_display, path_like=False) - # monitorLut=thumbnails - viewerProcess makes more sense - output_data["monitorLut"] = create_viewer_profile_string( - v_viewer, v_display, path_like=True) - if nuke.NUKE_VERSION_MAJOR <= 12: - output_data["monitorLut"] = create_viewer_profile_string( - m_viewer, m_display, path_like=True) - - return output_data - - def _is_settings_matching_environment(self, config_data): - """ Check if OCIO config path is different from environment - - Args: - config_data (dict): OCIO config data from settings - - Returns: - bool: True if settings are matching environment, False otherwise - """ - current_ocio_path = os.environ["OCIO"] - settings_ocio_path = config_data["path"] - - # normalize all paths to forward slashes - current_ocio_path = current_ocio_path.replace("\\", "/") - settings_ocio_path = settings_ocio_path.replace("\\", "/") - - if current_ocio_path != settings_ocio_path: - message = """ -It seems like there's a mismatch between the OCIO config path set in your Nuke -settings and the actual path set in your OCIO environment. - -To resolve this, please follow these steps: -1. Close Nuke if it's currently open. -2. Reopen Nuke. - -Please note the paths for your reference: - -- The OCIO environment path currently set: - `{env_path}` - -- The path in your current Nuke settings: - `{settings_path}` - -Reopening Nuke should synchronize these paths and resolve any discrepancies. -""" - nuke.message( - message.format( - env_path=current_ocio_path, - settings_path=settings_ocio_path - ) - ) - return False - - return True - - def _set_ocio_config_path_to_workfile(self, config_data): - """ Set OCIO config path to workfile - - Path set into nuke workfile. It is trying to replace path with - environment variable if possible. If not, it will set it as it is. - It also saves the script to apply the change, but only if it's not - empty Untitled script. - - Args: - config_data (dict): OCIO config data from settings - - """ - # replace path with env var if possible - ocio_path = self._replace_ocio_path_with_env_var(config_data) - - log.info("Setting OCIO config path to: `{}`".format( - ocio_path)) - - self._root_node["customOCIOConfigPath"].setValue( - ocio_path - ) - self._root_node["OCIO_config"].setValue("custom") - - # only save script if it's not empty - if self._root_node["name"].value() != "": - log.info("Saving script to apply OCIO config path change.") - nuke.scriptSave() - - def _get_included_vars(self, config_template): - """ Get all environment variables included in template - - Args: - config_template (str): OCIO config template from settings - - Returns: - list: list of environment variables included in template - """ - # resolve all environments for whitelist variables - included_vars = [ - "BUILTIN_OCIO_ROOT", - ] - - # include all project root related env vars - for env_var in os.environ: - if env_var.startswith("AYON_PROJECT_ROOT_"): - included_vars.append(env_var) - - # use regex to find env var in template with format {ENV_VAR} - # this way we make sure only template used env vars are included - env_var_regex = r"\{([A-Z0-9_]+)\}" - env_var = re.findall(env_var_regex, config_template) - if env_var: - included_vars.append(env_var[0]) - - return included_vars - - def _replace_ocio_path_with_env_var(self, config_data): - """ Replace OCIO config path with environment variable - - Environment variable is added as TCL expression to path. TCL expression - is also replacing backward slashes found in path for windows - formatted values. - - Args: - config_data (str): OCIO config dict from settings - - Returns: - str: OCIO config path with environment variable TCL expression - """ - config_path = config_data["path"].replace("\\", "/") - config_template = config_data["template"] - - included_vars = self._get_included_vars(config_template) - - # make sure we return original path if no env var is included - new_path = config_path - - for env_var in included_vars: - env_path = os.getenv(env_var) - if not env_path: - continue - - # it has to be directory current process can see - if not os.path.isdir(env_path): - continue - - # make sure paths are in same format - env_path = env_path.replace("\\", "/") - path = config_path.replace("\\", "/") - - # check if env_path is in path and replace to first found positive - if env_path in path: - # with regsub we make sure path format of slashes is correct - resub_expr = ( - "[regsub -all {{\\\\}} [getenv {}] \"/\"]").format(env_var) - - new_path = path.replace( - env_path, resub_expr - ) - break - - return new_path - - def set_writes_colorspace(self): - """ Adds correct colorspace to write node dict - """ - for node in nuke.allNodes(filter="Group", group=self._root_node): - log.info("Setting colorspace to `{}`".format(node.name())) - - # get data from avalon knob - avalon_knob_data = read_avalon_data(node) - node_data = get_node_data(node, INSTANCE_DATA_KNOB) - - if ( - # backward compatibility - # TODO: remove this once old avalon data api will be removed - avalon_knob_data - and avalon_knob_data.get("id") not in { - AYON_INSTANCE_ID, AVALON_INSTANCE_ID - } - ): - continue - elif ( - node_data - and node_data.get("id") not in { - AYON_INSTANCE_ID, AVALON_INSTANCE_ID - } - ): - continue - - if ( - # backward compatibility - # TODO: remove this once old avalon data api will be removed - avalon_knob_data - and "creator" not in avalon_knob_data - ): - continue - elif ( - node_data - and "creator_identifier" not in node_data - ): - continue - - nuke_imageio_writes = None - if avalon_knob_data: - # establish families - product_type = avalon_knob_data.get("productType") - if product_type is None: - product_type = avalon_knob_data["family"] - families = [product_type] - if avalon_knob_data.get("families"): - families.append(avalon_knob_data.get("families")) - - nuke_imageio_writes = get_imageio_node_setting( - node_class=avalon_knob_data["families"], - plugin_name=avalon_knob_data["creator"], - product_name=avalon_knob_data["productName"] - ) - elif node_data: - nuke_imageio_writes = get_write_node_template_attr(node) - - if not nuke_imageio_writes: - return - - write_node = None - - # get into the group node - node.begin() - for x in nuke.allNodes(): - if x.Class() == "Write": - write_node = x - node.end() - - if not write_node: - return - - set_node_knobs_from_settings( - write_node, nuke_imageio_writes["knobs"]) - - def set_reads_colorspace(self, read_clrs_inputs): - """ Setting colorspace to Read nodes - - Looping through all read nodes and tries to set colorspace based - on regex rules in presets - """ - changes = {} - for n in nuke.allNodes(): - file = nuke.filename(n) - if n.Class() != "Read": - continue - - # check if any colorspace presets for read is matching - preset_clrsp = None - - for input in read_clrs_inputs: - if not bool(re.search(input["regex"], file)): - continue - preset_clrsp = input["colorspace"] - - if preset_clrsp is not None: - current = n["colorspace"].value() - future = str(preset_clrsp) - if current != future: - changes[n.name()] = { - "from": current, - "to": future - } - - if changes: - msg = "Read nodes are not set to correct colorspace:\n\n" - for nname, knobs in changes.items(): - msg += ( - " - node: '{0}' is now '{1}' but should be '{2}'\n" - ).format(nname, knobs["from"], knobs["to"]) - - msg += "\nWould you like to change it?" - - if nuke.ask(msg): - for nname, knobs in changes.items(): - n = nuke.toNode(nname) - n["colorspace"].setValue(knobs["to"]) - log.info( - "Setting `{0}` to `{1}`".format( - nname, - knobs["to"])) - - def set_colorspace(self): - """ Setting colorspace following presets - """ - # get imageio - nuke_colorspace = get_nuke_imageio_settings() - - log.info("Setting colorspace to workfile...") - try: - self.set_root_colorspace(nuke_colorspace) - except AttributeError as _error: - msg = "Set Colorspace to workfile error: {}".format(_error) - nuke.message(msg) - - log.info("Setting colorspace to viewers...") - try: - self.set_viewers_colorspace(nuke_colorspace) - except AttributeError as _error: - msg = "Set Colorspace to viewer error: {}".format(_error) - nuke.message(msg) - - log.info("Setting colorspace to write nodes...") - try: - self.set_writes_colorspace() - except AttributeError as _error: - nuke.message(_error) - log.error(_error) - - log.info("Setting colorspace to read nodes...") - read_clrs_inputs = nuke_colorspace["regex_inputs"].get("inputs", []) - if read_clrs_inputs: - self.set_reads_colorspace(read_clrs_inputs) - - def reset_frame_range_handles(self): - """Set frame range to current folder.""" - - if "attrib" not in self._folder_entity: - msg = "Folder {} don't have set any 'attrib'".format( - self._folder_path - ) - log.warning(msg) - nuke.message(msg) - return - - folder_attributes = self._folder_entity["attrib"] - - missing_cols = [] - check_cols = ["fps", "frameStart", "frameEnd", - "handleStart", "handleEnd"] - - for col in check_cols: - if col not in folder_attributes: - missing_cols.append(col) - - if len(missing_cols) > 0: - missing = ", ".join(missing_cols) - msg = "'{}' are not set for folder '{}'!".format( - missing, self._folder_path) - log.warning(msg) - nuke.message(msg) - return - - # get handles values - handle_start = folder_attributes["handleStart"] - handle_end = folder_attributes["handleEnd"] - frame_start = folder_attributes["frameStart"] - frame_end = folder_attributes["frameEnd"] - - fps = float(folder_attributes["fps"]) - frame_start_handle = frame_start - handle_start - frame_end_handle = frame_end + handle_end - - self._root_node["lock_range"].setValue(False) - self._root_node["fps"].setValue(fps) - self._root_node["first_frame"].setValue(frame_start_handle) - self._root_node["last_frame"].setValue(frame_end_handle) - self._root_node["lock_range"].setValue(True) - - # update node graph so knobs are updated - update_node_graph() - - frame_range = '{0}-{1}'.format(frame_start, frame_end) - - for node in nuke.allNodes(filter="Viewer"): - node['frame_range'].setValue(frame_range) - node['frame_range_lock'].setValue(True) - node['frame_range'].setValue(frame_range) - node['frame_range_lock'].setValue(True) - - if not ASSIST: - set_node_data( - self._root_node, - INSTANCE_DATA_KNOB, - { - "handleStart": int(handle_start), - "handleEnd": int(handle_end) - } - ) - else: - log.warning( - "NukeAssist mode is not allowing " - "updating custom knobs..." - ) - - def reset_resolution(self): - """Set resolution to project resolution.""" - log.info("Resetting resolution") - project_name = get_current_project_name() - folder_attributes = self._folder_entity["attrib"] - - format_data = { - "width": folder_attributes["resolutionWidth"], - "height": folder_attributes["resolutionHeight"], - "pixel_aspect": folder_attributes["pixelAspect"], - "name": project_name - } - - if any(x_ for x_ in format_data.values() if x_ is None): - msg = ("Missing set shot attributes in DB." - "\nContact your supervisor!." - "\n\nWidth: `{width}`" - "\nHeight: `{height}`" - "\nPixel Aspect: `{pixel_aspect}`").format(**format_data) - log.error(msg) - nuke.message(msg) - - existing_format = None - for format in nuke.formats(): - if format_data["name"] == format.name(): - existing_format = format - break - - if existing_format: - # Enforce existing format to be correct. - existing_format.setWidth(format_data["width"]) - existing_format.setHeight(format_data["height"]) - existing_format.setPixelAspect(format_data["pixel_aspect"]) - else: - format_string = self.make_format_string(**format_data) - log.info("Creating new format: {}".format(format_string)) - nuke.addFormat(format_string) - - nuke.root()["format"].setValue(format_data["name"]) - log.info("Format is set.") - - # update node graph so knobs are updated - update_node_graph() - - def make_format_string(self, **kwargs): - if kwargs.get("r"): - return ( - "{width} " - "{height} " - "{x} " - "{y} " - "{r} " - "{t} " - "{pixel_aspect:.2f} " - "{name}".format(**kwargs) - ) - else: - return ( - "{width} " - "{height} " - "{pixel_aspect:.2f} " - "{name}".format(**kwargs) - ) - - def set_context_settings(self): - # replace reset resolution from avalon core to pype's - self.reset_resolution() - # replace reset resolution from avalon core to pype's - self.reset_frame_range_handles() - # add colorspace menu item - self.set_colorspace() - - def set_favorites(self): - from .utils import set_context_favorites - - work_dir = os.getenv("AYON_WORKDIR") - # TODO validate functionality - # - does expect the structure is '{root}/{project}/{folder}' - # - this used asset name expecting it is unique in project - folder_path = get_current_folder_path() - folder_name = folder_path.split("/")[-1] - favorite_items = OrderedDict() - - # project - # get project's root and split to parts - projects_root = os.path.normpath(work_dir.split( - Context.project_name)[0]) - # add project name - project_dir = os.path.join(projects_root, Context.project_name) + "/" - # add to favorites - favorite_items.update({"Project dir": project_dir.replace("\\", "/")}) - - # folder - folder_root = os.path.normpath(work_dir.split( - folder_name)[0]) - # add folder name - folder_dir = os.path.join(folder_root, folder_name) + "/" - # add to favorites - favorite_items.update({"Shot dir": folder_dir.replace("\\", "/")}) - - # workdir - favorite_items.update({"Work dir": work_dir.replace("\\", "/")}) - - set_context_favorites(favorite_items) - - -def get_write_node_template_attr(node): - """ Gets all defined data from presets - """ - - # TODO: add identifiers to settings and rename settings key - plugin_names_mapping = { - "create_write_image": "CreateWriteImage", - "create_write_prerender": "CreateWritePrerender", - "create_write_render": "CreateWriteRender" - } - # get avalon data from node - node_data = get_node_data(node, INSTANCE_DATA_KNOB) - identifier = node_data["creator_identifier"] - - # return template data - product_name = node_data.get("productName") - if product_name is None: - product_name = node_data["subset"] - return get_imageio_node_setting( - node_class="Write", - plugin_name=plugin_names_mapping[identifier], - product_name=product_name - ) - - -def get_dependent_nodes(nodes): - """Get all dependent nodes connected to the list of nodes. - - Looking for connections outside of the nodes in incoming argument. - - Arguments: - nodes (list): list of nuke.Node objects - - Returns: - connections_in: dictionary of nodes and its dependencies - connections_out: dictionary of nodes and its dependency - """ - - connections_in = dict() - connections_out = dict() - node_names = [n.name() for n in nodes] - for node in nodes: - inputs = node.dependencies() - outputs = node.dependent() - # collect all inputs outside - test_in = [(i, n) for i, n in enumerate(inputs) - if n.name() not in node_names] - if test_in: - connections_in.update({ - node: test_in - }) - # collect all outputs outside - test_out = [i for i in outputs if i.name() not in node_names] - if test_out: - # only one dependent node is allowed - connections_out.update({ - node: test_out[-1] - }) - - return connections_in, connections_out - - -def update_node_graph(): - # Resetting frame will update knob values - try: - root_node_lock = nuke.root()["lock_range"].value() - nuke.root()["lock_range"].setValue(not root_node_lock) - nuke.root()["lock_range"].setValue(root_node_lock) - - current_frame = nuke.frame() - nuke.frame(1) - nuke.frame(int(current_frame)) - except Exception as error: - log.warning(error) - - -def find_free_space_to_paste_nodes( - nodes, - group=nuke.root(), - direction="right", - offset=300 -): - """ - For getting coordinates in DAG (node graph) for placing new nodes - - Arguments: - nodes (list): list of nuke.Node objects - group (nuke.Node) [optional]: object in which context it is - direction (str) [optional]: where we want it to be placed - [left, right, top, bottom] - offset (int) [optional]: what offset it is from rest of nodes - - Returns: - xpos (int): x coordinace in DAG - ypos (int): y coordinace in DAG - """ - if len(nodes) == 0: - return 0, 0 - - group_xpos = list() - group_ypos = list() - - # get local coordinates of all nodes - nodes_xpos = [n.xpos() for n in nodes] + \ - [n.xpos() + n.screenWidth() for n in nodes] - - nodes_ypos = [n.ypos() for n in nodes] + \ - [n.ypos() + n.screenHeight() for n in nodes] - - # get complete screen size of all nodes to be placed in - nodes_screen_width = max(nodes_xpos) - min(nodes_xpos) - nodes_screen_heigth = max(nodes_ypos) - min(nodes_ypos) - - # get screen size (r,l,t,b) of all nodes in `group` - with group: - group_xpos = [n.xpos() for n in nuke.allNodes() if n not in nodes] + \ - [n.xpos() + n.screenWidth() for n in nuke.allNodes() - if n not in nodes] - group_ypos = [n.ypos() for n in nuke.allNodes() if n not in nodes] + \ - [n.ypos() + n.screenHeight() for n in nuke.allNodes() - if n not in nodes] - - # calc output left - if direction in "left": - xpos = min(group_xpos) - abs(nodes_screen_width) - abs(offset) - ypos = min(group_ypos) - return xpos, ypos - # calc output right - if direction in "right": - xpos = max(group_xpos) + abs(offset) - ypos = min(group_ypos) - return xpos, ypos - # calc output top - if direction in "top": - xpos = min(group_xpos) - ypos = min(group_ypos) - abs(nodes_screen_heigth) - abs(offset) - return xpos, ypos - # calc output bottom - if direction in "bottom": - xpos = min(group_xpos) - ypos = max(group_ypos) + abs(offset) - return xpos, ypos - - -@contextlib.contextmanager -def maintained_selection(exclude_nodes=None): - """Maintain selection during context - - Maintain selection during context and unselect - all nodes after context is done. - - Arguments: - exclude_nodes (list[nuke.Node]): list of nodes to be unselected - before context is done - - Example: - >>> with maintained_selection(): - ... node["selected"].setValue(True) - >>> print(node["selected"].value()) - False - """ - if exclude_nodes: - for node in exclude_nodes: - node["selected"].setValue(False) - - previous_selection = nuke.selectedNodes() - - try: - yield - finally: - # unselect all selection in case there is some - reset_selection() - - # and select all previously selected nodes - if previous_selection: - select_nodes(previous_selection) - - -@contextlib.contextmanager -def swap_node_with_dependency(old_node, new_node): - """ Swap node with dependency - - Swap node with dependency and reconnect all inputs and outputs. - It removes old node. - - Arguments: - old_node (nuke.Node): node to be replaced - new_node (nuke.Node): node to replace with - - Example: - >>> old_node_name = old_node["name"].value() - >>> print(old_node_name) - old_node_name_01 - >>> with swap_node_with_dependency(old_node, new_node) as node_name: - ... new_node["name"].setValue(node_name) - >>> print(new_node["name"].value()) - old_node_name_01 - """ - # preserve position - xpos, ypos = old_node.xpos(), old_node.ypos() - # preserve selection after all is done - outputs = get_node_outputs(old_node) - inputs = old_node.dependencies() - node_name = old_node["name"].value() - - try: - nuke.delete(old_node) - - yield node_name - finally: - - # Reconnect inputs - for i, node in enumerate(inputs): - new_node.setInput(i, node) - # Reconnect outputs - if outputs: - for n, pipes in outputs.items(): - for i in pipes: - n.setInput(i, new_node) - # return to original position - new_node.setXYpos(xpos, ypos) - - -def reset_selection(): - """Deselect all selected nodes""" - for node in nuke.selectedNodes(): - node["selected"].setValue(False) - - -def select_nodes(nodes): - """Selects all inputted nodes - - Arguments: - nodes (Union[list, tuple, set]): nuke nodes to be selected - """ - assert isinstance(nodes, (list, tuple, set)), \ - "nodes has to be list, tuple or set" - - for node in nodes: - node["selected"].setValue(True) - - -def launch_workfiles_app(): - """Show workfiles tool on nuke launch. - - Trigger to show workfiles tool on application launch. Can be executed only - once all other calls are ignored. - - Workfiles tool show is deferred after application initialization using - QTimer. - """ - - if Context.workfiles_launched: - return - - Context.workfiles_launched = True - - # get all important settings - open_at_start = env_value_to_bool( - env_key="AYON_WORKFILE_TOOL_ON_START", - default=None) - - # return if none is defined - if not open_at_start: - return - - # Show workfiles tool using timer - # - this will be probably triggered during initialization in that case - # the application is not be able to show uis so it must be - # deferred using timer - # - timer should be processed when initialization ends - # When applications starts to process events. - timer = QtCore.QTimer() - timer.timeout.connect(_launch_workfile_app) - timer.setInterval(100) - Context.workfiles_tool_timer = timer - timer.start() - - -def _launch_workfile_app(): - # Safeguard to not show window when application is still starting up - # or is already closing down. - closing_down = QtWidgets.QApplication.closingDown() - starting_up = QtWidgets.QApplication.startingUp() - - # Stop the timer if application finished start up of is closing down - if closing_down or not starting_up: - Context.workfiles_tool_timer.stop() - Context.workfiles_tool_timer = None - - # Skip if application is starting up or closing down - if starting_up or closing_down: - return - - # Make sure on top is enabled on first show so the window is not hidden - # under main nuke window - # - this happened on Centos 7 and it is because the focus of nuke - # changes to the main window after showing because of initialization - # which moves workfiles tool under it - host_tools.show_workfiles(parent=None, on_top=True) - - -@deprecated("ayon_nuke.api.lib.start_workfile_template_builder") -def process_workfile_builder(): - """ [DEPRECATED] Process workfile builder on nuke start - - This function is deprecated and will be removed in future versions. - Use settings for `project_settings/nuke/templated_workfile_build` which are - supported by api `start_workfile_template_builder()`. - """ - - # to avoid looping of the callback, remove it! - nuke.removeOnCreate(process_workfile_builder, nodeClass="Root") - - # get state from settings - project_settings = get_current_project_settings() - workfile_builder = project_settings["nuke"].get( - "workfile_builder", {}) - - # get settings - create_fv_on = workfile_builder.get("create_first_version") or None - builder_on = workfile_builder.get("builder_on_start") or None - - last_workfile_path = os.environ.get("AYON_LAST_WORKFILE") - - # generate first version in file not existing and feature is enabled - if create_fv_on and not os.path.exists(last_workfile_path): - # get custom template path if any - custom_template_path = get_current_context_custom_workfile_template( - project_settings=project_settings - ) - - # if custom template is defined - if custom_template_path: - log.info("Adding nodes from `{}`...".format( - custom_template_path - )) - try: - # import nodes into current script - nuke.nodePaste(custom_template_path) - except RuntimeError: - raise RuntimeError(( - "Template defined for project: {} is not working. " - "Talk to your manager for an advise").format( - custom_template_path)) - - # if builder at start is defined - if builder_on: - log.info("Building nodes from presets...") - # build nodes by defined presets - BuildWorkfile().process() - - log.info("Saving script as version `{}`...".format( - last_workfile_path - )) - # safe file as version - save_file(last_workfile_path) - return - - -def start_workfile_template_builder(): - from .workfile_template_builder import ( - build_workfile_template - ) - - # remove callback since it would be duplicating the workfile - nuke.removeOnCreate(start_workfile_template_builder, nodeClass="Root") - - # to avoid looping of the callback, remove it! - log.info("Starting workfile template builder...") - try: - build_workfile_template(workfile_creation_enabled=True) - except TemplateProfileNotFound: - log.warning("Template profile not found. Skipping...") - - -def add_scripts_menu(): - try: - from scriptsmenu import launchfornuke - except ImportError: - log.warning( - "Skipping studio.menu install, because " - "'scriptsmenu' module seems unavailable." - ) - return - - # load configuration of custom menu - project_name = get_current_project_name() - project_settings = get_project_settings(project_name) - config = project_settings["nuke"]["scriptsmenu"]["definition"] - _menu = project_settings["nuke"]["scriptsmenu"]["name"] - - if not config: - log.warning("Skipping studio menu, no definition found.") - return - - # run the launcher for Maya menu - studio_menu = launchfornuke.main(title=_menu.title()) - - # apply configuration - studio_menu.build_from_configuration(studio_menu, config) - - -def add_scripts_gizmo(): - - # load configuration of custom menu - project_name = get_current_project_name() - project_settings = get_project_settings(project_name) - platform_name = platform.system().lower() - - for gizmo_settings in project_settings["nuke"]["gizmo"]: - gizmo_list_definition = gizmo_settings["gizmo_definition"] - toolbar_name = gizmo_settings["toolbar_menu_name"] - # gizmo_toolbar_path = gizmo_settings["gizmo_toolbar_path"] - gizmo_source_dir = gizmo_settings.get( - "gizmo_source_dir", {}).get(platform_name) - toolbar_icon_path = gizmo_settings.get( - "toolbar_icon_path", {}).get(platform_name) - - if not gizmo_source_dir: - log.debug("Skipping studio gizmo `{}`, " - "no gizmo path found.".format(toolbar_name) - ) - return - - if not gizmo_list_definition: - log.debug("Skipping studio gizmo `{}`, " - "no definition found.".format(toolbar_name) - ) - return - - if toolbar_icon_path: - try: - toolbar_icon_path = toolbar_icon_path.format(**os.environ) - except KeyError as e: - log.error( - "This environment variable doesn't exist: {}".format(e) - ) - - existing_gizmo_path = [] - for source_dir in gizmo_source_dir: - try: - resolve_source_dir = source_dir.format(**os.environ) - except KeyError as e: - log.error( - "This environment variable doesn't exist: {}".format(e) - ) - continue - if not os.path.exists(resolve_source_dir): - log.warning( - "The source of gizmo `{}` does not exists".format( - resolve_source_dir - ) - ) - continue - existing_gizmo_path.append(resolve_source_dir) - - # run the launcher for Nuke toolbar - toolbar_menu = gizmo_menu.GizmoMenu( - title=toolbar_name, - icon=toolbar_icon_path - ) - - # apply configuration - toolbar_menu.add_gizmo_path(existing_gizmo_path) - toolbar_menu.build_from_configuration(gizmo_list_definition) - - -class NukeDirmap(HostDirmap): - def __init__(self, file_name, *args, **kwargs): - """ - Args: - file_name (str): full path of referenced file from workfiles - *args (tuple): Positional arguments for 'HostDirmap' class - **kwargs (dict): Keyword arguments for 'HostDirmap' class - """ - - self.file_name = file_name - super(NukeDirmap, self).__init__(*args, **kwargs) - - def on_enable_dirmap(self): - pass - - def dirmap_routine(self, source_path, destination_path): - source_path = source_path.lower().replace(os.sep, '/') - destination_path = destination_path.lower().replace(os.sep, '/') - if platform.system().lower() == "windows": - self.file_name = self.file_name.lower().replace( - source_path, destination_path) - else: - self.file_name = self.file_name.replace( - source_path, destination_path) - - -class DirmapCache: - """Caching class to get settings and sitesync easily and only once.""" - _project_name = None - _project_settings = None - _sitesync_addon_discovered = False - _sitesync_addon = None - _mapping = None - - @classmethod - def project_name(cls): - if cls._project_name is None: - cls._project_name = os.getenv("AYON_PROJECT_NAME") - return cls._project_name - - @classmethod - def project_settings(cls): - if cls._project_settings is None: - cls._project_settings = get_project_settings(cls.project_name()) - return cls._project_settings - - @classmethod - def sitesync_addon(cls): - if not cls._sitesync_addon_discovered: - cls._sitesync_addon_discovered = True - cls._sitesync_addon = AddonsManager().get("sitesync") - return cls._sitesync_addon - - @classmethod - def mapping(cls): - return cls._mapping - - @classmethod - def set_mapping(cls, mapping): - cls._mapping = mapping - - -def dirmap_file_name_filter(file_name): - """Nuke callback function with single full path argument. - - Checks project settings for potential mapping from source to dest. - """ - - dirmap_processor = NukeDirmap( - file_name, - "nuke", - DirmapCache.project_name(), - DirmapCache.project_settings(), - DirmapCache.sitesync_addon(), - ) - if not DirmapCache.mapping(): - DirmapCache.set_mapping(dirmap_processor.get_mappings()) - - dirmap_processor.process_dirmap(DirmapCache.mapping()) - if os.path.exists(dirmap_processor.file_name): - return dirmap_processor.file_name - return file_name - - -@contextlib.contextmanager -def node_tempfile(): - """Create a temp file where node is pasted during duplication. - - This is to avoid using clipboard for node duplication. - """ - - tmp_file = tempfile.NamedTemporaryFile( - mode="w", prefix="openpype_nuke_temp_", suffix=".nk", delete=False - ) - tmp_file.close() - node_tempfile_path = tmp_file.name - - try: - # Yield the path where node can be copied - yield node_tempfile_path - - finally: - # Remove the file at the end - os.remove(node_tempfile_path) - - -def duplicate_node(node): - reset_selection() - - # select required node for duplication - node.setSelected(True) - - with node_tempfile() as filepath: - # copy selected to temp filepath - nuke.nodeCopy(filepath) - - # reset selection - reset_selection() - - # paste node and selection is on it only - dupli_node = nuke.nodePaste(filepath) - - # reset selection - reset_selection() - - return dupli_node - - -def get_group_io_nodes(nodes): - """Get the input and the output of a group of nodes.""" - - if not nodes: - raise ValueError("there is no nodes in the list") - - input_node = None - output_node = None - - if len(nodes) == 1: - input_node = output_node = nodes[0] - - else: - for node in nodes: - if "Input" in node.name(): - input_node = node - - if "Output" in node.name(): - output_node = node - - if input_node is not None and output_node is not None: - break - - if input_node is None: - log.warning("No Input found") - - if output_node is None: - log.warning("No Output found") - - return input_node, output_node - - -def get_extreme_positions(nodes): - """Get the 4 numbers that represent the box of a group of nodes.""" - - if not nodes: - raise ValueError("there is no nodes in the list") - - nodes_xpos = [n.xpos() for n in nodes] + \ - [n.xpos() + n.screenWidth() for n in nodes] - - nodes_ypos = [n.ypos() for n in nodes] + \ - [n.ypos() + n.screenHeight() for n in nodes] - - min_x, min_y = (min(nodes_xpos), min(nodes_ypos)) - max_x, max_y = (max(nodes_xpos), max(nodes_ypos)) - return min_x, min_y, max_x, max_y - - -def refresh_node(node): - """Correct a bug caused by the multi-threading of nuke. - - Refresh the node to make sure that it takes the desired attributes. - """ - - x = node.xpos() - y = node.ypos() - nuke.autoplaceSnap(node) - node.setXYpos(x, y) - - -def refresh_nodes(nodes): - for node in nodes: - refresh_node(node) - - -def get_names_from_nodes(nodes): - """Get list of nodes names. - - Args: - nodes(List[nuke.Node]): List of nodes to convert into names. - - Returns: - List[str]: Name of passed nodes. - """ - - return [ - node.name() - for node in nodes - ] - - -def get_nodes_by_names(names): - """Get list of nuke nodes based on their names. - - Args: - names (List[str]): List of node names to be found. - - Returns: - List[nuke.Node]: List of nodes found by name. - """ - - return [ - nuke.toNode(name) - for name in names - ] - - -def get_viewer_config_from_string(input_string): - """Convert string to display and viewer string - - Args: - input_string (str): string with viewer - - Raises: - IndexError: if more then one slash in input string - IndexError: if missing closing bracket - - Returns: - tuple[str]: display, viewer - """ - display = None - viewer = input_string - # check if () or / or \ in name - if "/" in viewer: - split = viewer.split("/") - - # rise if more then one column - if len(split) > 2: - raise IndexError(( - "Viewer Input string is not correct. " - "more then two `/` slashes! {}" - ).format(input_string)) - - viewer = split[1] - display = split[0] - elif "(" in viewer: - pattern = r"([\w\d\s\.\-]+).*[(](.*)[)]" - result_ = re.findall(pattern, viewer) - try: - result_ = result_.pop() - display = str(result_[1]).rstrip() - viewer = str(result_[0]).rstrip() - except IndexError: - raise IndexError(( - "Viewer Input string is not correct. " - "Missing bracket! {}" - ).format(input_string)) - - return (display, viewer) - - -def create_viewer_profile_string(viewer, display=None, path_like=False): - """Convert viewer and display to string - - Args: - viewer (str): viewer name - display (Optional[str]): display name - path_like (Optional[bool]): if True, return path like string - - Returns: - str: viewer config string - """ - if not display: - return viewer - - if path_like: - return "{}/{}".format(display, viewer) - return "{} ({})".format(viewer, display) - - -def get_filenames_without_hash(filename, frame_start, frame_end): - """Get filenames without frame hash - i.e. "renderCompositingMain.baking.0001.exr" - - Args: - filename (str): filename with frame hash - frame_start (str): start of the frame - frame_end (str): end of the frame - - Returns: - list: filename per frame of the sequence - """ - filenames = [] - for frame in range(int(frame_start), (int(frame_end) + 1)): - if "#" in filename: - # use regex to convert #### to {:0>4} - def replace(match): - return "{{:0>{}}}".format(len(match.group())) - filename_without_hashes = re.sub("#+", replace, filename) - new_filename = filename_without_hashes.format(frame) - filenames.append(new_filename) - return filenames - - -def create_camera_node_by_version(): - """Function to create the camera with the latest node class - For Nuke version 14.0 or later, the Camera4 camera node class - would be used - For the version before, the Camera2 camera node class - would be used - Returns: - Node: camera node - """ - nuke_number_version = nuke.NUKE_VERSION_MAJOR - if nuke_number_version >= 14: - return nuke.createNode("Camera4") - else: - return nuke.createNode("Camera2") - - -def link_knobs(knobs, node, group_node): - """Link knobs from inside `group_node`""" - - missing_knobs = [] - for knob in knobs: - if knob in group_node.knobs(): - continue - - if knob not in node.knobs().keys(): - missing_knobs.append(knob) - - link = nuke.Link_Knob("") - link.makeLink(node.name(), knob) - link.setName(knob) - link.setFlag(0x1000) - group_node.addKnob(link) - - if missing_knobs: - raise ValueError( - "Write node exposed knobs missing:\n\n{}\n\nPlease review" - " project settings.".format("\n".join(missing_knobs)) - ) diff --git a/server_addon/nuke/client/ayon_nuke/api/pipeline.py b/server_addon/nuke/client/ayon_nuke/api/pipeline.py deleted file mode 100644 index 2ba430c272..0000000000 --- a/server_addon/nuke/client/ayon_nuke/api/pipeline.py +++ /dev/null @@ -1,641 +0,0 @@ -import nuke - -import os -import importlib -from collections import OrderedDict, defaultdict - -import pyblish.api - -from ayon_core.host import ( - HostBase, - IWorkfileHost, - ILoadHost, - IPublishHost -) -from ayon_core.settings import get_current_project_settings -from ayon_core.lib import register_event_callback, Logger -from ayon_core.pipeline import ( - register_loader_plugin_path, - register_creator_plugin_path, - register_inventory_action_path, - register_workfile_build_plugin_path, - AYON_INSTANCE_ID, - AVALON_INSTANCE_ID, - AVALON_CONTAINER_ID, - get_current_folder_path, - get_current_task_name, - registered_host, -) -from ayon_core.pipeline.workfile import BuildWorkfile -from ayon_core.tools.utils import host_tools -from ayon_nuke import NUKE_ROOT_DIR -from ayon_core.tools.workfile_template_build import open_template_ui - -from .lib import ( - Context, - ROOT_DATA_KNOB, - INSTANCE_DATA_KNOB, - get_main_window, - WorkfileSettings, - start_workfile_template_builder, - launch_workfiles_app, - check_inventory_versions, - set_avalon_knob_data, - read_avalon_data, - on_script_load, - dirmap_file_name_filter, - add_scripts_menu, - add_scripts_gizmo, - get_node_data, - set_node_data, - MENU_LABEL, -) -from .workfile_template_builder import ( - build_workfile_template, - create_placeholder, - update_placeholder, - NukeTemplateBuilder, -) -from .workio import ( - open_file, - save_file, - file_extensions, - has_unsaved_changes, - work_root, - current_file -) -from .constants import ASSIST -from . import push_to_project - -log = Logger.get_logger(__name__) - -PLUGINS_DIR = os.path.join(NUKE_ROOT_DIR, "plugins") -PUBLISH_PATH = os.path.join(PLUGINS_DIR, "publish") -LOAD_PATH = os.path.join(PLUGINS_DIR, "load") -CREATE_PATH = os.path.join(PLUGINS_DIR, "create") -INVENTORY_PATH = os.path.join(PLUGINS_DIR, "inventory") -WORKFILE_BUILD_PATH = os.path.join(PLUGINS_DIR, "workfile_build") - -# registering pyblish gui regarding settings in presets -if os.getenv("PYBLISH_GUI", None): - pyblish.api.register_gui(os.getenv("PYBLISH_GUI", None)) - - -class NukeHost( - HostBase, IWorkfileHost, ILoadHost, IPublishHost -): - name = "nuke" - - def open_workfile(self, filepath): - return open_file(filepath) - - def save_workfile(self, filepath=None): - return save_file(filepath) - - def work_root(self, session): - return work_root(session) - - def get_current_workfile(self): - return current_file() - - def workfile_has_unsaved_changes(self): - return has_unsaved_changes() - - def get_workfile_extensions(self): - return file_extensions() - - def get_containers(self): - return ls() - - def install(self): - """Installing all requirements for Nuke host""" - - pyblish.api.register_host("nuke") - - self.log.info("Registering Nuke plug-ins..") - pyblish.api.register_plugin_path(PUBLISH_PATH) - register_loader_plugin_path(LOAD_PATH) - register_creator_plugin_path(CREATE_PATH) - register_inventory_action_path(INVENTORY_PATH) - register_workfile_build_plugin_path(WORKFILE_BUILD_PATH) - - # Register AYON event for workfiles loading. - register_event_callback("workio.open_file", check_inventory_versions) - register_event_callback("taskChanged", change_context_label) - - _install_menu() - - # add script menu - add_scripts_menu() - add_scripts_gizmo() - - add_nuke_callbacks() - - launch_workfiles_app() - - def get_context_data(self): - root_node = nuke.root() - return get_node_data(root_node, ROOT_DATA_KNOB) - - def update_context_data(self, data, changes): - root_node = nuke.root() - set_node_data(root_node, ROOT_DATA_KNOB, data) - - -def add_nuke_callbacks(): - """ Adding all available nuke callbacks - """ - nuke_settings = get_current_project_settings()["nuke"] - workfile_settings = WorkfileSettings() - - # Set context settings. - nuke.addOnCreate( - workfile_settings.set_context_settings, nodeClass="Root") - - # adding favorites to file browser - nuke.addOnCreate(workfile_settings.set_favorites, nodeClass="Root") - - # template builder callbacks - nuke.addOnCreate(start_workfile_template_builder, nodeClass="Root") - - # fix ffmpeg settings on script - nuke.addOnScriptLoad(on_script_load) - - # set checker for last versions on loaded containers - nuke.addOnScriptLoad(check_inventory_versions) - nuke.addOnScriptSave(check_inventory_versions) - - # set apply all workfile settings on script load and save - nuke.addOnScriptLoad(WorkfileSettings().set_context_settings) - - if nuke_settings["dirmap"]["enabled"]: - log.info("Added Nuke's dir-mapping callback ...") - # Add dirmap for file paths. - nuke.addFilenameFilter(dirmap_file_name_filter) - - log.info("Added Nuke callbacks ...") - - -def reload_config(): - """Attempt to reload pipeline at run-time. - - CAUTION: This is primarily for development and debugging purposes. - - """ - - for module in ( - "ayon_nuke.api.actions", - "ayon_nuke.api.menu", - "ayon_nuke.api.plugin", - "ayon_nuke.api.lib", - ): - log.info("Reloading module: {}...".format(module)) - - module = importlib.import_module(module) - - try: - importlib.reload(module) - except AttributeError as e: - from importlib import reload - log.warning("Cannot reload module: {}".format(e)) - reload(module) - - -def _show_workfiles(): - # Make sure parent is not set - # - this makes Workfiles tool as separated window which - # avoid issues with reopening - # - it is possible to explicitly change on top flag of the tool - host_tools.show_workfiles(parent=None, on_top=False) - - -def get_context_label(): - return "{0}, {1}".format( - get_current_folder_path(), - get_current_task_name() - ) - - -def _install_menu(): - """Install AYON menu into Nuke's main menu bar.""" - - # uninstall original AYON menu - main_window = get_main_window() - menubar = nuke.menu("Nuke") - menu = menubar.addMenu(MENU_LABEL) - - if not ASSIST: - label = get_context_label() - context_action_item = menu.addCommand("Context") - context_action_item.setEnabled(False) - - Context.context_action_item = context_action_item - - context_action = context_action_item.action() - context_action.setText(label) - - # add separator after context label - menu.addSeparator() - - menu.addCommand( - "Work Files...", - _show_workfiles - ) - - menu.addSeparator() - if not ASSIST: - # only add parent if nuke version is 14 or higher - # known issue with no solution yet - menu.addCommand( - "Create...", - lambda: host_tools.show_publisher( - parent=main_window, - tab="create" - ) - ) - # only add parent if nuke version is 14 or higher - # known issue with no solution yet - menu.addCommand( - "Publish...", - lambda: host_tools.show_publisher( - parent=main_window, - tab="publish" - ) - ) - - menu.addCommand( - "Load...", - lambda: host_tools.show_loader( - parent=main_window, - use_context=True - ) - ) - menu.addCommand( - "Manage...", - lambda: host_tools.show_scene_inventory(parent=main_window) - ) - menu.addSeparator() - menu.addCommand( - "Library...", - lambda: host_tools.show_library_loader( - parent=main_window - ) - ) - menu.addSeparator() - menu.addCommand( - "Set Resolution", - lambda: WorkfileSettings().reset_resolution() - ) - menu.addCommand( - "Set Frame Range", - lambda: WorkfileSettings().reset_frame_range_handles() - ) - menu.addCommand( - "Set Colorspace", - lambda: WorkfileSettings().set_colorspace() - ) - menu.addCommand( - "Apply All Settings", - lambda: WorkfileSettings().set_context_settings() - ) - - menu.addSeparator() - menu.addCommand( - "Build Workfile", - lambda: BuildWorkfile().process() - ) - - menu_template = menu.addMenu("Template Builder") - menu_template.addCommand( - "Build Workfile from template", - lambda: build_workfile_template() - ) - - if not ASSIST: - menu_template.addSeparator() - menu_template.addCommand( - "Open template", - lambda: open_template_ui( - NukeTemplateBuilder(registered_host()), get_main_window() - ) - ) - menu_template.addCommand( - "Create Place Holder", - lambda: create_placeholder() - ) - menu_template.addCommand( - "Update Place Holder", - lambda: update_placeholder() - ) - - menu.addCommand( - "Push to Project", - lambda: push_to_project.main() - ) - - menu.addSeparator() - menu.addCommand( - "Experimental tools...", - lambda: host_tools.show_experimental_tools_dialog(parent=main_window) - ) - menu.addSeparator() - # add reload pipeline only in debug mode - if bool(os.getenv("NUKE_DEBUG")): - menu.addSeparator() - menu.addCommand("Reload Pipeline", reload_config) - - # adding shortcuts - add_shortcuts_from_presets() - - -def change_context_label(): - if ASSIST: - return - - context_action_item = Context.context_action_item - if context_action_item is None: - return - context_action = context_action_item.action() - - old_label = context_action.text() - new_label = get_context_label() - - context_action.setText(new_label) - - log.info("Task label changed from `{}` to `{}`".format( - old_label, new_label)) - - -def add_shortcuts_from_presets(): - menubar = nuke.menu("Nuke") - nuke_presets = get_current_project_settings()["nuke"]["general"] - - if nuke_presets.get("menu"): - menu_label_mapping = { - "create": "Create...", - "manage": "Manage...", - "load": "Load...", - "build_workfile": "Build Workfile", - "publish": "Publish..." - } - - for command_name, shortcut_str in nuke_presets.get("menu").items(): - log.info("menu_name `{}` | menu_label `{}`".format( - command_name, MENU_LABEL - )) - log.info("Adding Shortcut `{}` to `{}`".format( - shortcut_str, command_name - )) - try: - menu = menubar.findItem(MENU_LABEL) - item_label = menu_label_mapping[command_name] - menuitem = menu.findItem(item_label) - menuitem.setShortcut(shortcut_str) - except (AttributeError, KeyError) as e: - log.error(e) - - -def containerise(node, - name, - namespace, - context, - loader=None, - data=None): - """Bundle `node` into an assembly and imprint it with metadata - - Containerisation enables a tracking of version, author and origin - for loaded assets. - - Arguments: - node (nuke.Node): Nuke's node object to imprint as container - name (str): Name of resulting assembly - namespace (str): Namespace under which to host container - context (dict): Asset information - loader (str, optional): Name of node used to produce this container. - - Returns: - node (nuke.Node): containerised nuke's node object - - """ - data = OrderedDict( - [ - ("schema", "openpype:container-2.0"), - ("id", AVALON_CONTAINER_ID), - ("name", name), - ("namespace", namespace), - ("loader", str(loader)), - ("representation", context["representation"]["id"]), - ], - - **data or dict() - ) - - set_avalon_knob_data(node, data) - - # set tab to first native - node.setTab(0) - - return node - - -def parse_container(node): - """Returns containerised data of a node - - Reads the imprinted data from `containerise`. - - Arguments: - node (nuke.Node): Nuke's node object to read imprinted data - - Returns: - dict: The container schema data for this container node. - - """ - data = read_avalon_data(node) - - # If not all required data return the empty container - required = ["schema", "id", "name", - "namespace", "loader", "representation"] - if not all(key in data for key in required): - return - - # Store the node's name - data.update({ - "objectName": node.fullName(), - "node": node, - }) - - return data - - -def update_container(node, keys=None): - """Returns node with updateted containder data - - Arguments: - node (nuke.Node): The node in Nuke to imprint as container, - keys (dict, optional): data which should be updated - - Returns: - node (nuke.Node): nuke node with updated container data - - Raises: - TypeError on given an invalid container node - - """ - keys = keys or dict() - - container = parse_container(node) - if not container: - raise TypeError("Not a valid container node.") - - container.update(keys) - node = set_avalon_knob_data(node, container) - - return node - - -def ls(): - """List available containers. - - This function is used by the Container Manager in Nuke. You'll - need to implement a for-loop that then *yields* one Container at - a time. - """ - all_nodes = nuke.allNodes(recurseGroups=False) - - nodes = [n for n in all_nodes] - - for n in nodes: - container = parse_container(n) - if container: - yield container - - -def list_instances(creator_id=None): - """List all created instances to publish from current workfile. - - For SubsetManager - - Args: - creator_id (Optional[str]): creator identifier - - Returns: - (list) of dictionaries matching instances format - """ - instances_by_order = defaultdict(list) - product_instances = [] - instance_ids = set() - - for node in nuke.allNodes(recurseGroups=True): - - if node.Class() in ["Viewer", "Dot"]: - continue - - try: - if node["disable"].value(): - continue - except NameError: - # pass if disable knob doesn't exist - pass - - # get data from avalon knob - instance_data = get_node_data( - node, INSTANCE_DATA_KNOB) - - if not instance_data: - continue - - if instance_data["id"] not in { - AYON_INSTANCE_ID, AVALON_INSTANCE_ID - }: - continue - - if creator_id and instance_data["creator_identifier"] != creator_id: - continue - - instance_id = instance_data.get("instance_id") - if not instance_id: - pass - elif instance_id in instance_ids: - instance_data.pop("instance_id") - else: - instance_ids.add(instance_id) - - # node name could change, so update product name data - _update_product_name_data(instance_data, node) - - if "render_order" not in node.knobs(): - product_instances.append((node, instance_data)) - continue - - order = int(node["render_order"].value()) - instances_by_order[order].append((node, instance_data)) - - # Sort instances based on order attribute or product name. - # TODO: remove in future Publisher enhanced with sorting - ordered_instances = [] - for key in sorted(instances_by_order.keys()): - instances_by_product = defaultdict(list) - for node, data_ in instances_by_order[key]: - product_name = data_.get("productName") - if product_name is None: - product_name = data_.get("subset") - instances_by_product[product_name].append((node, data_)) - for subkey in sorted(instances_by_product.keys()): - ordered_instances.extend(instances_by_product[subkey]) - - instances_by_product = defaultdict(list) - for node, data_ in product_instances: - product_name = data_.get("productName") - if product_name is None: - product_name = data_.get("subset") - instances_by_product[product_name].append((node, data_)) - for key in sorted(instances_by_product.keys()): - ordered_instances.extend(instances_by_product[key]) - - return ordered_instances - - -def _update_product_name_data(instance_data, node): - """Update product name data in instance data. - - Args: - instance_data (dict): instance creator data - node (nuke.Node): nuke node - """ - # make sure node name is product name - old_product_name = instance_data.get("productName") - if old_product_name is None: - old_product_name = instance_data.get("subset") - old_variant = instance_data["variant"] - product_name_root = old_product_name.replace(old_variant, "") - - new_product_name = node.name() - new_variant = new_product_name.replace(product_name_root, "") - - instance_data["productName"] = new_product_name - instance_data["variant"] = new_variant - - -def remove_instance(instance): - """Remove instance from current workfile metadata. - - For SubsetManager - - Args: - instance (dict): instance representation from subsetmanager model - """ - instance_node = instance.transient_data["node"] - instance_knob = instance_node.knobs()[INSTANCE_DATA_KNOB] - instance_node.removeKnob(instance_knob) - nuke.delete(instance_node) - - -def select_instance(instance): - """ - Select instance in Node View - - Args: - instance (dict): instance representation from subsetmanager model - """ - instance_node = instance.transient_data["node"] - instance_node["selected"].setValue(True) diff --git a/server_addon/nuke/client/ayon_nuke/api/plugin.py b/server_addon/nuke/client/ayon_nuke/api/plugin.py deleted file mode 100644 index fc30f328c7..0000000000 --- a/server_addon/nuke/client/ayon_nuke/api/plugin.py +++ /dev/null @@ -1,1227 +0,0 @@ -import nuke -import re -import os -import sys -import six -import random -import string -from collections import defaultdict - -from ayon_core.settings import get_current_project_settings -from ayon_core.lib import ( - BoolDef, - EnumDef -) -from ayon_core.lib import StringTemplate -from ayon_core.pipeline import ( - LoaderPlugin, - CreatorError, - Creator as NewCreator, - CreatedInstance, - get_current_task_name, - AYON_INSTANCE_ID, - AVALON_INSTANCE_ID, -) -from ayon_core.pipeline.colorspace import ( - get_display_view_colorspace_name, - get_colorspace_settings_from_publish_context, - set_colorspace_data_to_representation -) -from ayon_core.lib.transcoding import ( - VIDEO_EXTENSIONS -) -from .lib import ( - INSTANCE_DATA_KNOB, - Knobby, - maintained_selection, - get_avalon_knob_data, - set_node_knobs_from_settings, - set_node_data, - get_node_data, - get_view_process_node, - get_filenames_without_hash, - link_knobs -) -from .pipeline import ( - list_instances, - remove_instance -) - - -def _collect_and_cache_nodes(creator): - key = "openpype.nuke.nodes" - if key not in creator.collection_shared_data: - instances_by_identifier = defaultdict(list) - for item in list_instances(): - _, instance_data = item - identifier = instance_data["creator_identifier"] - instances_by_identifier[identifier].append(item) - creator.collection_shared_data[key] = instances_by_identifier - return creator.collection_shared_data[key] - - -class NukeCreatorError(CreatorError): - pass - - -class NukeCreator(NewCreator): - selected_nodes = [] - - def pass_pre_attributes_to_instance( - self, - instance_data, - pre_create_data, - keys=None - ): - if not keys: - keys = pre_create_data.keys() - - creator_attrs = instance_data["creator_attributes"] = {} - for pass_key in keys: - creator_attrs[pass_key] = pre_create_data[pass_key] - - def check_existing_product(self, product_name): - """Make sure product name is unique. - - It search within all nodes recursively - and checks if product name is found in - any node having instance data knob. - - Arguments: - product_name (str): Product name - """ - - for node in nuke.allNodes(recurseGroups=True): - # make sure testing node is having instance knob - if INSTANCE_DATA_KNOB not in node.knobs().keys(): - continue - node_data = get_node_data(node, INSTANCE_DATA_KNOB) - - if not node_data: - # a node has no instance data - continue - - # test if product name is matching - if node_data.get("productType") == product_name: - raise NukeCreatorError( - ( - "A publish instance for '{}' already exists " - "in nodes! Please change the variant " - "name to ensure unique output." - ).format(product_name) - ) - - def create_instance_node( - self, - node_name, - knobs=None, - parent=None, - node_type=None - ): - """Create node representing instance. - - Arguments: - node_name (str): Name of the new node. - knobs (OrderedDict): node knobs name and values - parent (str): Name of the parent node. - node_type (str, optional): Nuke node Class. - - Returns: - nuke.Node: Newly created instance node. - - """ - node_type = node_type or "NoOp" - - node_knobs = knobs or {} - - # set parent node - parent_node = nuke.root() - if parent: - parent_node = nuke.toNode(parent) - - try: - with parent_node: - created_node = nuke.createNode(node_type) - created_node["name"].setValue(node_name) - - for key, values in node_knobs.items(): - if key in created_node.knobs(): - created_node["key"].setValue(values) - except Exception as _err: - raise NukeCreatorError("Creating have failed: {}".format(_err)) - - return created_node - - def set_selected_nodes(self, pre_create_data): - if pre_create_data.get("use_selection"): - self.selected_nodes = nuke.selectedNodes() - if self.selected_nodes == []: - raise NukeCreatorError("Creator error: No active selection") - else: - self.selected_nodes = [] - - def create(self, product_name, instance_data, pre_create_data): - - # make sure selected nodes are added - self.set_selected_nodes(pre_create_data) - - # make sure product name is unique - self.check_existing_product(product_name) - - try: - instance_node = self.create_instance_node( - product_name, - node_type=instance_data.pop("node_type", None) - ) - instance = CreatedInstance( - self.product_type, - product_name, - instance_data, - self - ) - - instance.transient_data["node"] = instance_node - - self._add_instance_to_context(instance) - - set_node_data( - instance_node, INSTANCE_DATA_KNOB, instance.data_to_store()) - - return instance - - except Exception as er: - six.reraise( - NukeCreatorError, - NukeCreatorError("Creator error: {}".format(er)), - sys.exc_info()[2]) - - def collect_instances(self): - cached_instances = _collect_and_cache_nodes(self) - attr_def_keys = { - attr_def.key - for attr_def in self.get_instance_attr_defs() - } - attr_def_keys.discard(None) - - for (node, data) in cached_instances[self.identifier]: - created_instance = CreatedInstance.from_existing( - data, self - ) - created_instance.transient_data["node"] = node - self._add_instance_to_context(created_instance) - - for key in ( - set(created_instance["creator_attributes"].keys()) - - attr_def_keys - ): - created_instance["creator_attributes"].pop(key) - - def update_instances(self, update_list): - for created_inst, changes in update_list: - instance_node = created_inst.transient_data["node"] - - # update instance node name if product name changed - if "productName" in changes.changed_keys: - instance_node["name"].setValue( - changes["productName"].new_value - ) - - # in case node is not existing anymore (user erased it manually) - try: - instance_node.fullName() - except ValueError: - self.remove_instances([created_inst]) - continue - - set_node_data( - instance_node, - INSTANCE_DATA_KNOB, - created_inst.data_to_store() - ) - - def remove_instances(self, instances): - for instance in instances: - remove_instance(instance) - self._remove_instance_from_context(instance) - - def get_pre_create_attr_defs(self): - return [ - BoolDef( - "use_selection", - default=not self.create_context.headless, - label="Use selection" - ) - ] - - def get_creator_settings(self, project_settings, settings_key=None): - if not settings_key: - settings_key = self.__class__.__name__ - return project_settings["nuke"]["create"][settings_key] - - -class NukeWriteCreator(NukeCreator): - """Add Publishable Write node""" - - identifier = "create_write" - label = "Create Write" - product_type = "write" - icon = "sign-out" - - def get_linked_knobs(self): - linked_knobs = [] - if "channels" in self.instance_attributes: - linked_knobs.append("channels") - if "ordered" in self.instance_attributes: - linked_knobs.append("render_order") - if "use_range_limit" in self.instance_attributes: - linked_knobs.extend(["___", "first", "last", "use_limit"]) - - return linked_knobs - - def integrate_links(self, node, outputs=True): - # skip if no selection - if not self.selected_node: - return - - # collect dependencies - input_nodes = [self.selected_node] - dependent_nodes = self.selected_node.dependent() if outputs else [] - - # relinking to collected connections - for i, input in enumerate(input_nodes): - node.setInput(i, input) - - # make it nicer in graph - node.autoplace() - - # relink also dependent nodes - for dep_nodes in dependent_nodes: - dep_nodes.setInput(0, node) - - def set_selected_nodes(self, pre_create_data): - if pre_create_data.get("use_selection"): - selected_nodes = nuke.selectedNodes() - if selected_nodes == []: - raise NukeCreatorError("Creator error: No active selection") - elif len(selected_nodes) > 1: - NukeCreatorError("Creator error: Select only one camera node") - self.selected_node = selected_nodes[0] - else: - self.selected_node = None - - def get_pre_create_attr_defs(self): - attr_defs = [ - BoolDef("use_selection", label="Use selection"), - self._get_render_target_enum() - ] - return attr_defs - - def get_instance_attr_defs(self): - attr_defs = [ - self._get_render_target_enum(), - ] - # add reviewable attribute - if "reviewable" in self.instance_attributes: - attr_defs.append(self._get_reviewable_bool()) - - return attr_defs - - def _get_render_target_enum(self): - rendering_targets = { - "local": "Local machine rendering", - "frames": "Use existing frames" - } - if ("farm_rendering" in self.instance_attributes): - rendering_targets["frames_farm"] = "Use existing frames - farm" - rendering_targets["farm"] = "Farm rendering" - - return EnumDef( - "render_target", - items=rendering_targets, - label="Render target" - ) - - def _get_reviewable_bool(self): - return BoolDef( - "review", - default=True, - label="Review" - ) - - def create(self, product_name, instance_data, pre_create_data): - # make sure selected nodes are added - self.set_selected_nodes(pre_create_data) - - # make sure product name is unique - self.check_existing_product(product_name) - - instance_node = self.create_instance_node( - product_name, - instance_data - ) - - try: - instance = CreatedInstance( - self.product_type, - product_name, - instance_data, - self - ) - - instance.transient_data["node"] = instance_node - - self._add_instance_to_context(instance) - - set_node_data( - instance_node, INSTANCE_DATA_KNOB, instance.data_to_store()) - - return instance - - except Exception as er: - six.reraise( - NukeCreatorError, - NukeCreatorError("Creator error: {}".format(er)), - sys.exc_info()[2] - ) - - def apply_settings(self, project_settings): - """Method called on initialization of plugin to apply settings.""" - - # plugin settings - plugin_settings = self.get_creator_settings(project_settings) - temp_rendering_path_template = ( - plugin_settings.get("temp_rendering_path_template") - or self.temp_rendering_path_template - ) - # TODO remove template key replacements - temp_rendering_path_template = ( - temp_rendering_path_template - .replace("{product[name]}", "{subset}") - .replace("{product[type]}", "{family}") - .replace("{task[name]}", "{task}") - .replace("{folder[name]}", "{asset}") - ) - # individual attributes - self.instance_attributes = plugin_settings.get( - "instance_attributes") or self.instance_attributes - self.prenodes = plugin_settings["prenodes"] - self.default_variants = plugin_settings.get( - "default_variants") or self.default_variants - self.temp_rendering_path_template = temp_rendering_path_template - - -def get_instance_group_node_childs(instance): - """Return list of instance group node children - - Args: - instance (pyblish.Instance): pyblish instance - - Returns: - list: [nuke.Node] - """ - node = instance.data["transientData"]["node"] - - if node.Class() != "Group": - return - - # collect child nodes - child_nodes = [] - # iterate all nodes - for node in nuke.allNodes(group=node): - # add contained nodes to instance's node list - child_nodes.append(node) - - return child_nodes - - -def get_colorspace_from_node(node): - # Add version data to instance - colorspace = node["colorspace"].value() - - # remove default part of the string - if "default (" in colorspace: - colorspace = re.sub(r"default.\(|\)", "", colorspace) - - return colorspace - - -def get_review_presets_config(): - settings = get_current_project_settings() - review_profiles = ( - settings["core"] - ["publish"] - ["ExtractReview"] - ["profiles"] - ) - - outputs = {} - for profile in review_profiles: - outputs.update(profile.get("outputs", {})) - - return [str(name) for name, _prop in outputs.items()] - - -class NukeLoader(LoaderPlugin): - container_id_knob = "containerId" - container_id = None - - def reset_container_id(self): - self.container_id = "".join(random.choice( - string.ascii_uppercase + string.digits) for _ in range(10)) - - def get_container_id(self, node): - id_knob = node.knobs().get(self.container_id_knob) - return id_knob.value() if id_knob else None - - def get_members(self, source): - """Return nodes that has same "containerId" as `source`""" - source_id = self.get_container_id(source) - return [node for node in nuke.allNodes(recurseGroups=True) - if self.get_container_id(node) == source_id - and node is not source] if source_id else [] - - def set_as_member(self, node): - source_id = self.get_container_id(node) - - if source_id: - node[self.container_id_knob].setValue(source_id) - else: - HIDEN_FLAG = 0x00040000 - _knob = Knobby( - "String_Knob", - self.container_id, - flags=[ - nuke.READ_ONLY, - HIDEN_FLAG - ]) - knob = _knob.create(self.container_id_knob) - node.addKnob(knob) - - def clear_members(self, parent_node): - parent_class = parent_node.Class() - members = self.get_members(parent_node) - - dependent_nodes = None - for node in members: - _depndc = [n for n in node.dependent() if n not in members] - if not _depndc: - continue - - dependent_nodes = _depndc - break - - for member in members: - if member.Class() == parent_class: - continue - self.log.info("removing node: `{}".format(member.name())) - nuke.delete(member) - - return dependent_nodes - - -class ExporterReview(object): - """ - Base class object for generating review data from Nuke - - Args: - klass (pyblish.plugin): pyblish plugin parent - instance (pyblish.instance): instance of pyblish context - - """ - data = None - publish_on_farm = False - - def __init__(self, - klass, - instance, - multiple_presets=True - ): - - self.log = klass.log - self.instance = instance - self.multiple_presets = multiple_presets - self.path_in = self.instance.data.get("path", None) - self.staging_dir = self.instance.data["stagingDir"] - self.collection = self.instance.data.get("collection", None) - self.data = {"representations": []} - - def get_file_info(self): - if self.collection: - # get path - self.fname = os.path.basename( - self.collection.format("{head}{padding}{tail}") - ) - self.fhead = self.collection.format("{head}") - - # get first and last frame - self.first_frame = min(self.collection.indexes) - self.last_frame = max(self.collection.indexes) - - # make sure slate frame is not included - frame_start_handle = self.instance.data["frameStartHandle"] - if frame_start_handle > self.first_frame: - self.first_frame = frame_start_handle - - else: - self.fname = os.path.basename(self.path_in) - self.fhead = os.path.splitext(self.fname)[0] + "." - self.first_frame = self.instance.data["frameStartHandle"] - self.last_frame = self.instance.data["frameEndHandle"] - - if "#" in self.fhead: - self.fhead = self.fhead.replace("#", "")[:-1] - - def get_representation_data( - self, - tags=None, - range=False, - custom_tags=None, - colorspace=None, - ): - """ Add representation data to self.data - - Args: - tags (list[str], optional): list of defined tags. - Defaults to None. - range (bool, optional): flag for adding ranges. - Defaults to False. - custom_tags (list[str], optional): user inputted custom tags. - Defaults to None. - colorspace (str, optional): colorspace name. - Defaults to None. - """ - add_tags = tags or [] - repre = { - "name": self.name, - "ext": self.ext, - "files": self.file, - "stagingDir": self.staging_dir, - "tags": [self.name.replace("_", "-")] + add_tags, - "data": { - # making sure that once intermediate file is published - # as representation, we will be able to then identify it - # from representation.data.isIntermediate - "isIntermediate": True - }, - } - - if custom_tags: - repre["custom_tags"] = custom_tags - - if range: - repre.update({ - "frameStart": self.first_frame, - "frameEnd": self.last_frame, - }) - if ".{}".format(self.ext) not in VIDEO_EXTENSIONS: - filenames = get_filenames_without_hash( - self.file, self.first_frame, self.last_frame) - repre["files"] = filenames - - if self.multiple_presets: - repre["outputName"] = self.name - - if self.publish_on_farm: - repre["tags"].append("publish_on_farm") - - # add colorspace data to representation - if colorspace: - set_colorspace_data_to_representation( - repre, - self.instance.context.data, - colorspace=colorspace, - log=self.log - ) - self.data["representations"].append(repre) - - def get_imageio_baking_profile(self): - from . import lib as opnlib - nuke_imageio = opnlib.get_nuke_imageio_settings() - - if nuke_imageio["baking_target"]["enabled"]: - return nuke_imageio["baking_target"] - else: - # viewer is having display and view keys only and it is - # display_view type - return { - "type": "display_view", - "display_view": nuke_imageio["viewer"], - } - - -class ExporterReviewLut(ExporterReview): - """ - Generator object for review lut from Nuke - - Args: - klass (pyblish.plugin): pyblish plugin parent - instance (pyblish.instance): instance of pyblish context - - - """ - _temp_nodes = [] - - def __init__(self, - klass, - instance, - name=None, - ext=None, - cube_size=None, - lut_size=None, - lut_style=None, - multiple_presets=True): - # initialize parent class - super(ExporterReviewLut, self).__init__( - klass, instance, multiple_presets) - - # deal with now lut defined in viewer lut - if hasattr(klass, "viewer_lut_raw"): - self.viewer_lut_raw = klass.viewer_lut_raw - else: - self.viewer_lut_raw = False - - self.name = name or "baked_lut" - self.ext = ext or "cube" - self.cube_size = cube_size or 32 - self.lut_size = lut_size or 1024 - self.lut_style = lut_style or "linear" - - # set frame start / end and file name to self - self.get_file_info() - - self.log.info("File info was set...") - - self.file = self.fhead + self.name + ".{}".format(self.ext) - self.path = os.path.join( - self.staging_dir, self.file).replace("\\", "/") - - def clean_nodes(self): - for node in self._temp_nodes: - nuke.delete(node) - self._temp_nodes = [] - self.log.info("Deleted nodes...") - - def generate_lut(self, **kwargs): - bake_viewer_process = kwargs["bake_viewer_process"] - bake_viewer_input_process_node = kwargs[ - "bake_viewer_input_process"] - - # ---------- start nodes creation - - # CMSTestPattern - cms_node = nuke.createNode("CMSTestPattern") - cms_node["cube_size"].setValue(self.cube_size) - # connect - self._temp_nodes.append(cms_node) - self.previous_node = cms_node - - if bake_viewer_process: - # Node View Process - if bake_viewer_input_process_node: - ipn = get_view_process_node() - if ipn is not None: - # connect - ipn.setInput(0, self.previous_node) - self._temp_nodes.append(ipn) - self.previous_node = ipn - self.log.debug( - "ViewProcess... `{}`".format(self._temp_nodes)) - - if not self.viewer_lut_raw: - # OCIODisplay - dag_node = nuke.createNode("OCIODisplay") - # connect - dag_node.setInput(0, self.previous_node) - self._temp_nodes.append(dag_node) - self.previous_node = dag_node - self.log.debug( - "OCIODisplay... `{}`".format(self._temp_nodes)) - - # GenerateLUT - gen_lut_node = nuke.createNode("GenerateLUT") - gen_lut_node["file"].setValue(self.path) - gen_lut_node["file_type"].setValue(".{}".format(self.ext)) - gen_lut_node["lut1d"].setValue(self.lut_size) - gen_lut_node["style1d"].setValue(self.lut_style) - # connect - gen_lut_node.setInput(0, self.previous_node) - self._temp_nodes.append(gen_lut_node) - # ---------- end nodes creation - - # Export lut file - nuke.execute( - gen_lut_node.name(), - int(self.first_frame), - int(self.first_frame)) - - self.log.info("Exported...") - - # ---------- generate representation data - self.get_representation_data() - - # ---------- Clean up - self.clean_nodes() - - return self.data - - -class ExporterReviewMov(ExporterReview): - """ - Metaclass for generating review mov files - - Args: - klass (pyblish.plugin): pyblish plugin parent - instance (pyblish.instance): instance of pyblish context - - """ - _temp_nodes = {} - - def __init__(self, - klass, - instance, - name=None, - ext=None, - multiple_presets=True - ): - # initialize parent class - super(ExporterReviewMov, self).__init__( - klass, instance, multiple_presets) - # passing presets for nodes to self - self.nodes = klass.nodes if hasattr(klass, "nodes") else {} - - # deal with now lut defined in viewer lut - self.viewer_lut_raw = klass.viewer_lut_raw - self.write_colorspace = instance.data["colorspace"] - self.color_channels = instance.data["color_channels"] - self.formatting_data = instance.data["anatomyData"] - - self.name = name or "baked" - self.ext = ext or "mov" - - # set frame start / end and file name to self - self.get_file_info() - - self.log.info("File info was set...") - - if ".{}".format(self.ext) in VIDEO_EXTENSIONS: - self.file = "{}{}.{}".format( - self.fhead, self.name, self.ext) - else: - # Output is image (or image sequence) - # When the file is an image it's possible it - # has extra information after the `fhead` that - # we want to preserve, e.g. like frame numbers - # or frames hashes like `####` - filename_no_ext = os.path.splitext( - os.path.basename(self.path_in))[0] - after_head = filename_no_ext[len(self.fhead):] - self.file = "{}{}.{}.{}".format( - self.fhead, self.name, after_head, self.ext) - self.path = os.path.join( - self.staging_dir, self.file).replace("\\", "/") - - def clean_nodes(self, node_name): - for node in self._temp_nodes[node_name]: - nuke.delete(node) - self._temp_nodes[node_name] = [] - self.log.info("Deleted nodes...") - - def render(self, render_node_name): - self.log.info("Rendering... ") - # Render Write node - nuke.execute( - render_node_name, - int(self.first_frame), - int(self.last_frame)) - - self.log.info("Rendered...") - - def save_file(self): - import shutil - with maintained_selection(): - self.log.info("Saving nodes as file... ") - # create nk path - path = f"{os.path.splitext(self.path)[0]}.nk" - # save file to the path - if not os.path.exists(os.path.dirname(path)): - os.makedirs(os.path.dirname(path)) - shutil.copyfile(self.instance.context.data["currentFile"], path) - - self.log.info("Nodes exported...") - return path - - def generate_mov(self, farm=False, delete=True, **kwargs): - # colorspace data - colorspace = self.write_colorspace - - # get colorspace settings - # get colorspace data from context - config_data, _ = get_colorspace_settings_from_publish_context( - self.instance.context.data) - - add_tags = [] - self.publish_on_farm = farm - read_raw = kwargs["read_raw"] - bake_viewer_process = kwargs["bake_viewer_process"] - bake_viewer_input_process_node = kwargs[ - "bake_viewer_input_process"] - - baking_colorspace = self.get_imageio_baking_profile() - - colorspace_override = kwargs["colorspace_override"] - if colorspace_override["enabled"]: - baking_colorspace = colorspace_override - - fps = self.instance.context.data["fps"] - - self.log.debug(f">> baking_view_profile `{baking_colorspace}`") - - add_custom_tags = kwargs.get("add_custom_tags", []) - - self.log.info(f"__ add_custom_tags: `{add_custom_tags}`") - - product_name = self.instance.data["productName"] - self._temp_nodes[product_name] = [] - - # Read node - r_node = nuke.createNode("Read") - r_node["file"].setValue(self.path_in) - r_node["first"].setValue(self.first_frame) - r_node["origfirst"].setValue(self.first_frame) - r_node["last"].setValue(self.last_frame) - r_node["origlast"].setValue(self.last_frame) - r_node["colorspace"].setValue(self.write_colorspace) - - # do not rely on defaults, set explicitly - # to be sure it is set correctly - r_node["frame_mode"].setValue("expression") - r_node["frame"].setValue("") - - if read_raw: - r_node["raw"].setValue(1) - - # connect to Read node - self._shift_to_previous_node_and_temp( - product_name, r_node, "Read... `{}`" - ) - - # add reformat node - reformat_nodes_config = kwargs["reformat_nodes_config"] - if reformat_nodes_config["enabled"]: - reposition_nodes = reformat_nodes_config["reposition_nodes"] - for reposition_node in reposition_nodes: - node_class = reposition_node["node_class"] - knobs = reposition_node["knobs"] - node = nuke.createNode(node_class) - set_node_knobs_from_settings(node, knobs) - - # connect in order - self._connect_to_above_nodes( - node, product_name, "Reposition node... `{}`" - ) - # append reformatted tag - add_tags.append("reformatted") - - # only create colorspace baking if toggled on - if bake_viewer_process: - if bake_viewer_input_process_node: - # View Process node - ipn = get_view_process_node() - if ipn is not None: - # connect to ViewProcess node - self._connect_to_above_nodes( - ipn, product_name, "ViewProcess... `{}`" - ) - - if not self.viewer_lut_raw: - # OCIODisplay - if baking_colorspace["type"] == "display_view": - display_view = baking_colorspace["display_view"] - - message = "OCIODisplay... '{}'" - node = nuke.createNode("OCIODisplay") - - # assign display and view - display = display_view["display"] - view = display_view["view"] - - # display could not be set in nuke_default config - if display: - # format display string with anatomy data - display = StringTemplate(display).format_strict( - self.formatting_data - ) - node["display"].setValue(display) - - # format view string with anatomy data - view = StringTemplate(view).format_strict( - self.formatting_data) - # assign viewer - node["view"].setValue(view) - - if config_data: - # convert display and view to colorspace - colorspace = get_display_view_colorspace_name( - config_path=config_data["path"], - display=display, view=view - ) - - # OCIOColorSpace - elif baking_colorspace["type"] == "colorspace": - baking_colorspace = baking_colorspace["colorspace"] - # format colorspace string with anatomy data - baking_colorspace = StringTemplate( - baking_colorspace).format_strict(self.formatting_data) - node = nuke.createNode("OCIOColorSpace") - message = "OCIOColorSpace... '{}'" - # no need to set input colorspace since it is driven by - # working colorspace - node["out_colorspace"].setValue(baking_colorspace) - colorspace = baking_colorspace - - else: - raise ValueError( - "Invalid baking color space type: " - f"{baking_colorspace['type']}" - ) - - self._connect_to_above_nodes( - node, product_name, message - ) - - # Write node - write_node = nuke.createNode("Write") - self.log.debug(f"Path: {self.path}") - - write_node["file"].setValue(str(self.path)) - write_node["file_type"].setValue(str(self.ext)) - write_node["channels"].setValue(str(self.color_channels)) - - # Knobs `meta_codec` and `mov64_codec` are not available on centos. - # TODO shouldn't this come from settings on outputs? - try: - write_node["meta_codec"].setValue("ap4h") - except Exception: - self.log.info("`meta_codec` knob was not found") - - try: - write_node["mov64_codec"].setValue("ap4h") - write_node["mov64_fps"].setValue(float(fps)) - except Exception: - self.log.info("`mov64_codec` knob was not found") - - try: - write_node["mov64_write_timecode"].setValue(1) - except Exception: - self.log.info("`mov64_write_timecode` knob was not found") - - write_node["raw"].setValue(1) - - # connect - write_node.setInput(0, self.previous_node) - self._temp_nodes[product_name].append(write_node) - self.log.debug(f"Write... `{self._temp_nodes[product_name]}`") - # ---------- end nodes creation - - # ---------- render or save to nk - if self.publish_on_farm: - nuke.scriptSave() - path_nk = self.save_file() - self.data.update({ - "bakeScriptPath": path_nk, - "bakeWriteNodeName": write_node.name(), - "bakeRenderPath": self.path - }) - else: - self.render(write_node.name()) - - # ---------- generate representation data - tags = ["review", "need_thumbnail"] - - if delete: - tags.append("delete") - - self.get_representation_data( - tags=tags + add_tags, - custom_tags=add_custom_tags, - range=True, - colorspace=colorspace, - ) - - self.log.debug(f"Representation... `{self.data}`") - - self.clean_nodes(product_name) - nuke.scriptSave() - - return self.data - - def _shift_to_previous_node_and_temp(self, product_name, node, message): - self._temp_nodes[product_name].append(node) - self.previous_node = node - self.log.debug(message.format(self._temp_nodes[product_name])) - - def _connect_to_above_nodes(self, node, product_name, message): - node.setInput(0, self.previous_node) - self._shift_to_previous_node_and_temp(product_name, node, message) - - -def convert_to_valid_instaces(): - """ Check and convert to latest publisher instances - - Also save as new minor version of workfile. - """ - def product_type_to_identifier(product_type): - mapping = { - "render": "create_write_render", - "prerender": "create_write_prerender", - "still": "create_write_image", - "model": "create_model", - "camera": "create_camera", - "nukenodes": "create_backdrop", - "gizmo": "create_gizmo", - "source": "create_source" - - } - return mapping[product_type] - - from ayon_nuke.api import workio - - task_name = get_current_task_name() - - # save into new workfile - current_file = workio.current_file() - - # add file suffex if not - if "_publisherConvert" not in current_file: - new_workfile = ( - current_file[:-3] - + "_publisherConvert" - + current_file[-3:] - ) - else: - new_workfile = current_file - - path = new_workfile.replace("\\", "/") - nuke.scriptSaveAs(new_workfile, overwrite=1) - nuke.Root()["name"].setValue(path) - nuke.Root()["project_directory"].setValue(os.path.dirname(path)) - nuke.Root().setModified(False) - - _remove_old_knobs(nuke.Root()) - - # loop all nodes and convert - for node in nuke.allNodes(recurseGroups=True): - transfer_data = { - "creator_attributes": {} - } - creator_attr = transfer_data["creator_attributes"] - - if node.Class() in ["Viewer", "Dot"]: - continue - - if get_node_data(node, INSTANCE_DATA_KNOB): - continue - - # get data from avalon knob - avalon_knob_data = get_avalon_knob_data( - node, ["avalon:", "ak:"]) - - if not avalon_knob_data: - continue - - if avalon_knob_data["id"] not in { - AYON_INSTANCE_ID, AVALON_INSTANCE_ID - }: - continue - - transfer_data.update({ - k: v for k, v in avalon_knob_data.items() - if k not in ["families", "creator"] - }) - - transfer_data["task"] = task_name - - product_type = avalon_knob_data.get("productType") - if product_type is None: - product_type = avalon_knob_data["family"] - - # establish families - families_ak = avalon_knob_data.get("families", []) - - if "suspend_publish" in node.knobs(): - creator_attr["suspended_publish"] = ( - node["suspend_publish"].value()) - - # get review knob value - if "review" in node.knobs(): - creator_attr["review"] = ( - node["review"].value()) - - if "publish" in node.knobs(): - transfer_data["active"] = ( - node["publish"].value()) - - # add identifier - transfer_data["creator_identifier"] = product_type_to_identifier( - product_type - ) - - # Add all nodes in group instances. - if node.Class() == "Group": - # only alter families for render product type - if families_ak and "write" in families_ak.lower(): - target = node["render"].value() - if target == "Use existing frames": - creator_attr["render_target"] = "frames" - elif target == "Local": - # Local rendering - creator_attr["render_target"] = "local" - elif target == "On farm": - # Farm rendering - creator_attr["render_target"] = "farm" - - if "deadlinePriority" in node.knobs(): - transfer_data["farm_priority"] = ( - node["deadlinePriority"].value()) - if "deadlineChunkSize" in node.knobs(): - creator_attr["farm_chunk"] = ( - node["deadlineChunkSize"].value()) - if "deadlineConcurrentTasks" in node.knobs(): - creator_attr["farm_concurrency"] = ( - node["deadlineConcurrentTasks"].value()) - - _remove_old_knobs(node) - - # add new instance knob with transfer data - set_node_data( - node, INSTANCE_DATA_KNOB, transfer_data) - - nuke.scriptSave() - - -def _remove_old_knobs(node): - remove_knobs = [ - "review", "publish", "render", "suspend_publish", "warn", "divd", - "OpenpypeDataGroup", "OpenpypeDataGroup_End", "deadlinePriority", - "deadlineChunkSize", "deadlineConcurrentTasks", "Deadline" - ] - - # remove all old knobs - for knob in node.allKnobs(): - try: - if knob.name() in remove_knobs: - node.removeKnob(knob) - elif "avalon" in knob.name(): - node.removeKnob(knob) - except ValueError: - pass - - -def exposed_write_knobs(settings, plugin_name, instance_node): - exposed_knobs = settings["nuke"]["create"][plugin_name].get( - "exposed_knobs", [] - ) - if exposed_knobs: - instance_node.addKnob(nuke.Text_Knob('', 'Write Knobs')) - write_node = nuke.allNodes(group=instance_node, filter="Write")[0] - link_knobs(exposed_knobs, write_node, instance_node) diff --git a/server_addon/nuke/client/ayon_nuke/api/push_to_project.py b/server_addon/nuke/client/ayon_nuke/api/push_to_project.py deleted file mode 100644 index 852e5d0e31..0000000000 --- a/server_addon/nuke/client/ayon_nuke/api/push_to_project.py +++ /dev/null @@ -1,118 +0,0 @@ -from collections import defaultdict -import shutil -import os - -from ayon_api import get_project, get_folder_by_id, get_task_by_id -from ayon_core.settings import get_project_settings -from ayon_core.pipeline import Anatomy, registered_host -from ayon_core.pipeline.template_data import get_template_data -from ayon_core.pipeline.workfile import get_workdir_with_workdir_data -from ayon_core.tools import context_dialog - -from .utils import bake_gizmos_recursively -from .lib import MENU_LABEL - -import nuke - - -def bake_container(container): - """Bake containers to read nodes.""" - - node = container["node"] - - # Fetch knobs to remove in order. - knobs_to_remove = [] - remove = False - for count in range(0, node.numKnobs()): - knob = node.knob(count) - - # All knobs from "AYON" tab knob onwards. - if knob.name() == MENU_LABEL: - remove = True - - if remove: - knobs_to_remove.append(knob) - - # Dont remove knobs from "containerId" onwards. - if knob.name() == "containerId": - remove = False - - # Knobs needs to be remove in reverse order, because child knobs needs to - # be remove first. - for knob in reversed(knobs_to_remove): - node.removeKnob(knob) - - node["tile_color"].setValue(0) - - -def main(): - context = context_dialog.ask_for_context() - - if context is None: - return - - # Get workfile path to save to. - project_name = context["project_name"] - project = get_project(project_name) - folder = get_folder_by_id(project_name, context["folder_id"]) - task = get_task_by_id(project_name, context["task_id"]) - host = registered_host() - project_settings = get_project_settings(project_name) - anatomy = Anatomy(project_name) - - workdir_data = get_template_data( - project, folder, task, host.name, project_settings - ) - - workdir = get_workdir_with_workdir_data( - workdir_data, - project_name, - anatomy, - project_settings=project_settings - ) - # Save current workfile. - current_file = host.current_file() - host.save_file(current_file) - - for container in host.ls(): - bake_container(container) - - # Bake gizmos. - bake_gizmos_recursively() - - # Copy all read node files to "resources" folder next to workfile and - # change file path. - first_frame = int(nuke.root()["first_frame"].value()) - last_frame = int(nuke.root()["last_frame"].value()) - files_by_node_name = defaultdict(set) - nodes_by_name = {} - for count in range(first_frame, last_frame + 1): - nuke.frame(count) - for node in nuke.allNodes(filter="Read"): - files_by_node_name[node.name()].add( - nuke.filename(node, nuke.REPLACE) - ) - nodes_by_name[node.name()] = node - - resources_dir = os.path.join(workdir, "resources") - for name, files in files_by_node_name.items(): - dir = os.path.join(resources_dir, name) - if not os.path.exists(dir): - os.makedirs(dir) - - for f in files: - shutil.copy(f, os.path.join(dir, os.path.basename(f))) - - node = nodes_by_name[name] - path = node["file"].value().replace(os.path.dirname(f), dir) - node["file"].setValue(path.replace("\\", "/")) - - # Save current workfile to new context. - pushed_workfile = os.path.join( - workdir, os.path.basename(current_file)) - host.save_file(pushed_workfile) - - # Open current context workfile. - host.open_file(current_file) - - nuke.message(f"Pushed to project: \n{pushed_workfile}") diff --git a/server_addon/nuke/client/ayon_nuke/api/utils.py b/server_addon/nuke/client/ayon_nuke/api/utils.py deleted file mode 100644 index 646bb0ece1..0000000000 --- a/server_addon/nuke/client/ayon_nuke/api/utils.py +++ /dev/null @@ -1,224 +0,0 @@ -import os -import re - -import nuke - -import pyblish.util -import pyblish.api -from qtpy import QtWidgets - -from ayon_core import resources -from ayon_core.pipeline import registered_host -from ayon_core.tools.utils import show_message_dialog -from ayon_core.pipeline.create import CreateContext - - -def set_context_favorites(favorites=None): - """ Adding favorite folders to nuke's browser - - Arguments: - favorites (dict): couples of {name:path} - """ - favorites = favorites or {} - icon_path = resources.get_resource("icons", "folder-favorite.png") - for name, path in favorites.items(): - nuke.addFavoriteDir( - name, - path, - nuke.IMAGE | nuke.SCRIPT | nuke.GEO, - icon=icon_path) - - -def get_node_outputs(node): - ''' - Return a dictionary of the nodes and pipes that are connected to node - ''' - dep_dict = {} - dependencies = node.dependent(nuke.INPUTS | nuke.HIDDEN_INPUTS) - for d in dependencies: - dep_dict[d] = [] - for i in range(d.inputs()): - if d.input(i) == node: - dep_dict[d].append(i) - return dep_dict - - -def is_node_gizmo(node): - ''' - return True if node is gizmo - ''' - return 'gizmo_file' in node.knobs() - - -def gizmo_is_nuke_default(gizmo): - '''Check if gizmo is in default install path''' - plug_dir = os.path.join(os.path.dirname( - nuke.env['ExecutablePath']), 'plugins') - return gizmo.filename().startswith(plug_dir) - - -def bake_gizmos_recursively(in_group=None): - """Converting a gizmo to group - - Arguments: - is_group (nuke.Node)[optonal]: group node or all nodes - """ - from .lib import maintained_selection - if in_group is None: - in_group = nuke.Root() - # preserve selection after all is done - with maintained_selection(): - # jump to the group - with in_group: - for node in nuke.allNodes(): - if is_node_gizmo(node) and not gizmo_is_nuke_default(node): - with node: - outputs = get_node_outputs(node) - group = node.makeGroup() - # Reconnect inputs and outputs if any - if outputs: - for n, pipes in outputs.items(): - for i in pipes: - n.setInput(i, group) - for i in range(node.inputs()): - group.setInput(i, node.input(i)) - # set node position and name - group.setXYpos(node.xpos(), node.ypos()) - name = node.name() - nuke.delete(node) - group.setName(name) - node = group - - if node.Class() == "Group": - bake_gizmos_recursively(node) - - -def colorspace_exists_on_node(node, colorspace_name): - """ Check if colorspace exists on node - - Look through all options in the colorspace knob, and see if we have an - exact match to one of the items. - - Args: - node (nuke.Node): nuke node object - colorspace_name (str): color profile name - - Returns: - bool: True if exists - """ - try: - colorspace_knob = node['colorspace'] - except ValueError: - # knob is not available on input node - return False - - return colorspace_name in get_colorspace_list(colorspace_knob) - - -def get_colorspace_list(colorspace_knob): - """Get available colorspace profile names - - Args: - colorspace_knob (nuke.Knob): nuke knob object - - Returns: - list: list of strings names of profiles - """ - results = [] - - # This pattern is to match with roles which uses an indentation and - # parentheses with original colorspace. The value returned from the - # colorspace is the string before the indentation, so we'll need to - # convert the values to match with value returned from the knob, - # ei. knob.value(). - pattern = r".*\t.* \(.*\)" - for colorspace in nuke.getColorspaceList(colorspace_knob): - match = re.search(pattern, colorspace) - if match: - results.append(colorspace.split("\t", 1)[0]) - else: - results.append(colorspace) - - return results - - -def is_headless(): - """ - Returns: - bool: headless - """ - return QtWidgets.QApplication.instance() is None - - -def submit_render_on_farm(node): - # Ensure code is executed in root context. - if nuke.root() == nuke.thisNode(): - _submit_render_on_farm(node) - else: - # If not in root context, move to the root context and then execute the - # code. - with nuke.root(): - _submit_render_on_farm(node) - - -def _submit_render_on_farm(node): - """Render on farm submission - - This function prepares the context for farm submission, validates it, - extracts relevant data, copies the current workfile to a timestamped copy, - and submits the job to the farm. - - Args: - node (Node): The node for which the farm submission is being made. - """ - - host = registered_host() - create_context = CreateContext(host) - - # Ensure CreateInstance is enabled. - for instance in create_context.instances: - if node.name() != instance.transient_data["node"].name(): - continue - - instance.data["active"] = True - - context = pyblish.api.Context() - context.data["create_context"] = create_context - # Used in pyblish plugin to determine which instance to publish. - context.data["node_name"] = node.name() - # Used in pyblish plugins to determine whether to run or not. - context.data["render_on_farm"] = True - - # Since we need to bypass version validation and incrementing, we need to - # remove the plugins from the list that are responsible for these tasks. - plugins = pyblish.api.discover() - blacklist = ["IncrementScriptVersion", "ValidateVersion"] - plugins = [ - plugin - for plugin in plugins - if plugin.__name__ not in blacklist - ] - - context = pyblish.util.publish(context, plugins=plugins) - - error_message = "" - success = True - for result in context.data["results"]: - if result["success"]: - continue - - success = False - - err = result["error"] - error_message += "\n" - error_message += err.formatted_traceback - - if not success: - show_message_dialog( - "Publish Errors", error_message, level="critical" - ) - return - - show_message_dialog( - "Submission Successful", "Submission to the farm was successful." - ) diff --git a/server_addon/nuke/client/ayon_nuke/api/workfile_template_builder.py b/server_addon/nuke/client/ayon_nuke/api/workfile_template_builder.py deleted file mode 100644 index aebf91c4a4..0000000000 --- a/server_addon/nuke/client/ayon_nuke/api/workfile_template_builder.py +++ /dev/null @@ -1,156 +0,0 @@ -import collections -import nuke - -from ayon_core.pipeline import registered_host -from ayon_core.pipeline.workfile.workfile_template_builder import ( - AbstractTemplateBuilder, - PlaceholderPlugin, -) -from ayon_core.tools.workfile_template_build import ( - WorkfileBuildPlaceholderDialog, -) -from .lib import ( - imprint, - reset_selection, - get_main_window, - WorkfileSettings, -) - -PLACEHOLDER_SET = "PLACEHOLDERS_SET" - - -class NukeTemplateBuilder(AbstractTemplateBuilder): - """Concrete implementation of AbstractTemplateBuilder for nuke""" - - def import_template(self, path): - """Import template into current scene. - Block if a template is already loaded. - - Args: - path (str): A path to current template (usually given by - get_template_preset implementation) - - Returns: - bool: Whether the template was successfully imported or not - """ - - # TODO check if the template is already imported - - nuke.nodePaste(path) - reset_selection() - - return True - - -class NukePlaceholderPlugin(PlaceholderPlugin): - node_color = 4278190335 - - def _collect_scene_placeholders(self): - # Cache placeholder data to shared data - placeholder_nodes = self.builder.get_shared_populate_data( - "placeholder_nodes" - ) - if placeholder_nodes is None: - placeholder_nodes = {} - all_groups = collections.deque() - all_groups.append(nuke.thisGroup()) - while all_groups: - group = all_groups.popleft() - for node in group.nodes(): - if isinstance(node, nuke.Group): - all_groups.append(node) - - node_knobs = node.knobs() - if ( - "is_placeholder" not in node_knobs - or not node.knob("is_placeholder").value() - ): - continue - - if "empty" in node_knobs and node.knob("empty").value(): - continue - - placeholder_nodes[node.fullName()] = node - - self.builder.set_shared_populate_data( - "placeholder_nodes", placeholder_nodes - ) - return placeholder_nodes - - def create_placeholder(self, placeholder_data): - placeholder_data["plugin_identifier"] = self.identifier - - placeholder = nuke.nodes.NoOp() - placeholder.setName("PLACEHOLDER") - placeholder.knob("tile_color").setValue(self.node_color) - - imprint(placeholder, placeholder_data) - imprint(placeholder, {"is_placeholder": True}) - placeholder.knob("is_placeholder").setVisible(False) - - def update_placeholder(self, placeholder_item, placeholder_data): - node = nuke.toNode(placeholder_item.scene_identifier) - imprint(node, placeholder_data) - - def _parse_placeholder_node_data(self, node): - placeholder_data = {} - for key in self.get_placeholder_keys(): - knob = node.knob(key) - value = None - if knob is not None: - value = knob.getValue() - placeholder_data[key] = value - return placeholder_data - - def delete_placeholder(self, placeholder): - """Remove placeholder if building was successful""" - placeholder_node = nuke.toNode(placeholder.scene_identifier) - nuke.delete(placeholder_node) - - -def build_workfile_template(*args, **kwargs): - builder = NukeTemplateBuilder(registered_host()) - builder.build_template(*args, **kwargs) - - # set all settings to shot context default - WorkfileSettings().set_context_settings() - - -def update_workfile_template(*args): - builder = NukeTemplateBuilder(registered_host()) - builder.rebuild_template() - - -def create_placeholder(*args): - host = registered_host() - builder = NukeTemplateBuilder(host) - window = WorkfileBuildPlaceholderDialog(host, builder, - parent=get_main_window()) - window.show() - - -def update_placeholder(*args): - host = registered_host() - builder = NukeTemplateBuilder(host) - placeholder_items_by_id = { - placeholder_item.scene_identifier: placeholder_item - for placeholder_item in builder.get_placeholders() - } - placeholder_items = [] - for node in nuke.selectedNodes(): - node_name = node.fullName() - if node_name in placeholder_items_by_id: - placeholder_items.append(placeholder_items_by_id[node_name]) - - # TODO show UI at least - if len(placeholder_items) == 0: - raise ValueError("No node selected") - - if len(placeholder_items) > 1: - raise ValueError("Too many selected nodes") - - placeholder_item = placeholder_items[0] - window = WorkfileBuildPlaceholderDialog(host, builder, - parent=get_main_window()) - window.set_update_mode(placeholder_item) - window.exec_() diff --git a/server_addon/nuke/client/ayon_nuke/api/workio.py b/server_addon/nuke/client/ayon_nuke/api/workio.py deleted file mode 100644 index b2445fd3d2..0000000000 --- a/server_addon/nuke/client/ayon_nuke/api/workio.py +++ /dev/null @@ -1,78 +0,0 @@ -"""Host API required Work Files tool""" -import os -import nuke -import shutil -from .utils import is_headless - - -def file_extensions(): - return [".nk"] - - -def has_unsaved_changes(): - return nuke.root().modified() - - -def save_file(filepath): - path = filepath.replace("\\", "/") - nuke.scriptSaveAs(path, overwrite=1) - nuke.Root()["name"].setValue(path) - nuke.Root()["project_directory"].setValue(os.path.dirname(path)) - nuke.Root().setModified(False) - - -def open_file(filepath): - - def read_script(nuke_script): - nuke.scriptClear() - nuke.scriptReadFile(nuke_script) - nuke.Root()["name"].setValue(nuke_script) - nuke.Root()["project_directory"].setValue(os.path.dirname(nuke_script)) - nuke.Root().setModified(False) - - filepath = filepath.replace("\\", "/") - - # To remain in the same window, we have to clear the script and read - # in the contents of the workfile. - # Nuke Preferences can be read after the script is read. - read_script(filepath) - - if not is_headless(): - autosave = nuke.toNode("preferences")["AutoSaveName"].evaluate() - autosave_prmpt = "Autosave detected.\n" \ - "Would you like to load the autosave file?" # noqa - if os.path.isfile(autosave) and nuke.ask(autosave_prmpt): - try: - # Overwrite the filepath with autosave - shutil.copy(autosave, filepath) - # Now read the (auto-saved) script again - read_script(filepath) - except shutil.Error as err: - nuke.message( - "Detected autosave file could not be used.\n{}" - - .format(err)) - - return True - - -def current_file(): - current_file = nuke.root().name() - - # Unsaved current file - if current_file == 'Root': - return None - - return os.path.normpath(current_file).replace("\\", "/") - - -def work_root(session): - - work_dir = session["AYON_WORKDIR"] - scene_dir = session.get("AVALON_SCENEDIR") - if scene_dir: - path = os.path.join(work_dir, scene_dir) - else: - path = work_dir - - return os.path.normpath(path).replace("\\", "/") diff --git a/server_addon/nuke/client/ayon_nuke/hooks/pre_nukeassist_setup.py b/server_addon/nuke/client/ayon_nuke/hooks/pre_nukeassist_setup.py deleted file mode 100644 index afef3ba843..0000000000 --- a/server_addon/nuke/client/ayon_nuke/hooks/pre_nukeassist_setup.py +++ /dev/null @@ -1,12 +0,0 @@ -from ayon_applications import PreLaunchHook - - -class PrelaunchNukeAssistHook(PreLaunchHook): - """ - Adding flag when nukeassist - """ - app_groups = {"nukeassist"} - launch_types = set() - - def execute(self): - self.launch_context.env["NUKEASSIST"] = "1" diff --git a/server_addon/nuke/client/ayon_nuke/plugins/__init__.py b/server_addon/nuke/client/ayon_nuke/plugins/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/server_addon/nuke/client/ayon_nuke/plugins/create/__init__.py b/server_addon/nuke/client/ayon_nuke/plugins/create/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/server_addon/nuke/client/ayon_nuke/plugins/create/convert_legacy.py b/server_addon/nuke/client/ayon_nuke/plugins/create/convert_legacy.py deleted file mode 100644 index 65e719d15b..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/create/convert_legacy.py +++ /dev/null @@ -1,55 +0,0 @@ -from ayon_core.pipeline import AYON_INSTANCE_ID, AVALON_INSTANCE_ID -from ayon_core.pipeline.create.creator_plugins import ProductConvertorPlugin -from ayon_nuke.api.lib import ( - INSTANCE_DATA_KNOB, - get_node_data, - get_avalon_knob_data, - NODE_TAB_NAME, -) -from ayon_nuke.api.plugin import convert_to_valid_instaces - -import nuke - - -class LegacyConverted(ProductConvertorPlugin): - identifier = "legacy.converter" - - def find_instances(self): - - legacy_found = False - # search for first available legacy item - for node in nuke.allNodes(recurseGroups=True): - if node.Class() in ["Viewer", "Dot"]: - continue - - if get_node_data(node, INSTANCE_DATA_KNOB): - continue - - if NODE_TAB_NAME not in node.knobs(): - continue - - # get data from avalon knob - avalon_knob_data = get_avalon_knob_data( - node, ["avalon:", "ak:"], create=False) - - if not avalon_knob_data: - continue - - if avalon_knob_data["id"] not in { - AYON_INSTANCE_ID, AVALON_INSTANCE_ID - }: - continue - - # catch and break - legacy_found = True - break - - if legacy_found: - # if not item do not add legacy instance converter - self.add_convertor_item("Convert legacy instances") - - def convert(self): - # loop all instances and convert them - convert_to_valid_instaces() - # remove legacy item if all is fine - self.remove_convertor_item() diff --git a/server_addon/nuke/client/ayon_nuke/plugins/create/create_backdrop.py b/server_addon/nuke/client/ayon_nuke/plugins/create/create_backdrop.py deleted file mode 100644 index f97b9efeb6..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/create/create_backdrop.py +++ /dev/null @@ -1,53 +0,0 @@ -from nukescripts import autoBackdrop - -from ayon_nuke.api import ( - NukeCreator, - maintained_selection, - select_nodes -) - - -class CreateBackdrop(NukeCreator): - """Add Publishable Backdrop""" - - settings_category = "nuke" - - identifier = "create_backdrop" - label = "Nukenodes (backdrop)" - product_type = "nukenodes" - icon = "file-archive-o" - maintain_selection = True - - # plugin attributes - node_color = "0xdfea5dff" - - def create_instance_node( - self, - node_name, - knobs=None, - parent=None, - node_type=None - ): - with maintained_selection(): - if len(self.selected_nodes) >= 1: - select_nodes(self.selected_nodes) - - created_node = autoBackdrop() - created_node["name"].setValue(node_name) - created_node["tile_color"].setValue(int(self.node_color, 16)) - created_node["note_font_size"].setValue(24) - created_node["label"].setValue("[{}]".format(node_name)) - - return created_node - - def create(self, product_name, instance_data, pre_create_data): - # make sure product name is unique - self.check_existing_product(product_name) - - instance = super(CreateBackdrop, self).create( - product_name, - instance_data, - pre_create_data - ) - - return instance diff --git a/server_addon/nuke/client/ayon_nuke/plugins/create/create_camera.py b/server_addon/nuke/client/ayon_nuke/plugins/create/create_camera.py deleted file mode 100644 index 69e5b9c676..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/create/create_camera.py +++ /dev/null @@ -1,71 +0,0 @@ -import nuke -from ayon_nuke.api import ( - NukeCreator, - NukeCreatorError, - maintained_selection -) -from ayon_nuke.api.lib import ( - create_camera_node_by_version -) - - -class CreateCamera(NukeCreator): - """Add Publishable Camera""" - - settings_category = "nuke" - - identifier = "create_camera" - label = "Camera (3d)" - product_type = "camera" - icon = "camera" - - # plugin attributes - node_color = "0xff9100ff" - - def create_instance_node( - self, - node_name, - knobs=None, - parent=None, - node_type=None - ): - with maintained_selection(): - if self.selected_nodes: - node = self.selected_nodes[0] - if node.Class() != "Camera3": - raise NukeCreatorError( - "Creator error: Select only camera node type") - created_node = self.selected_nodes[0] - else: - created_node = create_camera_node_by_version() - - created_node["tile_color"].setValue( - int(self.node_color, 16)) - - created_node["name"].setValue(node_name) - - return created_node - - def create(self, product_name, instance_data, pre_create_data): - # make sure product name is unique - self.check_existing_product(product_name) - - instance = super(CreateCamera, self).create( - product_name, - instance_data, - pre_create_data - ) - - return instance - - def set_selected_nodes(self, pre_create_data): - if pre_create_data.get("use_selection"): - self.selected_nodes = nuke.selectedNodes() - if self.selected_nodes == []: - raise NukeCreatorError( - "Creator error: No active selection") - elif len(self.selected_nodes) > 1: - raise NukeCreatorError( - "Creator error: Select only one camera node") - else: - self.selected_nodes = [] diff --git a/server_addon/nuke/client/ayon_nuke/plugins/create/create_gizmo.py b/server_addon/nuke/client/ayon_nuke/plugins/create/create_gizmo.py deleted file mode 100644 index 6be7cd58db..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/create/create_gizmo.py +++ /dev/null @@ -1,67 +0,0 @@ -import nuke -from ayon_nuke.api import ( - NukeCreator, - NukeCreatorError, - maintained_selection -) - - -class CreateGizmo(NukeCreator): - """Add Publishable Group as gizmo""" - - settings_category = "nuke" - - identifier = "create_gizmo" - label = "Gizmo (group)" - product_type = "gizmo" - icon = "file-archive-o" - default_variants = ["ViewerInput", "Lut", "Effect"] - - # plugin attributes - node_color = "0x7533c1ff" - - def create_instance_node( - self, - node_name, - knobs=None, - parent=None, - node_type=None - ): - with maintained_selection(): - if self.selected_nodes: - node = self.selected_nodes[0] - if node.Class() != "Group": - raise NukeCreatorError( - "Creator error: Select only 'Group' node type") - created_node = node - else: - created_node = nuke.collapseToGroup() - - created_node["tile_color"].setValue( - int(self.node_color, 16)) - - created_node["name"].setValue(node_name) - - return created_node - - def create(self, product_name, instance_data, pre_create_data): - # make sure product name is unique - self.check_existing_product(product_name) - - instance = super(CreateGizmo, self).create( - product_name, - instance_data, - pre_create_data - ) - - return instance - - def set_selected_nodes(self, pre_create_data): - if pre_create_data.get("use_selection"): - self.selected_nodes = nuke.selectedNodes() - if self.selected_nodes == []: - raise NukeCreatorError("Creator error: No active selection") - elif len(self.selected_nodes) > 1: - NukeCreatorError("Creator error: Select only one 'Group' node") - else: - self.selected_nodes = [] diff --git a/server_addon/nuke/client/ayon_nuke/plugins/create/create_model.py b/server_addon/nuke/client/ayon_nuke/plugins/create/create_model.py deleted file mode 100644 index b7d7b740c2..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/create/create_model.py +++ /dev/null @@ -1,67 +0,0 @@ -import nuke -from ayon_nuke.api import ( - NukeCreator, - NukeCreatorError, - maintained_selection -) - - -class CreateModel(NukeCreator): - """Add Publishable Camera""" - - settings_category = "nuke" - - identifier = "create_model" - label = "Model (3d)" - product_type = "model" - icon = "cube" - default_variants = ["Main"] - - # plugin attributes - node_color = "0xff3200ff" - - def create_instance_node( - self, - node_name, - knobs=None, - parent=None, - node_type=None - ): - with maintained_selection(): - if self.selected_nodes: - node = self.selected_nodes[0] - if node.Class() != "Scene": - raise NukeCreatorError( - "Creator error: Select only 'Scene' node type") - created_node = node - else: - created_node = nuke.createNode("Scene") - - created_node["tile_color"].setValue( - int(self.node_color, 16)) - - created_node["name"].setValue(node_name) - - return created_node - - def create(self, product_name, instance_data, pre_create_data): - # make sure product name is unique - self.check_existing_product(product_name) - - instance = super(CreateModel, self).create( - product_name, - instance_data, - pre_create_data - ) - - return instance - - def set_selected_nodes(self, pre_create_data): - if pre_create_data.get("use_selection"): - self.selected_nodes = nuke.selectedNodes() - if self.selected_nodes == []: - raise NukeCreatorError("Creator error: No active selection") - elif len(self.selected_nodes) > 1: - NukeCreatorError("Creator error: Select only one 'Scene' node") - else: - self.selected_nodes = [] diff --git a/server_addon/nuke/client/ayon_nuke/plugins/create/create_source.py b/server_addon/nuke/client/ayon_nuke/plugins/create/create_source.py deleted file mode 100644 index 1579cebb1d..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/create/create_source.py +++ /dev/null @@ -1,90 +0,0 @@ -import nuke -import six -import sys -from ayon_nuke.api import ( - INSTANCE_DATA_KNOB, - NukeCreator, - NukeCreatorError, - set_node_data -) -from ayon_core.pipeline import ( - CreatedInstance -) - - -class CreateSource(NukeCreator): - """Add Publishable Read with source""" - - settings_category = "nuke" - - identifier = "create_source" - label = "Source (read)" - product_type = "source" - icon = "film" - default_variants = ["Effect", "Backplate", "Fire", "Smoke"] - - # plugin attributes - node_color = "0xff9100ff" - - def create_instance_node( - self, - node_name, - read_node - ): - read_node["tile_color"].setValue( - int(self.node_color, 16)) - read_node["name"].setValue(node_name) - - return read_node - - def create(self, product_name, instance_data, pre_create_data): - - # make sure selected nodes are added - self.set_selected_nodes(pre_create_data) - - try: - for read_node in self.selected_nodes: - if read_node.Class() != 'Read': - continue - - node_name = read_node.name() - _product_name = product_name + node_name - - # make sure product name is unique - self.check_existing_product(_product_name) - - instance_node = self.create_instance_node( - _product_name, - read_node - ) - instance = CreatedInstance( - self.product_type, - _product_name, - instance_data, - self - ) - - instance.transient_data["node"] = instance_node - - self._add_instance_to_context(instance) - - set_node_data( - instance_node, - INSTANCE_DATA_KNOB, - instance.data_to_store() - ) - - except Exception as er: - six.reraise( - NukeCreatorError, - NukeCreatorError("Creator error: {}".format(er)), - sys.exc_info()[2]) - - def set_selected_nodes(self, pre_create_data): - if pre_create_data.get("use_selection"): - self.selected_nodes = nuke.selectedNodes() - if self.selected_nodes == []: - raise NukeCreatorError("Creator error: No active selection") - else: - NukeCreatorError( - "Creator error: only supported with active selection") diff --git a/server_addon/nuke/client/ayon_nuke/plugins/create/create_write_image.py b/server_addon/nuke/client/ayon_nuke/plugins/create/create_write_image.py deleted file mode 100644 index 2268817e76..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/create/create_write_image.py +++ /dev/null @@ -1,174 +0,0 @@ -import nuke -import sys -import six - -from ayon_core.pipeline import ( - CreatedInstance -) -from ayon_core.lib import ( - BoolDef, - NumberDef, - UISeparatorDef, - EnumDef -) -from ayon_nuke import api as napi -from ayon_nuke.api.plugin import exposed_write_knobs - - -class CreateWriteImage(napi.NukeWriteCreator): - - settings_category = "nuke" - - identifier = "create_write_image" - label = "Image (write)" - product_type = "image" - icon = "sign-out" - - instance_attributes = [ - "use_range_limit" - ] - default_variants = [ - "StillFrame", - "MPFrame", - "LayoutFrame" - ] - temp_rendering_path_template = ( - "{work}/renders/nuke/{subset}/{subset}.{frame}.{ext}") - - def get_pre_create_attr_defs(self): - attr_defs = [ - BoolDef( - "use_selection", - default=not self.create_context.headless, - label="Use selection" - ), - self._get_render_target_enum(), - UISeparatorDef(), - self._get_frame_source_number() - ] - return attr_defs - - def _get_render_target_enum(self): - rendering_targets = { - "local": "Local machine rendering", - "frames": "Use existing frames" - } - - return EnumDef( - "render_target", - items=rendering_targets, - label="Render target" - ) - - def _get_frame_source_number(self): - return NumberDef( - "active_frame", - label="Active frame", - default=nuke.frame() - ) - - def create_instance_node(self, product_name, instance_data): - settings = self.project_settings["nuke"]["create"]["CreateWriteImage"] - - # add fpath_template - write_data = { - "creator": self.__class__.__name__, - "productName": product_name, - "fpath_template": self.temp_rendering_path_template, - "render_on_farm": ( - "render_on_farm" in settings["instance_attributes"] - ) - } - write_data.update(instance_data) - - created_node = napi.create_write_node( - product_name, - write_data, - input=self.selected_node, - prenodes=self.prenodes, - linked_knobs=self.get_linked_knobs(), - **{ - "frame": nuke.frame() - } - ) - - self._add_frame_range_limit(created_node, instance_data) - - self.integrate_links(created_node, outputs=True) - - return created_node - - def create(self, product_name, instance_data, pre_create_data): - product_name = product_name.format(**pre_create_data) - - # pass values from precreate to instance - self.pass_pre_attributes_to_instance( - instance_data, - pre_create_data, - [ - "active_frame", - "render_target" - ] - ) - - # make sure selected nodes are added - self.set_selected_nodes(pre_create_data) - - # make sure product name is unique - self.check_existing_product(product_name) - - instance_node = self.create_instance_node( - product_name, - instance_data, - ) - - try: - instance = CreatedInstance( - self.product_type, - product_name, - instance_data, - self - ) - - instance.transient_data["node"] = instance_node - - self._add_instance_to_context(instance) - - napi.set_node_data( - instance_node, - napi.INSTANCE_DATA_KNOB, - instance.data_to_store() - ) - - exposed_write_knobs( - self.project_settings, self.__class__.__name__, instance_node - ) - - return instance - - except Exception as er: - six.reraise( - napi.NukeCreatorError, - napi.NukeCreatorError("Creator error: {}".format(er)), - sys.exc_info()[2] - ) - - def _add_frame_range_limit(self, write_node, instance_data): - if "use_range_limit" not in self.instance_attributes: - return - - active_frame = ( - instance_data["creator_attributes"].get("active_frame")) - - write_node.begin() - for n in nuke.allNodes(): - # get write node - if n.Class() in "Write": - w_node = n - write_node.end() - - w_node["use_limit"].setValue(True) - w_node["first"].setValue(active_frame or nuke.frame()) - w_node["last"].setExpression("first") - - return write_node diff --git a/server_addon/nuke/client/ayon_nuke/plugins/create/create_write_prerender.py b/server_addon/nuke/client/ayon_nuke/plugins/create/create_write_prerender.py deleted file mode 100644 index 014e91e81c..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/create/create_write_prerender.py +++ /dev/null @@ -1,160 +0,0 @@ -import nuke -import sys -import six - -from ayon_core.pipeline import ( - CreatedInstance -) -from ayon_core.lib import ( - BoolDef -) -from ayon_nuke import api as napi -from ayon_nuke.api.plugin import exposed_write_knobs - - -class CreateWritePrerender(napi.NukeWriteCreator): - - settings_category = "nuke" - - identifier = "create_write_prerender" - label = "Prerender (write)" - product_type = "prerender" - icon = "sign-out" - - instance_attributes = [ - "use_range_limit" - ] - default_variants = [ - "Key01", - "Bg01", - "Fg01", - "Branch01", - "Part01" - ] - temp_rendering_path_template = ( - "{work}/renders/nuke/{subset}/{subset}.{frame}.{ext}") - - # Before write node render. - order = 90 - - def get_pre_create_attr_defs(self): - attr_defs = [ - BoolDef( - "use_selection", - default=not self.create_context.headless, - label="Use selection" - ), - self._get_render_target_enum() - ] - return attr_defs - - def create_instance_node(self, product_name, instance_data): - settings = self.project_settings["nuke"]["create"] - settings = settings["CreateWritePrerender"] - - # add fpath_template - write_data = { - "creator": self.__class__.__name__, - "productName": product_name, - "fpath_template": self.temp_rendering_path_template, - "render_on_farm": ( - "render_on_farm" in settings["instance_attributes"] - ) - } - - write_data.update(instance_data) - - # get width and height - if self.selected_node: - width, height = ( - self.selected_node.width(), self.selected_node.height()) - else: - actual_format = nuke.root().knob('format').value() - width, height = (actual_format.width(), actual_format.height()) - - created_node = napi.create_write_node( - product_name, - write_data, - input=self.selected_node, - prenodes=self.prenodes, - linked_knobs=self.get_linked_knobs(), - **{ - "width": width, - "height": height - } - ) - - self._add_frame_range_limit(created_node) - - self.integrate_links(created_node, outputs=True) - - return created_node - - def create(self, product_name, instance_data, pre_create_data): - # pass values from precreate to instance - self.pass_pre_attributes_to_instance( - instance_data, - pre_create_data, - [ - "render_target" - ] - ) - - # make sure selected nodes are added - self.set_selected_nodes(pre_create_data) - - # make sure product name is unique - self.check_existing_product(product_name) - - instance_node = self.create_instance_node( - product_name, - instance_data - ) - - try: - instance = CreatedInstance( - self.product_type, - product_name, - instance_data, - self - ) - - instance.transient_data["node"] = instance_node - - self._add_instance_to_context(instance) - - napi.set_node_data( - instance_node, - napi.INSTANCE_DATA_KNOB, - instance.data_to_store() - ) - - exposed_write_knobs( - self.project_settings, self.__class__.__name__, instance_node - ) - - return instance - - except Exception as er: - six.reraise( - napi.NukeCreatorError, - napi.NukeCreatorError("Creator error: {}".format(er)), - sys.exc_info()[2] - ) - - def _add_frame_range_limit(self, write_node): - if "use_range_limit" not in self.instance_attributes: - return - - write_node.begin() - for n in nuke.allNodes(): - # get write node - if n.Class() in "Write": - w_node = n - write_node.end() - - w_node["use_limit"].setValue(True) - w_node["first"].setValue(nuke.root()["first_frame"].value()) - w_node["last"].setValue(nuke.root()["last_frame"].value()) - - return write_node diff --git a/server_addon/nuke/client/ayon_nuke/plugins/create/create_write_render.py b/server_addon/nuke/client/ayon_nuke/plugins/create/create_write_render.py deleted file mode 100644 index bed081c882..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/create/create_write_render.py +++ /dev/null @@ -1,136 +0,0 @@ -import nuke -import sys -import six - -from ayon_core.pipeline import ( - CreatedInstance -) -from ayon_core.lib import ( - BoolDef -) -from ayon_nuke import api as napi -from ayon_nuke.api.plugin import exposed_write_knobs - - -class CreateWriteRender(napi.NukeWriteCreator): - - settings_category = "nuke" - - identifier = "create_write_render" - label = "Render (write)" - product_type = "render" - icon = "sign-out" - - instance_attributes = [ - "reviewable" - ] - default_variants = [ - "Main", - "Mask" - ] - temp_rendering_path_template = ( - "{work}/renders/nuke/{subset}/{subset}.{frame}.{ext}") - - def get_pre_create_attr_defs(self): - attr_defs = [ - BoolDef( - "use_selection", - default=not self.create_context.headless, - label="Use selection" - ), - self._get_render_target_enum() - ] - return attr_defs - - def create_instance_node(self, product_name, instance_data): - settings = self.project_settings["nuke"]["create"]["CreateWriteRender"] - - # add fpath_template - write_data = { - "creator": self.__class__.__name__, - "productName": product_name, - "fpath_template": self.temp_rendering_path_template, - "render_on_farm": ( - "render_on_farm" in settings["instance_attributes"] - ) - } - - write_data.update(instance_data) - - # get width and height - if self.selected_node: - width, height = ( - self.selected_node.width(), self.selected_node.height()) - else: - actual_format = nuke.root().knob('format').value() - width, height = (actual_format.width(), actual_format.height()) - - self.log.debug(">>>>>>> : {}".format(self.instance_attributes)) - self.log.debug(">>>>>>> : {}".format(self.get_linked_knobs())) - - created_node = napi.create_write_node( - product_name, - write_data, - input=self.selected_node, - prenodes=self.prenodes, - linked_knobs=self.get_linked_knobs(), - **{ - "width": width, - "height": height - } - ) - - self.integrate_links(created_node, outputs=False) - - return created_node - - def create(self, product_name, instance_data, pre_create_data): - # pass values from precreate to instance - self.pass_pre_attributes_to_instance( - instance_data, - pre_create_data, - [ - "render_target" - ] - ) - # make sure selected nodes are added - self.set_selected_nodes(pre_create_data) - - # make sure product name is unique - self.check_existing_product(product_name) - - instance_node = self.create_instance_node( - product_name, - instance_data - ) - - try: - instance = CreatedInstance( - self.product_type, - product_name, - instance_data, - self - ) - - instance.transient_data["node"] = instance_node - - self._add_instance_to_context(instance) - - napi.set_node_data( - instance_node, - napi.INSTANCE_DATA_KNOB, - instance.data_to_store() - ) - - exposed_write_knobs( - self.project_settings, self.__class__.__name__, instance_node - ) - - return instance - - except Exception as er: - six.reraise( - napi.NukeCreatorError, - napi.NukeCreatorError("Creator error: {}".format(er)), - sys.exc_info()[2] - ) diff --git a/server_addon/nuke/client/ayon_nuke/plugins/create/workfile_creator.py b/server_addon/nuke/client/ayon_nuke/plugins/create/workfile_creator.py deleted file mode 100644 index 463d898224..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/create/workfile_creator.py +++ /dev/null @@ -1,84 +0,0 @@ -import ayon_api - -import ayon_nuke.api as api -from ayon_core.pipeline import ( - AutoCreator, - CreatedInstance, -) -from ayon_nuke.api import ( - INSTANCE_DATA_KNOB, - set_node_data -) -import nuke - - -class WorkfileCreator(AutoCreator): - - settings_category = "nuke" - - identifier = "workfile" - product_type = "workfile" - - default_variant = "Main" - - def get_instance_attr_defs(self): - return [] - - def collect_instances(self): - root_node = nuke.root() - instance_data = api.get_node_data( - root_node, api.INSTANCE_DATA_KNOB - ) - - project_name = self.create_context.get_current_project_name() - folder_path = self.create_context.get_current_folder_path() - task_name = self.create_context.get_current_task_name() - host_name = self.create_context.host_name - - folder_entity = ayon_api.get_folder_by_path( - project_name, folder_path - ) - task_entity = ayon_api.get_task_by_name( - project_name, folder_entity["id"], task_name - ) - product_name = self.get_product_name( - project_name, - folder_entity, - task_entity, - self.default_variant, - host_name, - ) - instance_data.update({ - "folderPath": folder_path, - "task": task_name, - "variant": self.default_variant - }) - instance_data.update(self.get_dynamic_data( - project_name, - folder_entity, - task_entity, - self.default_variant, - host_name, - instance_data - )) - - instance = CreatedInstance( - self.product_type, product_name, instance_data, self - ) - instance.transient_data["node"] = root_node - self._add_instance_to_context(instance) - - def update_instances(self, update_list): - for created_inst, _changes in update_list: - instance_node = created_inst.transient_data["node"] - - set_node_data( - instance_node, - INSTANCE_DATA_KNOB, - created_inst.data_to_store() - ) - - def create(self, options=None): - # no need to create if it is created - # in `collect_instances` - pass diff --git a/server_addon/nuke/client/ayon_nuke/plugins/inventory/repair_old_loaders.py b/server_addon/nuke/client/ayon_nuke/plugins/inventory/repair_old_loaders.py deleted file mode 100644 index 11d65d4b8c..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/inventory/repair_old_loaders.py +++ /dev/null @@ -1,36 +0,0 @@ -from ayon_core.lib import Logger -from ayon_core.pipeline import InventoryAction -from ayon_nuke.api.lib import set_avalon_knob_data - - -class RepairOldLoaders(InventoryAction): - - label = "Repair Old Loaders" - icon = "gears" - color = "#cc0000" - - log = Logger.get_logger(__name__) - - def process(self, containers): - import nuke - new_loader = "LoadClip" - - for cdata in containers: - orig_loader = cdata["loader"] - orig_name = cdata["objectName"] - if orig_loader not in ["LoadSequence", "LoadMov"]: - self.log.warning( - "This repair action is only working on " - "`LoadSequence` and `LoadMov` Loaders") - continue - - new_name = orig_name.replace(orig_loader, new_loader) - node = nuke.toNode(cdata["objectName"]) - - cdata.update({ - "loader": new_loader, - "objectName": new_name - }) - node["name"].setValue(new_name) - # get data from avalon knob - set_avalon_knob_data(node, cdata) diff --git a/server_addon/nuke/client/ayon_nuke/plugins/inventory/select_containers.py b/server_addon/nuke/client/ayon_nuke/plugins/inventory/select_containers.py deleted file mode 100644 index f67c8c16e9..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/inventory/select_containers.py +++ /dev/null @@ -1,21 +0,0 @@ -from ayon_core.pipeline import InventoryAction -from ayon_nuke.api.command import viewer_update_and_undo_stop - - -class SelectContainers(InventoryAction): - - label = "Select Containers" - icon = "mouse-pointer" - color = "#d8d8d8" - - def process(self, containers): - import nuke - - nodes = [nuke.toNode(i["objectName"]) for i in containers] - - with viewer_update_and_undo_stop(): - # clear previous_selection - [n['selected'].setValue(False) for n in nodes] - # Select tool - for node in nodes: - node["selected"].setValue(True) diff --git a/server_addon/nuke/client/ayon_nuke/plugins/load/actions.py b/server_addon/nuke/client/ayon_nuke/plugins/load/actions.py deleted file mode 100644 index a4e2b156a3..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/load/actions.py +++ /dev/null @@ -1,77 +0,0 @@ -"""A module containing generic loader actions that will display in the Loader. - -""" - -from ayon_core.lib import Logger -from ayon_core.pipeline import load -from ayon_nuke.api import lib - -log = Logger.get_logger(__name__) - - -class SetFrameRangeLoader(load.LoaderPlugin): - """Set frame range excluding pre- and post-handles""" - - product_types = { - "animation", - "camera", - "write", - "yeticache", - "pointcache", - } - representations = {"*"} - extensions = {"*"} - - label = "Set frame range" - order = 11 - icon = "clock-o" - color = "white" - - def load(self, context, name, namespace, data): - version_entity = context["version"] - version_attributes = version_entity["attrib"] - - start = version_attributes.get("frameStart") - end = version_attributes.get("frameEnd") - - log.info("start: {}, end: {}".format(start, end)) - if start is None or end is None: - log.info("Skipping setting frame range because start or " - "end frame data is missing..") - return - - lib.update_frame_range(start, end) - - -class SetFrameRangeWithHandlesLoader(load.LoaderPlugin): - """Set frame range including pre- and post-handles""" - - product_types = { - "animation", - "camera", - "write", - "yeticache", - "pointcache", - } - representations = {"*"} - - label = "Set frame range (with handles)" - order = 12 - icon = "clock-o" - color = "white" - - def load(self, context, name, namespace, data): - version_attributes = context["version"]["attrib"] - start = version_attributes.get("frameStart") - end = version_attributes.get("frameEnd") - - if start is None or end is None: - print("Skipping setting frame range because start or " - "end frame data is missing..") - return - - # Include handles - start -= version_attributes.get("handleStart", 0) - end += version_attributes.get("handleEnd", 0) - - lib.update_frame_range(start, end) diff --git a/server_addon/nuke/client/ayon_nuke/plugins/load/load_backdrop.py b/server_addon/nuke/client/ayon_nuke/plugins/load/load_backdrop.py deleted file mode 100644 index 054a56d041..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/load/load_backdrop.py +++ /dev/null @@ -1,255 +0,0 @@ -import nuke -import nukescripts -import ayon_api - -from ayon_core.pipeline import ( - load, - get_representation_path, -) -from ayon_nuke.api.lib import ( - find_free_space_to_paste_nodes, - maintained_selection, - reset_selection, - select_nodes, - get_avalon_knob_data, - set_avalon_knob_data -) -from ayon_nuke.api.command import viewer_update_and_undo_stop -from ayon_nuke.api import containerise, update_container - - -class LoadBackdropNodes(load.LoaderPlugin): - """Loading Published Backdrop nodes (workfile, nukenodes)""" - - product_types = {"workfile", "nukenodes"} - representations = {"*"} - extensions = {"nk"} - - settings_category = "nuke" - - label = "Import Nuke Nodes" - order = 0 - icon = "eye" - color = "white" - node_color = "0x7533c1ff" - - def load(self, context, name, namespace, data): - """ - Loading function to import .nk file into script and wrap - it on backdrop - - Arguments: - context (dict): context of version - name (str): name of the version - namespace (str): namespace name - data (dict): compulsory attribute > not used - - Returns: - nuke node: containerised nuke node object - """ - - # get main variables - namespace = namespace or context["folder"]["name"] - version_entity = context["version"] - - version_attributes = version_entity["attrib"] - colorspace = version_attributes.get("colorSpace") - - object_name = "{}_{}".format(name, namespace) - - # prepare data for imprinting - data_imprint = { - "version": version_entity["version"], - "colorspaceInput": colorspace - } - - # add attributes from the version to imprint to metadata knob - for k in ["source", "fps"]: - data_imprint[k] = version_attributes[k] - - # getting file path - file = self.filepath_from_context(context).replace("\\", "/") - - # adding nodes to node graph - # just in case we are in group lets jump out of it - nuke.endGroup() - - # Get mouse position - n = nuke.createNode("NoOp") - xcursor, ycursor = (n.xpos(), n.ypos()) - reset_selection() - nuke.delete(n) - - bdn_frame = 50 - - with maintained_selection(): - - # add group from nk - nuke.nodePaste(file) - - # get all pasted nodes - new_nodes = list() - nodes = nuke.selectedNodes() - - # get pointer position in DAG - xpointer, ypointer = find_free_space_to_paste_nodes( - nodes, direction="right", offset=200 + bdn_frame - ) - - # reset position to all nodes and replace inputs and output - for n in nodes: - reset_selection() - xpos = (n.xpos() - xcursor) + xpointer - ypos = (n.ypos() - ycursor) + ypointer - n.setXYpos(xpos, ypos) - - # replace Input nodes for dots - if n.Class() in "Input": - dot = nuke.createNode("Dot") - new_name = n.name().replace("INP", "DOT") - dot.setName(new_name) - dot["label"].setValue(new_name) - dot.setXYpos(xpos, ypos) - new_nodes.append(dot) - - # rewire - dep = n.dependent() - for d in dep: - index = next((i for i, dpcy in enumerate( - d.dependencies()) - if n is dpcy), 0) - d.setInput(index, dot) - - # remove Input node - reset_selection() - nuke.delete(n) - continue - - # replace Input nodes for dots - elif n.Class() in "Output": - dot = nuke.createNode("Dot") - new_name = n.name() + "_DOT" - dot.setName(new_name) - dot["label"].setValue(new_name) - dot.setXYpos(xpos, ypos) - new_nodes.append(dot) - - # rewire - dep = next((d for d in n.dependencies()), None) - if dep: - dot.setInput(0, dep) - - # remove Input node - reset_selection() - nuke.delete(n) - continue - else: - new_nodes.append(n) - - # reselect nodes with new Dot instead of Inputs and Output - reset_selection() - select_nodes(new_nodes) - # place on backdrop - bdn = nukescripts.autoBackdrop() - - # add frame offset - xpos = bdn.xpos() - bdn_frame - ypos = bdn.ypos() - bdn_frame - bdwidth = bdn["bdwidth"].value() + (bdn_frame*2) - bdheight = bdn["bdheight"].value() + (bdn_frame*2) - - bdn["xpos"].setValue(xpos) - bdn["ypos"].setValue(ypos) - bdn["bdwidth"].setValue(bdwidth) - bdn["bdheight"].setValue(bdheight) - - bdn["name"].setValue(object_name) - bdn["label"].setValue("Version tracked frame: \n`{}`\n\nPLEASE DO NOT REMOVE OR MOVE \nANYTHING FROM THIS FRAME!".format(object_name)) - bdn["note_font_size"].setValue(20) - - return containerise( - node=bdn, - name=name, - namespace=namespace, - context=context, - loader=self.__class__.__name__, - data=data_imprint) - - def update(self, container, context): - """Update the Loader's path - - Nuke automatically tries to reset some variables when changing - the loader's path to a new file. These automatic changes are to its - inputs: - - """ - - # get main variables - # Get version from io - project_name = context["project"]["name"] - version_entity = context["version"] - repre_entity = context["representation"] - - # get corresponding node - GN = container["node"] - - file = get_representation_path(repre_entity).replace("\\", "/") - - name = container["name"] - namespace = container["namespace"] - object_name = "{}_{}".format(name, namespace) - - version_attributes = version_entity["attrib"] - colorspace = version_attributes.get("colorSpace") - - data_imprint = { - "representation": repre_entity["id"], - "version": version_entity["version"], - "colorspaceInput": colorspace, - } - - for k in ["source", "fps"]: - data_imprint[k] = version_attributes[k] - - # adding nodes to node graph - # just in case we are in group lets jump out of it - nuke.endGroup() - - with maintained_selection(): - xpos = GN.xpos() - ypos = GN.ypos() - avalon_data = get_avalon_knob_data(GN) - nuke.delete(GN) - # add group from nk - nuke.nodePaste(file) - - GN = nuke.selectedNode() - set_avalon_knob_data(GN, avalon_data) - GN.setXYpos(xpos, ypos) - GN["name"].setValue(object_name) - - # get all versions in list - last_version_entity = ayon_api.get_last_version_by_product_id( - project_name, version_entity["productId"], fields={"id"} - ) - - # change color of node - if version_entity["id"] == last_version_entity["id"]: - color_value = self.node_color - else: - color_value = "0xd88467ff" - GN["tile_color"].setValue(int(color_value, 16)) - - self.log.info( - "updated to version: {}".format(version_entity["version"]) - ) - - return update_container(GN, data_imprint) - - def switch(self, container, context): - self.update(container, context) - - def remove(self, container): - node = container["node"] - with viewer_update_and_undo_stop(): - nuke.delete(node) diff --git a/server_addon/nuke/client/ayon_nuke/plugins/load/load_camera_abc.py b/server_addon/nuke/client/ayon_nuke/plugins/load/load_camera_abc.py deleted file mode 100644 index 3930cf52fa..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/load/load_camera_abc.py +++ /dev/null @@ -1,198 +0,0 @@ -import nuke -import ayon_api - -from ayon_core.pipeline import ( - load, - get_representation_path, -) -from ayon_nuke.api import ( - containerise, - update_container, - viewer_update_and_undo_stop -) -from ayon_nuke.api.lib import ( - maintained_selection -) - - -class AlembicCameraLoader(load.LoaderPlugin): - """ - This will load alembic camera into script. - """ - - product_types = {"camera"} - representations = {"*"} - extensions = {"abc"} - - settings_category = "nuke" - - label = "Load Alembic Camera" - icon = "camera" - color = "orange" - node_color = "0x3469ffff" - - def load(self, context, name, namespace, data): - # get main variables - version_entity = context["version"] - - version_attributes = version_entity["attrib"] - first = version_attributes.get("frameStart") - last = version_attributes.get("frameEnd") - fps = version_attributes.get("fps") or nuke.root()["fps"].getValue() - - namespace = namespace or context["folder"]["name"] - object_name = "{}_{}".format(name, namespace) - - # prepare data for imprinting - # add additional metadata from the version to imprint to metadata knob - data_imprint = { - "frameStart": first, - "frameEnd": last, - "version": version_entity["version"], - } - for k in ["source", "fps"]: - data_imprint[k] = version_attributes[k] - - # getting file path - file = self.filepath_from_context(context).replace("\\", "/") - - with maintained_selection(): - camera_node = nuke.createNode( - "Camera2", - "name {} file {} read_from_file True".format( - object_name, file), - inpanel=False - ) - - camera_node.forceValidate() - camera_node["frame_rate"].setValue(float(fps)) - - # workaround because nuke's bug is not adding - # animation keys properly - xpos = camera_node.xpos() - ypos = camera_node.ypos() - nuke.nodeCopy("%clipboard%") - nuke.delete(camera_node) - nuke.nodePaste("%clipboard%") - camera_node = nuke.toNode(object_name) - camera_node.setXYpos(xpos, ypos) - - # color node by correct color by actual version - self.node_version_color( - context["project"]["name"], version_entity, camera_node - ) - - return containerise( - node=camera_node, - name=name, - namespace=namespace, - context=context, - loader=self.__class__.__name__, - data=data_imprint) - - def update(self, container, context): - """ - Called by Scene Inventory when look should be updated to current - version. - If any reference edits cannot be applied, eg. shader renamed and - material not present, reference is unloaded and cleaned. - All failed edits are highlighted to the user via message box. - - Args: - container: object that has look to be updated - representation: (dict): relationship data to get proper - representation from DB and persisted - data in .json - Returns: - None - """ - # Get version from io - version_entity = context["version"] - repre_entity = context["representation"] - - # get main variables - version_attributes = version_entity["attrib"] - first = version_attributes.get("frameStart") - last = version_attributes.get("frameEnd") - fps = version_attributes.get("fps") or nuke.root()["fps"].getValue() - - # prepare data for imprinting - data_imprint = { - "representation": repre_entity["id"], - "frameStart": first, - "frameEnd": last, - "version": version_entity["version"] - } - - # add attributes from the version to imprint to metadata knob - for k in ["source", "fps"]: - data_imprint[k] = version_attributes[k] - - # getting file path - file = get_representation_path(repre_entity).replace("\\", "/") - - with maintained_selection(): - camera_node = container["node"] - camera_node['selected'].setValue(True) - - # collect input output dependencies - dependencies = camera_node.dependencies() - dependent = camera_node.dependent() - - camera_node["frame_rate"].setValue(float(fps)) - camera_node["file"].setValue(file) - - # workaround because nuke's bug is - # not adding animation keys properly - xpos = camera_node.xpos() - ypos = camera_node.ypos() - nuke.nodeCopy("%clipboard%") - camera_name = camera_node.name() - nuke.delete(camera_node) - nuke.nodePaste("%clipboard%") - camera_node = nuke.toNode(camera_name) - camera_node.setXYpos(xpos, ypos) - - # link to original input nodes - for i, input in enumerate(dependencies): - camera_node.setInput(i, input) - # link to original output nodes - for d in dependent: - index = next((i for i, dpcy in enumerate( - d.dependencies()) - if camera_node is dpcy), 0) - d.setInput(index, camera_node) - - # color node by correct color by actual version - self.node_version_color( - context["project"]["name"], version_entity, camera_node - ) - - self.log.info( - "updated to version: {}".format(version_entity["version"]) - ) - - return update_container(camera_node, data_imprint) - - def node_version_color(self, project_name, version_entity, node): - """ Coloring a node by correct color by actual version - """ - # get all versions in list - last_version_entity = ayon_api.get_last_version_by_product_id( - project_name, version_entity["productId"], fields={"id"} - ) - - # change color of node - if version_entity["id"] == last_version_entity["id"]: - color_value = self.node_color - else: - color_value = "0xd88467ff" - node["tile_color"].setValue(int(color_value, 16)) - - def switch(self, container, context): - self.update(container, context) - - def remove(self, container): - node = container["node"] - with viewer_update_and_undo_stop(): - nuke.delete(node) diff --git a/server_addon/nuke/client/ayon_nuke/plugins/load/load_clip.py b/server_addon/nuke/client/ayon_nuke/plugins/load/load_clip.py deleted file mode 100644 index d1e38eea6b..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/load/load_clip.py +++ /dev/null @@ -1,584 +0,0 @@ -from copy import deepcopy - -import nuke -import qargparse -import ayon_api - -from ayon_core.lib import Logger -from ayon_core.pipeline import ( - get_representation_path, -) -from ayon_core.pipeline.colorspace import ( - get_imageio_file_rules_colorspace_from_filepath, - get_current_context_imageio_config_preset, -) -from ayon_nuke.api.lib import ( - get_imageio_input_colorspace, - maintained_selection -) -from ayon_nuke.api import ( - containerise, - update_container, - viewer_update_and_undo_stop, - colorspace_exists_on_node -) -from ayon_core.lib.transcoding import ( - VIDEO_EXTENSIONS, - IMAGE_EXTENSIONS -) -from ayon_nuke.api import plugin - - -class LoadClip(plugin.NukeLoader): - """Load clip into Nuke - - Either it is image sequence or video file. - """ - log = Logger.get_logger(__name__) - - product_types = { - "source", - "plate", - "render", - "prerender", - "review", - } - representations = {"*"} - extensions = set( - ext.lstrip(".") for ext in IMAGE_EXTENSIONS.union(VIDEO_EXTENSIONS) - ) - - settings_category = "nuke" - - label = "Load Clip" - order = -20 - icon = "file-video-o" - color = "white" - - # Loaded from settings - representations_include = [] - - script_start = int(nuke.root()["first_frame"].value()) - - # option gui - options_defaults = { - "start_at_workfile": True, - "add_retime": True, - "deep_exr": False - } - - node_name_template = "{class_name}_{ext}" - - @classmethod - def get_options(cls, *args): - return [ - qargparse.Boolean( - "start_at_workfile", - help="Load at workfile start frame", - default=cls.options_defaults["start_at_workfile"] - ), - qargparse.Boolean( - "add_retime", - help="Load with retime", - default=cls.options_defaults["add_retime"] - ), - qargparse.Boolean( - "deep_exr", - help="Read with deep exr", - default=cls.options_defaults["deep_exr"] - ) - ] - - @classmethod - def get_representations(cls): - return cls.representations_include or cls.representations - - def load(self, context, name, namespace, options): - """Load asset via database.""" - project_name = context["project"]["name"] - repre_entity = context["representation"] - version_entity = context["version"] - version_attributes = version_entity["attrib"] - version_data = version_entity["data"] - - # reset container id so it is always unique for each instance - self.reset_container_id() - - is_sequence = len(repre_entity["files"]) > 1 - - if is_sequence: - context["representation"] = ( - self._representation_with_hash_in_frame(repre_entity) - ) - - filepath = self.filepath_from_context(context) - filepath = filepath.replace("\\", "/") - self.log.debug("_ filepath: {}".format(filepath)) - - start_at_workfile = options.get( - "start_at_workfile", self.options_defaults["start_at_workfile"]) - - add_retime = options.get( - "add_retime", self.options_defaults["add_retime"]) - - deep_exr = options.get( - "deep_exr", self.options_defaults["deep_exr"]) - - repre_id = repre_entity["id"] - - self.log.debug( - "Representation id `{}` ".format(repre_id)) - - self.handle_start = version_attributes.get("handleStart", 0) - self.handle_end = version_attributes.get("handleEnd", 0) - - first = version_attributes.get("frameStart") - last = version_attributes.get("frameEnd") - first -= self.handle_start - last += self.handle_end - - if not is_sequence: - duration = last - first - first = 1 - last = first + duration - - # If a slate is present, the frame range is 1 frame longer for movies, - # but file sequences its the first frame that is 1 frame lower. - slate_frames = repre_entity["data"].get("slateFrames", 0) - extension = "." + repre_entity["context"]["ext"] - - if extension in VIDEO_EXTENSIONS: - last += slate_frames - - files_count = len(repre_entity["files"]) - if extension in IMAGE_EXTENSIONS and files_count != 1: - first -= slate_frames - - # Fallback to folder name when namespace is None - if namespace is None: - namespace = context["folder"]["name"] - - if not filepath: - self.log.warning( - "Representation id `{}` is failing to load".format(repre_id)) - return - - read_name = self._get_node_name(context) - read_node = None - if deep_exr: - # Create the Loader with the filename path set - read_node = nuke.createNode( - "DeepRead", - "name {}".format(read_name), - inpanel=False - ) - else: - # Create the Loader with the filename path set - read_node = nuke.createNode( - "Read", - "name {}".format(read_name), - inpanel=False - ) - - # get colorspace - colorspace = ( - repre_entity["data"].get("colorspace") - or version_attributes.get("colorSpace") - ) - - # to avoid multiple undo steps for rest of process - # we will switch off undo-ing - with viewer_update_and_undo_stop(): - read_node["file"].setValue(filepath) - if read_node.Class() == "Read": - self.set_colorspace_to_node( - read_node, - filepath, - project_name, - version_entity, - repre_entity - ) - - self._set_range_to_node( - read_node, first, last, start_at_workfile, slate_frames - ) - - version_name = version_entity["version"] - if version_name < 0: - version_name = "hero" - - data_imprint = { - "version": version_name, - "db_colorspace": colorspace - } - - # add attributes from the version to imprint metadata knob - for key in [ - "frameStart", - "frameEnd", - "source", - "fps", - "handleStart", - "handleEnd", - ]: - value = version_attributes.get(key, str(None)) - if isinstance(value, str): - value = value.replace("\\", "/") - data_imprint[key] = value - - if add_retime and version_data.get("retime"): - data_imprint["addRetime"] = True - - read_node["tile_color"].setValue(int("0x4ecd25ff", 16)) - - container = containerise( - read_node, - name=name, - namespace=namespace, - context=context, - loader=self.__class__.__name__, - data=data_imprint) - - if add_retime and version_data.get("retime"): - self._make_retimes(read_node, version_data) - - self.set_as_member(read_node) - - return container - - def switch(self, container, context): - self.update(container, context) - - def _representation_with_hash_in_frame(self, repre_entity): - """Convert frame key value to padded hash - - Args: - repre_entity (dict): Representation entity. - - Returns: - dict: altered representation data - - """ - new_repre_entity = deepcopy(repre_entity) - context = new_repre_entity["context"] - - # Get the frame from the context and hash it - frame = context["frame"] - hashed_frame = "#" * len(str(frame)) - - # Replace the frame with the hash in the originalBasename - if ( - "{originalBasename}" in new_repre_entity["attrib"]["template"] - ): - origin_basename = context["originalBasename"] - context["originalBasename"] = origin_basename.replace( - frame, hashed_frame - ) - - # Replace the frame with the hash in the frame - new_repre_entity["context"]["frame"] = hashed_frame - return new_repre_entity - - def update(self, container, context): - """Update the Loader's path - - Nuke automatically tries to reset some variables when changing - the loader's path to a new file. These automatic changes are to its - inputs: - - """ - - project_name = context["project"]["name"] - version_entity = context["version"] - repre_entity = context["representation"] - - version_attributes = version_entity["attrib"] - version_data = version_entity["data"] - - is_sequence = len(repre_entity["files"]) > 1 - - read_node = container["node"] - - if is_sequence: - repre_entity = self._representation_with_hash_in_frame( - repre_entity - ) - - filepath = ( - get_representation_path(repre_entity) - ).replace("\\", "/") - self.log.debug("_ filepath: {}".format(filepath)) - - start_at_workfile = "start at" in read_node['frame_mode'].value() - - add_retime = [ - key for key in read_node.knobs().keys() - if "addRetime" in key - ] - - repre_id = repre_entity["id"] - - # colorspace profile - colorspace = ( - repre_entity["data"].get("colorspace") - or version_attributes.get("colorSpace") - ) - - self.handle_start = version_attributes.get("handleStart", 0) - self.handle_end = version_attributes.get("handleEnd", 0) - - first = version_attributes.get("frameStart") - last = version_attributes.get("frameEnd") - first -= self.handle_start - last += self.handle_end - - if not is_sequence: - duration = last - first - first = 1 - last = first + duration - - if not filepath: - self.log.warning( - "Representation id `{}` is failing to load".format(repre_id)) - return - - read_node["file"].setValue(filepath) - - # to avoid multiple undo steps for rest of process - # we will switch off undo-ing - with viewer_update_and_undo_stop(): - if read_node.Class() == "Read": - self.set_colorspace_to_node( - read_node, - filepath, - project_name, - version_entity, - repre_entity - ) - - self._set_range_to_node(read_node, first, last, start_at_workfile) - - updated_dict = { - "representation": repre_entity["id"], - "frameStart": str(first), - "frameEnd": str(last), - "version": str(version_entity["version"]), - "db_colorspace": colorspace, - "source": version_attributes.get("source"), - "handleStart": str(self.handle_start), - "handleEnd": str(self.handle_end), - "fps": str(version_attributes.get("fps")) - } - - last_version_entity = ayon_api.get_last_version_by_product_id( - project_name, version_entity["productId"], fields={"id"} - ) - # change color of read_node - if version_entity["id"] == last_version_entity["id"]: - color_value = "0x4ecd25ff" - else: - color_value = "0xd84f20ff" - read_node["tile_color"].setValue(int(color_value, 16)) - - # Update the imprinted representation - update_container(read_node, updated_dict) - self.log.info( - "updated to version: {}".format(version_entity["version"]) - ) - - if add_retime and version_data.get("retime"): - self._make_retimes(read_node, version_data) - else: - self.clear_members(read_node) - - self.set_as_member(read_node) - - def set_colorspace_to_node( - self, - read_node, - filepath, - project_name, - version_entity, - repre_entity, - ): - """Set colorspace to read node. - - Sets colorspace with available names validation. - - Args: - read_node (nuke.Node): The nuke's read node - filepath (str): File path. - project_name (str): Project name. - version_entity (dict): Version entity. - repre_entity (dict): Representation entity. - - """ - used_colorspace = self._get_colorspace_data( - project_name, version_entity, repre_entity, filepath - ) - if ( - used_colorspace - and colorspace_exists_on_node(read_node, used_colorspace) - ): - self.log.info(f"Used colorspace: {used_colorspace}") - read_node["colorspace"].setValue(used_colorspace) - else: - self.log.info("Colorspace not set...") - - def remove(self, container): - read_node = container["node"] - assert read_node.Class() == "Read", "Must be Read" - - with viewer_update_and_undo_stop(): - members = self.get_members(read_node) - nuke.delete(read_node) - for member in members: - nuke.delete(member) - - def _set_range_to_node( - self, read_node, first, last, start_at_workfile, slate_frames=0 - ): - read_node['origfirst'].setValue(int(first)) - read_node['first'].setValue(int(first)) - read_node['origlast'].setValue(int(last)) - read_node['last'].setValue(int(last)) - - # set start frame depending on workfile or version - if start_at_workfile: - read_node['frame_mode'].setValue("start at") - - start_frame = self.script_start - slate_frames - - read_node['frame'].setValue(str(start_frame)) - - def _make_retimes(self, parent_node, version_data): - ''' Create all retime and timewarping nodes with copied animation ''' - speed = version_data.get('speed', 1) - time_warp_nodes = version_data.get('timewarps', []) - last_node = None - source_id = self.get_container_id(parent_node) - self.log.debug("__ source_id: {}".format(source_id)) - self.log.debug("__ members: {}".format( - self.get_members(parent_node))) - - dependent_nodes = self.clear_members(parent_node) - - with maintained_selection(): - parent_node['selected'].setValue(True) - - if speed != 1: - rtn = nuke.createNode( - "Retime", - "speed {}".format(speed)) - - rtn["before"].setValue("continue") - rtn["after"].setValue("continue") - rtn["input.first_lock"].setValue(True) - rtn["input.first"].setValue( - self.script_start - ) - self.set_as_member(rtn) - last_node = rtn - - if time_warp_nodes != []: - start_anim = self.script_start + (self.handle_start / speed) - for timewarp in time_warp_nodes: - twn = nuke.createNode( - timewarp["Class"], - "name {}".format(timewarp["name"]) - ) - if isinstance(timewarp["lookup"], list): - # if array for animation - twn["lookup"].setAnimated() - for i, value in enumerate(timewarp["lookup"]): - twn["lookup"].setValueAt( - (start_anim + i) + value, - (start_anim + i)) - else: - # if static value `int` - twn["lookup"].setValue(timewarp["lookup"]) - - self.set_as_member(twn) - last_node = twn - - if dependent_nodes: - # connect to original inputs - for i, n in enumerate(dependent_nodes): - last_node.setInput(i, n) - - def _get_node_name(self, context): - folder_entity = context["folder"] - product_name = context["product"]["name"] - repre_entity = context["representation"] - - folder_name = folder_entity["name"] - repre_cont = repre_entity["context"] - name_data = { - "folder": { - "name": folder_name, - }, - "product": { - "name": product_name, - }, - "asset": folder_name, - "subset": product_name, - "representation": repre_entity["name"], - "ext": repre_cont["representation"], - "id": repre_entity["id"], - "class_name": self.__class__.__name__ - } - - return self.node_name_template.format(**name_data) - - def _get_colorspace_data( - self, project_name, version_entity, repre_entity, filepath - ): - """Get colorspace data from version and representation documents - - Args: - project_name (str): Project name. - version_entity (dict): Version entity. - repre_entity (dict): Representation entity. - filepath (str): File path. - - Returns: - Any[str,None]: colorspace name or None - """ - # Get backward compatible colorspace key. - colorspace = repre_entity["data"].get("colorspace") - self.log.debug( - f"Colorspace from representation colorspace: {colorspace}" - ) - - # Get backward compatible version data key if colorspace is not found. - if not colorspace: - colorspace = version_entity["attrib"].get("colorSpace") - self.log.debug( - f"Colorspace from version colorspace: {colorspace}" - ) - - # Get colorspace from representation colorspaceData if colorspace is - # not found. - if not colorspace: - colorspace_data = repre_entity["data"].get("colorspaceData", {}) - colorspace = colorspace_data.get("colorspace") - self.log.debug( - f"Colorspace from representation colorspaceData: {colorspace}" - ) - - config_data = get_current_context_imageio_config_preset() - # check if any filerules are not applicable - new_parsed_colorspace = get_imageio_file_rules_colorspace_from_filepath( # noqa - filepath, "nuke", project_name, config_data=config_data - ) - self.log.debug(f"Colorspace new filerules: {new_parsed_colorspace}") - - # colorspace from `project_settings/nuke/imageio/regexInputs` - old_parsed_colorspace = get_imageio_input_colorspace(filepath) - self.log.debug(f"Colorspace old filerules: {old_parsed_colorspace}") - - return ( - new_parsed_colorspace - or old_parsed_colorspace - or colorspace - ) diff --git a/server_addon/nuke/client/ayon_nuke/plugins/load/load_effects.py b/server_addon/nuke/client/ayon_nuke/plugins/load/load_effects.py deleted file mode 100644 index e923a02424..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/load/load_effects.py +++ /dev/null @@ -1,361 +0,0 @@ -import json -from collections import OrderedDict -import nuke -import six -import ayon_api - -from ayon_core.pipeline import ( - load, - get_representation_path, -) -from ayon_nuke.api import ( - containerise, - update_container, - viewer_update_and_undo_stop -) - - -class LoadEffects(load.LoaderPlugin): - """Loading colorspace soft effect exported from nukestudio""" - - product_types = {"effect"} - representations = {"*"} - extensions = {"json"} - - settings_category = "nuke" - - label = "Load Effects - nodes" - order = 0 - icon = "cc" - color = "white" - ignore_attr = ["useLifetime"] - - def load(self, context, name, namespace, data): - """ - Loading function to get the soft effects to particular read node - - Arguments: - context (dict): context of version - name (str): name of the version - namespace (str): namespace name - data (dict): compulsory attribute > not used - - Returns: - nuke node: containerised nuke node object - """ - # get main variables - version_entity = context["version"] - - version_attributes = version_entity["attrib"] - first = version_attributes.get("frameStart") - last = version_attributes.get("frameEnd") - colorspace = version_attributes.get("colorSpace") - - workfile_first_frame = int(nuke.root()["first_frame"].getValue()) - namespace = namespace or context["folder"]["name"] - object_name = "{}_{}".format(name, namespace) - - # prepare data for imprinting - data_imprint = { - "frameStart": first, - "frameEnd": last, - "version": version_entity["version"], - "colorspaceInput": colorspace, - } - - # add additional metadata from the version to imprint to Avalon knob - for k in [ - "frameStart", - "frameEnd", - "handleStart", - "handleEnd", - "source", - "fps" - ]: - data_imprint[k] = version_attributes[k] - - # getting file path - file = self.filepath_from_context(context).replace("\\", "/") - - # getting data from json file with unicode conversion - with open(file, "r") as f: - json_f = {self.byteify(key): self.byteify(value) - for key, value in json.load(f).items()} - - # get correct order of nodes by positions on track and subtrack - nodes_order = self.reorder_nodes(json_f) - - # adding nodes to node graph - # just in case we are in group lets jump out of it - nuke.endGroup() - - GN = nuke.createNode( - "Group", - "name {}_1".format(object_name), - inpanel=False - ) - - # adding content to the group node - with GN: - pre_node = nuke.createNode("Input") - pre_node["name"].setValue("rgb") - - for ef_name, ef_val in nodes_order.items(): - node = nuke.createNode(ef_val["class"]) - for k, v in ef_val["node"].items(): - if k in self.ignore_attr: - continue - - try: - node[k].value() - except NameError as e: - self.log.warning(e) - continue - - if isinstance(v, list) and len(v) > 4: - node[k].setAnimated() - for i, value in enumerate(v): - if isinstance(value, list): - for ci, cv in enumerate(value): - node[k].setValueAt( - cv, - (workfile_first_frame + i), - ci) - else: - node[k].setValueAt( - value, - (workfile_first_frame + i)) - else: - node[k].setValue(v) - node.setInput(0, pre_node) - pre_node = node - - output = nuke.createNode("Output") - output.setInput(0, pre_node) - - # try to find parent read node - self.connect_read_node(GN, namespace, json_f["assignTo"]) - - GN["tile_color"].setValue(int("0x3469ffff", 16)) - - self.log.info("Loaded lut setup: `{}`".format(GN["name"].value())) - - return containerise( - node=GN, - name=name, - namespace=namespace, - context=context, - loader=self.__class__.__name__, - data=data_imprint) - - def update(self, container, context): - """Update the Loader's path - - Nuke automatically tries to reset some variables when changing - the loader's path to a new file. These automatic changes are to its - inputs: - - """ - # get main variables - # Get version from io - project_name = context["project"]["name"] - version_entity = context["version"] - repre_entity = context["representation"] - - # get corresponding node - GN = container["node"] - - file = get_representation_path(repre_entity).replace("\\", "/") - - version_attributes = version_entity["attrib"] - first = version_attributes.get("frameStart") - last = version_attributes.get("frameEnd") - colorspace = version_attributes.get("colorSpace") - - workfile_first_frame = int(nuke.root()["first_frame"].getValue()) - namespace = container["namespace"] - - data_imprint = { - "representation": repre_entity["id"], - "frameStart": first, - "frameEnd": last, - "version": version_entity["version"], - "colorspaceInput": colorspace - } - - for k in [ - "frameStart", - "frameEnd", - "handleStart", - "handleEnd", - "source", - "fps", - ]: - data_imprint[k] = version_attributes[k] - - # Update the imprinted representation - update_container( - GN, - data_imprint - ) - - # getting data from json file with unicode conversion - with open(file, "r") as f: - json_f = {self.byteify(key): self.byteify(value) - for key, value in json.load(f).items()} - - # get correct order of nodes by positions on track and subtrack - nodes_order = self.reorder_nodes(json_f) - - # adding nodes to node graph - # just in case we are in group lets jump out of it - nuke.endGroup() - - # adding content to the group node - with GN: - # first remove all nodes - [nuke.delete(n) for n in nuke.allNodes()] - - # create input node - pre_node = nuke.createNode("Input") - pre_node["name"].setValue("rgb") - - for _, ef_val in nodes_order.items(): - node = nuke.createNode(ef_val["class"]) - for k, v in ef_val["node"].items(): - if k in self.ignore_attr: - continue - - try: - node[k].value() - except NameError as e: - self.log.warning(e) - continue - - if isinstance(v, list) and len(v) > 4: - node[k].setAnimated() - for i, value in enumerate(v): - if isinstance(value, list): - for ci, cv in enumerate(value): - node[k].setValueAt( - cv, - (workfile_first_frame + i), - ci) - else: - node[k].setValueAt( - value, - (workfile_first_frame + i)) - else: - node[k].setValue(v) - node.setInput(0, pre_node) - pre_node = node - - # create output node - output = nuke.createNode("Output") - output.setInput(0, pre_node) - - # try to find parent read node - self.connect_read_node(GN, namespace, json_f["assignTo"]) - - last_version_entity = ayon_api.get_last_version_by_product_id( - project_name, version_entity["productId"], fields={"id"} - ) - - # change color of node - if version_entity["id"] == last_version_entity["id"]: - color_value = "0x3469ffff" - else: - color_value = "0xd84f20ff" - - GN["tile_color"].setValue(int(color_value, 16)) - - self.log.info( - "updated to version: {}".format(version_entity["version"]) - ) - - def connect_read_node(self, group_node, namespace, product_name): - """ - Finds read node and selects it - - Arguments: - namespace (str): namespace name - - Returns: - nuke node: node is selected - None: if nothing found - """ - search_name = "{0}_{1}".format(namespace, product_name) - - node = [ - n for n in nuke.allNodes(filter="Read") - if search_name in n["file"].value() - ] - if len(node) > 0: - rn = node[0] - else: - rn = None - - # Parent read node has been found - # solving connections - if rn: - dep_nodes = rn.dependent() - - if len(dep_nodes) > 0: - for dn in dep_nodes: - dn.setInput(0, group_node) - - group_node.setInput(0, rn) - group_node.autoplace() - - def reorder_nodes(self, data): - new_order = OrderedDict() - trackNums = [v["trackIndex"] for k, v in data.items() - if isinstance(v, dict)] - subTrackNums = [v["subTrackIndex"] for k, v in data.items() - if isinstance(v, dict)] - - for trackIndex in range( - min(trackNums), max(trackNums) + 1): - for subTrackIndex in range( - min(subTrackNums), max(subTrackNums) + 1): - item = self.get_item(data, trackIndex, subTrackIndex) - if item is not {}: - new_order.update(item) - return new_order - - def get_item(self, data, trackIndex, subTrackIndex): - return {key: val for key, val in data.items() - if isinstance(val, dict) - if subTrackIndex == val["subTrackIndex"] - if trackIndex == val["trackIndex"]} - - def byteify(self, input): - """ - Converts unicode strings to strings - It goes through all dictionary - - Arguments: - input (dict/str): input - - Returns: - dict: with fixed values and keys - - """ - - if isinstance(input, dict): - return {self.byteify(key): self.byteify(value) - for key, value in input.items()} - elif isinstance(input, list): - return [self.byteify(element) for element in input] - elif isinstance(input, six.text_type): - return str(input) - else: - return input - - def switch(self, container, context): - self.update(container, context) - - def remove(self, container): - node = container["node"] - with viewer_update_and_undo_stop(): - nuke.delete(node) diff --git a/server_addon/nuke/client/ayon_nuke/plugins/load/load_effects_ip.py b/server_addon/nuke/client/ayon_nuke/plugins/load/load_effects_ip.py deleted file mode 100644 index ce7e7debeb..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/load/load_effects_ip.py +++ /dev/null @@ -1,372 +0,0 @@ -import json -from collections import OrderedDict -import six -import nuke -import ayon_api - -from ayon_core.pipeline import ( - load, - get_representation_path, -) -from ayon_nuke.api import lib -from ayon_nuke.api import ( - containerise, - update_container, - viewer_update_and_undo_stop -) - - -class LoadEffectsInputProcess(load.LoaderPlugin): - """Loading colorspace soft effect exported from nukestudio""" - - product_types = {"effect"} - representations = {"*"} - extensions = {"json"} - - settings_category = "nuke" - - label = "Load Effects - Input Process" - order = 0 - icon = "eye" - color = "#cc0000" - ignore_attr = ["useLifetime"] - - def load(self, context, name, namespace, data): - """ - Loading function to get the soft effects to particular read node - - Arguments: - context (dict): context of version - name (str): name of the version - namespace (str): namespace name - data (dict): compulsory attribute > not used - - Returns: - nuke node: containerised nuke node object - """ - - # get main variables - version_entity = context["version"] - - version_attributes = version_entity["attrib"] - first = version_attributes.get("frameStart") - last = version_attributes.get("frameEnd") - colorspace = version_attributes.get("colorSpace") - - workfile_first_frame = int(nuke.root()["first_frame"].getValue()) - namespace = namespace or context["folder"]["name"] - object_name = "{}_{}".format(name, namespace) - - # prepare data for imprinting - data_imprint = { - "frameStart": first, - "frameEnd": last, - "version": version_entity["version"], - "colorspaceInput": colorspace, - } - # add additional metadata from the version to imprint to Avalon knob - for k in [ - "frameStart", - "frameEnd", - "handleStart", - "handleEnd", - "source", - "fps" - ]: - data_imprint[k] = version_attributes[k] - - # getting file path - file = self.filepath_from_context(context).replace("\\", "/") - - # getting data from json file with unicode conversion - with open(file, "r") as f: - json_f = {self.byteify(key): self.byteify(value) - for key, value in json.load(f).items()} - - # get correct order of nodes by positions on track and subtrack - nodes_order = self.reorder_nodes(json_f) - - # adding nodes to node graph - # just in case we are in group lets jump out of it - nuke.endGroup() - - GN = nuke.createNode( - "Group", - "name {}_1".format(object_name), - inpanel=False - ) - - # adding content to the group node - with GN: - pre_node = nuke.createNode("Input") - pre_node["name"].setValue("rgb") - - for _, ef_val in nodes_order.items(): - node = nuke.createNode(ef_val["class"]) - for k, v in ef_val["node"].items(): - if k in self.ignore_attr: - continue - - try: - node[k].value() - except NameError as e: - self.log.warning(e) - continue - - if isinstance(v, list) and len(v) > 4: - node[k].setAnimated() - for i, value in enumerate(v): - if isinstance(value, list): - for ci, cv in enumerate(value): - node[k].setValueAt( - cv, - (workfile_first_frame + i), - ci) - else: - node[k].setValueAt( - value, - (workfile_first_frame + i)) - else: - node[k].setValue(v) - - node.setInput(0, pre_node) - pre_node = node - - output = nuke.createNode("Output") - output.setInput(0, pre_node) - - # try to place it under Viewer1 - if not self.connect_active_viewer(GN): - nuke.delete(GN) - return - - GN["tile_color"].setValue(int("0x3469ffff", 16)) - - self.log.info("Loaded lut setup: `{}`".format(GN["name"].value())) - - return containerise( - node=GN, - name=name, - namespace=namespace, - context=context, - loader=self.__class__.__name__, - data=data_imprint) - - def update(self, container, context): - """Update the Loader's path - - Nuke automatically tries to reset some variables when changing - the loader's path to a new file. These automatic changes are to its - inputs: - - """ - - # get main variables - # Get version from io - project_name = context["project"]["name"] - version_entity = context["version"] - repre_entity = context["representation"] - - # get corresponding node - GN = container["node"] - - file = get_representation_path(repre_entity).replace("\\", "/") - - version_attributes = version_entity["attrib"] - first = version_attributes.get("frameStart") - last = version_attributes.get("frameEnd") - colorspace = version_attributes.get("colorSpace") - - workfile_first_frame = int(nuke.root()["first_frame"].getValue()) - - data_imprint = { - "representation": repre_entity["id"], - "frameStart": first, - "frameEnd": last, - "version": version_entity["version"], - "colorspaceInput": colorspace, - } - - for k in [ - "frameStart", - "frameEnd", - "handleStart", - "handleEnd", - "source", - "fps" - ]: - data_imprint[k] = version_attributes[k] - - # Update the imprinted representation - update_container( - GN, - data_imprint - ) - - # getting data from json file with unicode conversion - with open(file, "r") as f: - json_f = {self.byteify(key): self.byteify(value) - for key, value in json.load(f).items()} - - # get correct order of nodes by positions on track and subtrack - nodes_order = self.reorder_nodes(json_f) - - # adding nodes to node graph - # just in case we are in group lets jump out of it - nuke.endGroup() - - # adding content to the group node - with GN: - # first remove all nodes - [nuke.delete(n) for n in nuke.allNodes()] - - # create input node - pre_node = nuke.createNode("Input") - pre_node["name"].setValue("rgb") - - for _, ef_val in nodes_order.items(): - node = nuke.createNode(ef_val["class"]) - for k, v in ef_val["node"].items(): - if k in self.ignore_attr: - continue - - try: - node[k].value() - except NameError as e: - self.log.warning(e) - continue - - if isinstance(v, list) and len(v) > 4: - node[k].setAnimated() - for i, value in enumerate(v): - if isinstance(value, list): - for ci, cv in enumerate(value): - node[k].setValueAt( - cv, - (workfile_first_frame + i), - ci) - else: - node[k].setValueAt( - value, - (workfile_first_frame + i)) - else: - node[k].setValue(v) - node.setInput(0, pre_node) - pre_node = node - - # create output node - output = nuke.createNode("Output") - output.setInput(0, pre_node) - - # get all versions in list - last_version_entity = ayon_api.get_last_version_by_product_id( - project_name, version_entity["productId"], fields={"id"} - ) - - # change color of node - if version_entity["id"] == last_version_entity["id"]: - color_value = "0x3469ffff" - else: - color_value = "0xd84f20ff" - GN["tile_color"].setValue(int(color_value, 16)) - - self.log.info("updated to version: {}".format(version_entity["name"])) - - def connect_active_viewer(self, group_node): - """ - Finds Active viewer and - place the node under it, also adds - name of group into Input Process of the viewer - - Arguments: - group_node (nuke node): nuke group node object - - """ - group_node_name = group_node["name"].value() - - viewer = [n for n in nuke.allNodes() if "Viewer1" in n["name"].value()] - if len(viewer) > 0: - viewer = viewer[0] - else: - msg = str("Please create Viewer node before you " - "run this action again") - self.log.error(msg) - nuke.message(msg) - return None - - # get coordinates of Viewer1 - xpos = viewer["xpos"].value() - ypos = viewer["ypos"].value() - - ypos += 150 - - viewer["ypos"].setValue(ypos) - - # set coordinates to group node - group_node["xpos"].setValue(xpos) - group_node["ypos"].setValue(ypos + 50) - - # add group node name to Viewer Input Process - viewer["input_process_node"].setValue(group_node_name) - - # put backdrop under - lib.create_backdrop( - label="Input Process", - layer=2, - nodes=[viewer, group_node], - color="0x7c7faaff") - - return True - - def reorder_nodes(self, data): - new_order = OrderedDict() - trackNums = [v["trackIndex"] for k, v in data.items() - if isinstance(v, dict)] - subTrackNums = [v["subTrackIndex"] for k, v in data.items() - if isinstance(v, dict)] - - for trackIndex in range( - min(trackNums), max(trackNums) + 1): - for subTrackIndex in range( - min(subTrackNums), max(subTrackNums) + 1): - item = self.get_item(data, trackIndex, subTrackIndex) - if item is not {}: - new_order.update(item) - return new_order - - def get_item(self, data, trackIndex, subTrackIndex): - return {key: val for key, val in data.items() - if isinstance(val, dict) - if subTrackIndex == val["subTrackIndex"] - if trackIndex == val["trackIndex"]} - - def byteify(self, input): - """ - Converts unicode strings to strings - It goes through all dictionary - - Arguments: - input (dict/str): input - - Returns: - dict: with fixed values and keys - - """ - - if isinstance(input, dict): - return {self.byteify(key): self.byteify(value) - for key, value in input.items()} - elif isinstance(input, list): - return [self.byteify(element) for element in input] - elif isinstance(input, six.text_type): - return str(input) - else: - return input - - def switch(self, container, context): - self.update(container, context) - - def remove(self, container): - node = container["node"] - with viewer_update_and_undo_stop(): - nuke.delete(node) diff --git a/server_addon/nuke/client/ayon_nuke/plugins/load/load_gizmo.py b/server_addon/nuke/client/ayon_nuke/plugins/load/load_gizmo.py deleted file mode 100644 index 1c91af0c1c..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/load/load_gizmo.py +++ /dev/null @@ -1,190 +0,0 @@ -import nuke -import ayon_api - -from ayon_core.pipeline import ( - load, - get_representation_path, -) -from ayon_nuke.api.lib import ( - maintained_selection, - get_avalon_knob_data, - set_avalon_knob_data, - swap_node_with_dependency, -) -from ayon_nuke.api import ( - containerise, - update_container, - viewer_update_and_undo_stop -) - - -class LoadGizmo(load.LoaderPlugin): - """Loading nuke Gizmo""" - - product_types = {"gizmo"} - representations = {"*"} - extensions = {"nk"} - - settings_category = "nuke" - - label = "Load Gizmo" - order = 0 - icon = "dropbox" - color = "white" - node_color = "0x75338eff" - - def load(self, context, name, namespace, data): - """ - Loading function to get Gizmo into node graph - - Arguments: - context (dict): context of version - name (str): name of the version - namespace (str): namespace name - data (dict): compulsory attribute > not used - - Returns: - nuke node: containerized nuke node object - """ - - # get main variables - version_entity = context["version"] - version_attributes = version_entity["attrib"] - - first = version_attributes.get("frameStart") - last = version_attributes.get("frameEnd") - colorspace = version_attributes.get("colorSpace") - - namespace = namespace or context["folder"]["name"] - object_name = "{}_{}".format(name, namespace) - - # prepare data for imprinting - data_imprint = { - "frameStart": first, - "frameEnd": last, - "version": version_entity["version"], - "colorspaceInput": colorspace - } - - # add attributes from the version to imprint to metadata knob - for k in [ - "frameStart", - "frameEnd", - "handleStart", - "handleEnd", - "source", - "fps" - ]: - data_imprint[k] = version_attributes[k] - - # getting file path - file = self.filepath_from_context(context).replace("\\", "/") - - # adding nodes to node graph - # just in case we are in group lets jump out of it - nuke.endGroup() - - with maintained_selection(): - # add group from nk - nuke.nodePaste(file) - - group_node = nuke.selectedNode() - - group_node["name"].setValue(object_name) - - return containerise( - node=group_node, - name=name, - namespace=namespace, - context=context, - loader=self.__class__.__name__, - data=data_imprint) - - def update(self, container, context): - """Update the Loader's path - - Nuke automatically tries to reset some variables when changing - the loader's path to a new file. These automatic changes are to its - inputs: - - """ - - # get main variables - # Get version from io - project_name = context["project"]["name"] - version_entity = context["version"] - repre_entity = context["representation"] - - version_attributes = version_entity["attrib"] - - # get corresponding node - group_node = container["node"] - - file = get_representation_path(repre_entity).replace("\\", "/") - - first = version_attributes.get("frameStart") - last = version_attributes.get("frameEnd") - colorspace = version_attributes.get("colorSpace") - - data_imprint = { - "representation": repre_entity["id"], - "frameStart": first, - "frameEnd": last, - "version": version_entity["version"], - "colorspaceInput": colorspace - } - - for k in [ - "frameStart", - "frameEnd", - "handleStart", - "handleEnd", - "source", - "fps" - ]: - data_imprint[k] = version_attributes[k] - - # capture pipeline metadata - avalon_data = get_avalon_knob_data(group_node) - - # adding nodes to node graph - # just in case we are in group lets jump out of it - nuke.endGroup() - - with maintained_selection([group_node]): - # insert nuke script to the script - nuke.nodePaste(file) - # convert imported to selected node - new_group_node = nuke.selectedNode() - # swap nodes with maintained connections - with swap_node_with_dependency( - group_node, new_group_node) as node_name: - new_group_node["name"].setValue(node_name) - # set updated pipeline metadata - set_avalon_knob_data(new_group_node, avalon_data) - - last_version_entity = ayon_api.get_last_version_by_product_id( - project_name, version_entity["productId"], fields={"id"} - ) - - # change color of node - if version_entity["id"] == last_version_entity["id"]: - color_value = self.node_color - else: - color_value = "0xd88467ff" - - new_group_node["tile_color"].setValue(int(color_value, 16)) - - self.log.info( - "updated to version: {}".format(version_entity["name"]) - ) - - return update_container(new_group_node, data_imprint) - - def switch(self, container, context): - self.update(container, context) - - def remove(self, container): - node = container["node"] - with viewer_update_and_undo_stop(): - nuke.delete(node) diff --git a/server_addon/nuke/client/ayon_nuke/plugins/load/load_gizmo_ip.py b/server_addon/nuke/client/ayon_nuke/plugins/load/load_gizmo_ip.py deleted file mode 100644 index 36e878fdf1..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/load/load_gizmo_ip.py +++ /dev/null @@ -1,270 +0,0 @@ -import nuke -import six -import ayon_api - -from ayon_core.pipeline import ( - load, - get_representation_path, -) -from ayon_nuke.api.lib import ( - maintained_selection, - create_backdrop, - get_avalon_knob_data, - set_avalon_knob_data, - swap_node_with_dependency, -) -from ayon_nuke.api import ( - containerise, - update_container, - viewer_update_and_undo_stop -) - - -class LoadGizmoInputProcess(load.LoaderPlugin): - """Loading colorspace soft effect exported from nukestudio""" - - product_types = {"gizmo"} - representations = {"*"} - extensions = {"nk"} - - settings_category = "nuke" - - label = "Load Gizmo - Input Process" - order = 0 - icon = "eye" - color = "#cc0000" - node_color = "0x7533c1ff" - - def load(self, context, name, namespace, data): - """ - Loading function to get Gizmo as Input Process on viewer - - Arguments: - context (dict): context of version - name (str): name of the version - namespace (str): namespace name - data (dict): compulsory attribute > not used - - Returns: - nuke node: containerized nuke node object - """ - - # get main variables - version_entity = context["version"] - - version_attributes = version_entity["attrib"] - first = version_attributes.get("frameStart") - last = version_attributes.get("frameEnd") - colorspace = version_attributes.get("colorSpace") - - namespace = namespace or context["folder"]["name"] - object_name = "{}_{}".format(name, namespace) - - # prepare data for imprinting - # add additional metadata from the version to imprint to metadata knob - data_imprint = { - "frameStart": first, - "frameEnd": last, - "version": version_entity["version"], - "colorspaceInput": colorspace - } - - for k in [ - "frameStart", - "frameEnd", - "handleStart", - "handleEnd", - "source", - "fps" - ]: - data_imprint[k] = version_attributes[k] - - # getting file path - file = self.filepath_from_context(context).replace("\\", "/") - - # adding nodes to node graph - # just in case we are in group lets jump out of it - nuke.endGroup() - - with maintained_selection(): - # add group from nk - nuke.nodePaste(file) - - group_node = nuke.selectedNode() - - group_node["name"].setValue(object_name) - - # try to place it under Viewer1 - if not self.connect_active_viewer(group_node): - nuke.delete(group_node) - return - - return containerise( - node=group_node, - name=name, - namespace=namespace, - context=context, - loader=self.__class__.__name__, - data=data_imprint) - - def update(self, container, context): - """Update the Loader's path - - Nuke automatically tries to reset some variables when changing - the loader's path to a new file. These automatic changes are to its - inputs: - - """ - - # get main variables - # Get version from io - project_name = context["project"]["name"] - version_entity = context["version"] - repre_entity = context["representation"] - - # get corresponding node - group_node = container["node"] - - file = get_representation_path(repre_entity).replace("\\", "/") - - version_attributes = version_entity["attrib"] - first = version_attributes.get("frameStart") - last = version_attributes.get("frameEnd") - colorspace = version_attributes.get("colorSpace") - - data_imprint = { - "representation": repre_entity["id"], - "frameStart": first, - "frameEnd": last, - "version": version_entity["version"], - "colorspaceInput": colorspace - } - - for k in [ - "frameStart", - "frameEnd", - "handleStart", - "handleEnd", - "source", - "fps" - ]: - data_imprint[k] = version_attributes[k] - - # capture pipeline metadata - avalon_data = get_avalon_knob_data(group_node) - - # adding nodes to node graph - # just in case we are in group lets jump out of it - nuke.endGroup() - - with maintained_selection([group_node]): - # insert nuke script to the script - nuke.nodePaste(file) - # convert imported to selected node - new_group_node = nuke.selectedNode() - # swap nodes with maintained connections - with swap_node_with_dependency( - group_node, new_group_node) as node_name: - new_group_node["name"].setValue(node_name) - # set updated pipeline metadata - set_avalon_knob_data(new_group_node, avalon_data) - - last_version_entity = ayon_api.get_last_version_by_product_id( - project_name, version_entity["productId"], fields={"id"} - ) - - # change color of node - if version_entity["id"] == last_version_entity["id"]: - color_value = self.node_color - else: - color_value = "0xd88467ff" - new_group_node["tile_color"].setValue(int(color_value, 16)) - - self.log.info( - "updated to version: {}".format(version_entity["version"]) - ) - - return update_container(new_group_node, data_imprint) - - def connect_active_viewer(self, group_node): - """ - Finds Active viewer and - place the node under it, also adds - name of group into Input Process of the viewer - - Arguments: - group_node (nuke node): nuke group node object - - """ - group_node_name = group_node["name"].value() - - viewer = [n for n in nuke.allNodes() if "Viewer1" in n["name"].value()] - if len(viewer) > 0: - viewer = viewer[0] - else: - msg = str("Please create Viewer node before you " - "run this action again") - self.log.error(msg) - nuke.message(msg) - return None - - # get coordinates of Viewer1 - xpos = viewer["xpos"].value() - ypos = viewer["ypos"].value() - - ypos += 150 - - viewer["ypos"].setValue(ypos) - - # set coordinates to group node - group_node["xpos"].setValue(xpos) - group_node["ypos"].setValue(ypos + 50) - - # add group node name to Viewer Input Process - viewer["input_process_node"].setValue(group_node_name) - - # put backdrop under - create_backdrop( - label="Input Process", - layer=2, - nodes=[viewer, group_node], - color="0x7c7faaff" - ) - - return True - - def get_item(self, data, trackIndex, subTrackIndex): - return {key: val for key, val in data.items() - if subTrackIndex == val["subTrackIndex"] - if trackIndex == val["trackIndex"]} - - def byteify(self, input): - """ - Converts unicode strings to strings - It goes through all dictionary - - Arguments: - input (dict/str): input - - Returns: - dict: with fixed values and keys - - """ - - if isinstance(input, dict): - return {self.byteify(key): self.byteify(value) - for key, value in input.items()} - elif isinstance(input, list): - return [self.byteify(element) for element in input] - elif isinstance(input, six.text_type): - return str(input) - else: - return input - - def switch(self, container, context): - self.update(container, context) - - def remove(self, container): - node = container["node"] - with viewer_update_and_undo_stop(): - nuke.delete(node) diff --git a/server_addon/nuke/client/ayon_nuke/plugins/load/load_image.py b/server_addon/nuke/client/ayon_nuke/plugins/load/load_image.py deleted file mode 100644 index 0c43f5a5ca..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/load/load_image.py +++ /dev/null @@ -1,254 +0,0 @@ -import nuke - -import qargparse -import ayon_api - -from ayon_core.pipeline import ( - load, - get_representation_path, -) -from ayon_nuke.api.lib import ( - get_imageio_input_colorspace -) -from ayon_nuke.api import ( - containerise, - update_container, - viewer_update_and_undo_stop -) -from ayon_core.lib.transcoding import ( - IMAGE_EXTENSIONS -) - - -class LoadImage(load.LoaderPlugin): - """Load still image into Nuke""" - - product_types = { - "render2d", - "source", - "plate", - "render", - "prerender", - "review", - "image", - } - representations = {"*"} - extensions = set(ext.lstrip(".") for ext in IMAGE_EXTENSIONS) - - settings_category = "nuke" - - label = "Load Image" - order = -10 - icon = "image" - color = "white" - - # Loaded from settings - representations_include = [] - - node_name_template = "{class_name}_{ext}" - - options = [ - qargparse.Integer( - "frame_number", - label="Frame Number", - default=int(nuke.root()["first_frame"].getValue()), - min=1, - max=999999, - help="What frame is reading from?" - ) - ] - - @classmethod - def get_representations(cls): - return cls.representations_include or cls.representations - - def load(self, context, name, namespace, options): - self.log.info("__ options: `{}`".format(options)) - frame_number = options.get( - "frame_number", int(nuke.root()["first_frame"].getValue()) - ) - - version_entity = context["version"] - version_attributes = version_entity["attrib"] - repre_entity = context["representation"] - repre_id = repre_entity["id"] - - self.log.debug( - "Representation id `{}` ".format(repre_id)) - - last = first = int(frame_number) - - # Fallback to folder name when namespace is None - if namespace is None: - namespace = context["folder"]["name"] - - file = self.filepath_from_context(context) - - if not file: - self.log.warning( - "Representation id `{}` is failing to load".format(repre_id)) - return - - file = file.replace("\\", "/") - - frame = repre_entity["context"].get("frame") - if frame: - padding = len(frame) - file = file.replace( - frame, - format(frame_number, "0{}".format(padding))) - - read_name = self._get_node_name(context) - - # Create the Loader with the filename path set - with viewer_update_and_undo_stop(): - r = nuke.createNode( - "Read", - "name {}".format(read_name), - inpanel=False - ) - - r["file"].setValue(file) - - # Set colorspace defined in version data - colorspace = version_entity["attrib"].get("colorSpace") - if colorspace: - r["colorspace"].setValue(str(colorspace)) - - preset_clrsp = get_imageio_input_colorspace(file) - - if preset_clrsp is not None: - r["colorspace"].setValue(preset_clrsp) - - r["origfirst"].setValue(first) - r["first"].setValue(first) - r["origlast"].setValue(last) - r["last"].setValue(last) - - # add attributes from the version to imprint metadata knob - colorspace = version_attributes["colorSpace"] - data_imprint = { - "frameStart": first, - "frameEnd": last, - "version": version_entity["version"], - "colorspace": colorspace, - } - for k in ["source", "fps"]: - data_imprint[k] = version_attributes.get(k, str(None)) - - r["tile_color"].setValue(int("0x4ecd25ff", 16)) - - return containerise(r, - name=name, - namespace=namespace, - context=context, - loader=self.__class__.__name__, - data=data_imprint) - - def switch(self, container, context): - self.update(container, context) - - def update(self, container, context): - """Update the Loader's path - - Nuke automatically tries to reset some variables when changing - the loader's path to a new file. These automatic changes are to its - inputs: - - """ - node = container["node"] - frame_number = node["first"].value() - - assert node.Class() == "Read", "Must be Read" - - project_name = context["project"]["name"] - version_entity = context["version"] - repre_entity = context["representation"] - - repr_cont = repre_entity["context"] - - file = get_representation_path(repre_entity) - - if not file: - repre_id = repre_entity["id"] - self.log.warning( - "Representation id `{}` is failing to load".format(repre_id)) - return - - file = file.replace("\\", "/") - - frame = repr_cont.get("frame") - if frame: - padding = len(frame) - file = file.replace( - frame, - format(frame_number, "0{}".format(padding))) - - # Get start frame from version data - last_version_entity = ayon_api.get_last_version_by_product_id( - project_name, version_entity["productId"], fields={"id"} - ) - - last = first = int(frame_number) - - # Set the global in to the start frame of the sequence - node["file"].setValue(file) - node["origfirst"].setValue(first) - node["first"].setValue(first) - node["origlast"].setValue(last) - node["last"].setValue(last) - - version_attributes = version_entity["attrib"] - updated_dict = { - "representation": repre_entity["id"], - "frameStart": str(first), - "frameEnd": str(last), - "version": str(version_entity["version"]), - "colorspace": version_attributes.get("colorSpace"), - "source": version_attributes.get("source"), - "fps": str(version_attributes.get("fps")), - } - - # change color of node - if version_entity["id"] == last_version_entity["id"]: - color_value = "0x4ecd25ff" - else: - color_value = "0xd84f20ff" - node["tile_color"].setValue(int(color_value, 16)) - - # Update the imprinted representation - update_container(node, updated_dict) - self.log.info("updated to version: {}".format( - version_entity["version"] - )) - - def remove(self, container): - node = container["node"] - assert node.Class() == "Read", "Must be Read" - - with viewer_update_and_undo_stop(): - nuke.delete(node) - - def _get_node_name(self, context): - folder_entity = context["folder"] - product_name = context["product"]["name"] - repre_entity = context["representation"] - - folder_name = folder_entity["name"] - repre_cont = repre_entity["context"] - name_data = { - "folder": { - "name": folder_name, - }, - "product": { - "name": product_name, - }, - "asset": folder_name, - "subset": product_name, - "representation": repre_entity["name"], - "ext": repre_cont["representation"], - "id": repre_entity["id"], - "class_name": self.__class__.__name__ - } - - return self.node_name_template.format(**name_data) diff --git a/server_addon/nuke/client/ayon_nuke/plugins/load/load_matchmove.py b/server_addon/nuke/client/ayon_nuke/plugins/load/load_matchmove.py deleted file mode 100644 index c1b5a24504..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/load/load_matchmove.py +++ /dev/null @@ -1,32 +0,0 @@ -import nuke -from ayon_core.pipeline import load - - -class MatchmoveLoader(load.LoaderPlugin): - """ - This will run matchmove script to create track in script. - """ - - product_types = {"matchmove"} - representations = {"*"} - extensions = {"py"} - - settings_category = "nuke" - - defaults = ["Camera", "Object"] - - label = "Run matchmove script" - icon = "empire" - color = "orange" - - def load(self, context, name, namespace, data): - path = self.filepath_from_context(context) - if path.lower().endswith(".py"): - exec(open(path).read()) - - else: - msg = "Unsupported script type" - self.log.error(msg) - nuke.message(msg) - - return True diff --git a/server_addon/nuke/client/ayon_nuke/plugins/load/load_model.py b/server_addon/nuke/client/ayon_nuke/plugins/load/load_model.py deleted file mode 100644 index 551147be96..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/load/load_model.py +++ /dev/null @@ -1,207 +0,0 @@ -import nuke -import ayon_api - -from ayon_core.pipeline import ( - load, - get_representation_path, -) -from ayon_nuke.api.lib import maintained_selection -from ayon_nuke.api import ( - containerise, - update_container, - viewer_update_and_undo_stop -) - - -class AlembicModelLoader(load.LoaderPlugin): - """ - This will load alembic model or anim into script. - """ - - product_types = {"model", "pointcache", "animation"} - representations = {"*"} - extensions = {"abc"} - - settings_category = "nuke" - - label = "Load Alembic" - icon = "cube" - color = "orange" - node_color = "0x4ecd91ff" - - def load(self, context, name, namespace, data): - # get main variables - project_name = context["project"]["name"] - version_entity = context["version"] - - version_attributes = version_entity["attrib"] - first = version_attributes.get("frameStart") - last = version_attributes.get("frameEnd") - fps = version_attributes.get("fps") or nuke.root()["fps"].getValue() - - namespace = namespace or context["folder"]["name"] - object_name = "{}_{}".format(name, namespace) - - # prepare data for imprinting - data_imprint = { - "frameStart": first, - "frameEnd": last, - "version": version_entity["version"] - } - # add attributes from the version to imprint to metadata knob - for k in ["source", "fps"]: - data_imprint[k] = version_attributes[k] - - # getting file path - file = self.filepath_from_context(context).replace("\\", "/") - - with maintained_selection(): - model_node = nuke.createNode( - "ReadGeo2", - "name {} file {} ".format( - object_name, file), - inpanel=False - ) - - model_node.forceValidate() - - # Ensure all items are imported and selected. - scene_view = model_node.knob('scene_view') - scene_view.setImportedItems(scene_view.getAllItems()) - scene_view.setSelectedItems(scene_view.getAllItems()) - - model_node["frame_rate"].setValue(float(fps)) - - # workaround because nuke's bug is not adding - # animation keys properly - xpos = model_node.xpos() - ypos = model_node.ypos() - nuke.nodeCopy("%clipboard%") - nuke.delete(model_node) - nuke.nodePaste("%clipboard%") - model_node = nuke.toNode(object_name) - model_node.setXYpos(xpos, ypos) - - # color node by correct color by actual version - self.node_version_color(project_name, version_entity, model_node) - - return containerise( - node=model_node, - name=name, - namespace=namespace, - context=context, - loader=self.__class__.__name__, - data=data_imprint) - - def update(self, container, context): - """ - Called by Scene Inventory when look should be updated to current - version. - If any reference edits cannot be applied, eg. shader renamed and - material not present, reference is unloaded and cleaned. - All failed edits are highlighted to the user via message box. - - Args: - container: object that has look to be updated - context: (dict): relationship data to get proper - representation from DB and persisted - data in .json - Returns: - None - """ - # Get version from io - project_name = context["project"]["name"] - version_entity = context["version"] - repre_entity = context["representation"] - - # get corresponding node - model_node = container["node"] - - # get main variables - version_attributes = version_entity["attrib"] - first = version_attributes.get("frameStart") - last = version_attributes.get("frameEnd") - fps = version_attributes.get("fps") or nuke.root()["fps"].getValue() - - # prepare data for imprinting - data_imprint = { - "representation": repre_entity["id"], - "frameStart": first, - "frameEnd": last, - "version": version_entity["version"] - } - - # add additional metadata from the version to imprint to Avalon knob - for k in ["source", "fps"]: - data_imprint[k] = version_attributes[k] - - # getting file path - file = get_representation_path(repre_entity).replace("\\", "/") - - with maintained_selection(): - model_node['selected'].setValue(True) - - # collect input output dependencies - dependencies = model_node.dependencies() - dependent = model_node.dependent() - - model_node["frame_rate"].setValue(float(fps)) - model_node["file"].setValue(file) - - # Ensure all items are imported and selected. - scene_view = model_node.knob('scene_view') - scene_view.setImportedItems(scene_view.getAllItems()) - scene_view.setSelectedItems(scene_view.getAllItems()) - - # workaround because nuke's bug is - # not adding animation keys properly - xpos = model_node.xpos() - ypos = model_node.ypos() - nuke.nodeCopy("%clipboard%") - nuke.delete(model_node) - - # paste the node back and set the position - nuke.nodePaste("%clipboard%") - model_node = nuke.selectedNode() - model_node.setXYpos(xpos, ypos) - - # link to original input nodes - for i, input in enumerate(dependencies): - model_node.setInput(i, input) - # link to original output nodes - for d in dependent: - index = next((i for i, dpcy in enumerate( - d.dependencies()) - if model_node is dpcy), 0) - d.setInput(index, model_node) - - # color node by correct color by actual version - self.node_version_color(project_name, version_entity, model_node) - - self.log.info( - "updated to version: {}".format(version_entity["version"]) - ) - - return update_container(model_node, data_imprint) - - def node_version_color(self, project_name, version_entity, node): - """ Coloring a node by correct color by actual version""" - - last_version_entity = ayon_api.get_last_version_by_product_id( - project_name, version_entity["productId"], fields={"id"} - ) - - # change color of node - if version_entity["id"] == last_version_entity["id"]: - color_value = self.node_color - else: - color_value = "0xd88467ff" - node["tile_color"].setValue(int(color_value, 16)) - - def switch(self, container, context): - self.update(container, context) - - def remove(self, container): - node = nuke.toNode(container['objectName']) - with viewer_update_and_undo_stop(): - nuke.delete(node) diff --git a/server_addon/nuke/client/ayon_nuke/plugins/load/load_ociolook.py b/server_addon/nuke/client/ayon_nuke/plugins/load/load_ociolook.py deleted file mode 100644 index bdff8d7e28..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/load/load_ociolook.py +++ /dev/null @@ -1,349 +0,0 @@ -import os -import json -import secrets - -import nuke -import six -import ayon_api - -from ayon_core.pipeline import ( - load, - get_representation_path, -) -from ayon_nuke.api import ( - containerise, - viewer_update_and_undo_stop, - update_container, -) - - -class LoadOcioLookNodes(load.LoaderPlugin): - """Loading Ocio look to the nuke.Node graph""" - - product_types = {"ociolook"} - representations = {"*"} - extensions = {"json"} - - settings_category = "nuke" - - label = "Load OcioLook [nodes]" - order = 0 - icon = "cc" - color = "white" - ignore_attr = ["useLifetime"] - - # plugin attributes - current_node_color = "0x4ecd91ff" - old_node_color = "0xd88467ff" - - # json file variables - schema_version = 1 - - def load(self, context, name, namespace, data): - """ - Loading function to get the soft effects to particular read node - - Arguments: - context (dict): context of version - name (str): name of the version - namespace (str): namespace name - data (dict): compulsory attribute > not used - - Returns: - nuke.Node: containerized nuke.Node object - """ - namespace = namespace or context["folder"]["name"] - suffix = secrets.token_hex(nbytes=4) - node_name = "{}_{}_{}".format( - name, namespace, suffix) - - # getting file path - filepath = self.filepath_from_context(context) - - json_f = self._load_json_data(filepath) - - group_node = self._create_group_node( - filepath, json_f["data"]) - # renaming group node - group_node["name"].setValue(node_name) - - self._node_version_color( - context["project"]["name"], - context["version"], - group_node - ) - - self.log.info( - "Loaded lut setup: `{}`".format(group_node["name"].value())) - - return containerise( - node=group_node, - name=name, - namespace=namespace, - context=context, - loader=self.__class__.__name__ - ) - - def _create_group_node( - self, - filepath, - data, - group_node=None - ): - """Creates group node with all the nodes inside. - - Creating mainly `OCIOFileTransform` nodes with `OCIOColorSpace` nodes - in between - in case those are needed. - - Arguments: - filepath (str): path to json file - data (dict): data from json file - group_node (Optional[nuke.Node]): group node or None - - Returns: - nuke.Node: group node with all the nodes inside - """ - # get corresponding node - - root_working_colorspace = nuke.root()["workingSpaceLUT"].value() - - dir_path = os.path.dirname(filepath) - all_files = os.listdir(dir_path) - - ocio_working_colorspace = _colorspace_name_by_type( - data["ocioLookWorkingSpace"]) - - # adding nodes to node graph - # just in case we are in group lets jump out of it - nuke.endGroup() - - input_node = None - output_node = None - if group_node: - # remove all nodes between Input and Output nodes - for node in group_node.nodes(): - if node.Class() not in ["Input", "Output"]: - nuke.delete(node) - elif node.Class() == "Input": - input_node = node - elif node.Class() == "Output": - output_node = node - else: - group_node = nuke.createNode( - "Group", - inpanel=False - ) - - # adding content to the group node - with group_node: - pre_colorspace = root_working_colorspace - - # reusing input node if it exists during update - if input_node: - pre_node = input_node - else: - pre_node = nuke.createNode("Input") - pre_node["name"].setValue("rgb") - - # Compare script working colorspace with ocio working colorspace - # found in json file and convert to json's if needed - if pre_colorspace != ocio_working_colorspace: - pre_node = _add_ocio_colorspace_node( - pre_node, - pre_colorspace, - ocio_working_colorspace - ) - pre_colorspace = ocio_working_colorspace - - for ocio_item in data["ocioLookItems"]: - input_space = _colorspace_name_by_type( - ocio_item["input_colorspace"]) - output_space = _colorspace_name_by_type( - ocio_item["output_colorspace"]) - - # making sure we are set to correct colorspace for otio item - if pre_colorspace != input_space: - pre_node = _add_ocio_colorspace_node( - pre_node, - pre_colorspace, - input_space - ) - - node = nuke.createNode("OCIOFileTransform") - - # file path from lut representation - extension = ocio_item["ext"] - item_name = ocio_item["name"] - - item_lut_file = next( - ( - file for file in all_files - if file.endswith(extension) - ), - None - ) - if not item_lut_file: - raise ValueError( - "File with extension '{}' not " - "found in directory".format(extension) - ) - - item_lut_path = os.path.join( - dir_path, item_lut_file).replace("\\", "/") - node["file"].setValue(item_lut_path) - node["name"].setValue(item_name) - node["direction"].setValue(ocio_item["direction"]) - node["interpolation"].setValue(ocio_item["interpolation"]) - node["working_space"].setValue(input_space) - - pre_node.autoplace() - node.setInput(0, pre_node) - node.autoplace() - # pass output space into pre_colorspace for next iteration - # or for output node comparison - pre_colorspace = output_space - pre_node = node - - # making sure we are back in script working colorspace - if pre_colorspace != root_working_colorspace: - pre_node = _add_ocio_colorspace_node( - pre_node, - pre_colorspace, - root_working_colorspace - ) - - # reusing output node if it exists during update - if not output_node: - output = nuke.createNode("Output") - else: - output = output_node - - output.setInput(0, pre_node) - - return group_node - - def update(self, container, context): - repre_entity = context["representation"] - - group_node = container["node"] - - filepath = get_representation_path(repre_entity) - - json_f = self._load_json_data(filepath) - - group_node = self._create_group_node( - filepath, - json_f["data"], - group_node - ) - - self._node_version_color( - context["project"]["name"], context["version"], group_node - ) - - self.log.info("Updated lut setup: `{}`".format( - group_node["name"].value())) - - return update_container( - group_node, {"representation": repre_entity["id"]}) - - def _load_json_data(self, filepath): - # getting data from json file with unicode conversion - with open(filepath, "r") as _file: - json_f = {self._bytify(key): self._bytify(value) - for key, value in json.load(_file).items()} - - # check if the version in json_f is the same as plugin version - if json_f["version"] != self.schema_version: - raise KeyError( - "Version of json file is not the same as plugin version") - - return json_f - - def _bytify(self, input): - """ - Converts unicode strings to strings - It goes through all dictionary - - Arguments: - input (dict/str): input - - Returns: - dict: with fixed values and keys - - """ - - if isinstance(input, dict): - return {self._bytify(key): self._bytify(value) - for key, value in input.items()} - elif isinstance(input, list): - return [self._bytify(element) for element in input] - elif isinstance(input, six.text_type): - return str(input) - else: - return input - - def switch(self, container, context): - self.update(container, context) - - def remove(self, container): - node = nuke.toNode(container['objectName']) - with viewer_update_and_undo_stop(): - nuke.delete(node) - - def _node_version_color(self, project_name, version_entity, node): - """ Coloring a node by correct color by actual version""" - - last_version_entity = ayon_api.get_last_version_by_product_id( - project_name, version_entity["productId"], fields={"id"} - ) - - # change color of node - if version_entity["id"] == last_version_entity["id"]: - color_value = self.current_node_color - else: - color_value = self.old_node_color - node["tile_color"].setValue(int(color_value, 16)) - - -def _colorspace_name_by_type(colorspace_data): - """ - Returns colorspace name by type - - Arguments: - colorspace_data (dict): colorspace data - - Returns: - str: colorspace name - """ - if colorspace_data["type"] == "colorspaces": - return colorspace_data["name"] - elif colorspace_data["type"] == "roles": - return colorspace_data["colorspace"] - else: - raise KeyError("Unknown colorspace type: {}".format( - colorspace_data["type"])) - - -def _add_ocio_colorspace_node(pre_node, input_space, output_space): - """ - Adds OCIOColorSpace node to the node graph - - Arguments: - pre_node (nuke.Node): node to connect to - input_space (str): input colorspace - output_space (str): output colorspace - - Returns: - nuke.Node: node with OCIOColorSpace node - """ - node = nuke.createNode("OCIOColorSpace") - node.setInput(0, pre_node) - node["in_colorspace"].setValue(input_space) - node["out_colorspace"].setValue(output_space) - - pre_node.autoplace() - node.setInput(0, pre_node) - node.autoplace() - - return node diff --git a/server_addon/nuke/client/ayon_nuke/plugins/load/load_script_precomp.py b/server_addon/nuke/client/ayon_nuke/plugins/load/load_script_precomp.py deleted file mode 100644 index cf543dabfd..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/load/load_script_precomp.py +++ /dev/null @@ -1,162 +0,0 @@ -import nuke -import ayon_api - -from ayon_core.pipeline import ( - load, - get_representation_path, -) -from ayon_nuke.api.lib import get_avalon_knob_data -from ayon_nuke.api import ( - containerise, - update_container, - viewer_update_and_undo_stop -) - - -class LinkAsGroup(load.LoaderPlugin): - """Copy the published file to be pasted at the desired location""" - - product_types = {"workfile", "nukenodes"} - representations = {"*"} - extensions = {"nk"} - - settings_category = "nuke" - - label = "Load Precomp" - order = 0 - icon = "file" - color = "#cc0000" - - def load(self, context, name, namespace, data): - # for k, v in context.items(): - # log.info("key: `{}`, value: {}\n".format(k, v)) - version_entity = context["version"] - - version_attributes = version_entity["attrib"] - first = version_attributes.get("frameStart") - last = version_attributes.get("frameEnd") - colorspace = version_attributes.get("colorSpace") - - # Fallback to folder name when namespace is None - if namespace is None: - namespace = context["folder"]["name"] - - file = self.filepath_from_context(context).replace("\\", "/") - self.log.info("file: {}\n".format(file)) - - data_imprint = { - "startingFrame": first, - "frameStart": first, - "frameEnd": last, - "version": version_entity["version"] - } - # add additional metadata from the version to imprint to Avalon knob - for k in [ - "frameStart", - "frameEnd", - "handleStart", - "handleEnd", - "source", - "fps" - ]: - data_imprint[k] = version_attributes[k] - - # group context is set to precomp, so back up one level. - nuke.endGroup() - - # P = nuke.nodes.LiveGroup("file {}".format(file)) - P = nuke.createNode( - "Precomp", - "file {}".format(file), - inpanel=False - ) - - # Set colorspace defined in version data - self.log.info("colorspace: {}\n".format(colorspace)) - - P["name"].setValue("{}_{}".format(name, namespace)) - P["useOutput"].setValue(True) - - with P: - # iterate through all nodes in group node and find pype writes - writes = [n.name() for n in nuke.allNodes() - if n.Class() == "Group" - if get_avalon_knob_data(n)] - - if writes: - # create panel for selecting output - panel_choices = " ".join(writes) - panel_label = "Select write node for output" - p = nuke.Panel("Select Write Node") - p.addEnumerationPulldown( - panel_label, panel_choices) - p.show() - P["output"].setValue(p.value(panel_label)) - - P["tile_color"].setValue(0xff0ff0ff) - - return containerise( - node=P, - name=name, - namespace=namespace, - context=context, - loader=self.__class__.__name__, - data=data_imprint) - - def switch(self, container, context): - self.update(container, context) - - def update(self, container, context): - """Update the Loader's path - - Nuke automatically tries to reset some variables when changing - the loader's path to a new file. These automatic changes are to its - inputs: - - """ - node = container["node"] - - project_name = context["project"]["name"] - version_entity = context["version"] - repre_entity = context["representation"] - - root = get_representation_path(repre_entity).replace("\\", "/") - - # Get start frame from version data - - version_attributes = version_entity["attrib"] - updated_dict = { - "representation": repre_entity["id"], - "frameEnd": version_attributes.get("frameEnd"), - "version": version_entity["version"], - "colorspace": version_attributes.get("colorSpace"), - "source": version_attributes.get("source"), - "fps": version_attributes.get("fps"), - } - - # Update the imprinted representation - update_container( - node, - updated_dict - ) - - node["file"].setValue(root) - - last_version_entity = ayon_api.get_last_version_by_product_id( - project_name, version_entity["productId"], fields={"id"} - ) - # change color of node - if version_entity["id"] == last_version_entity["id"]: - color_value = "0xff0ff0ff" - else: - color_value = "0xd84f20ff" - node["tile_color"].setValue(int(color_value, 16)) - - self.log.info( - "updated to version: {}".format(version_entity["version"]) - ) - - def remove(self, container): - node = container["node"] - with viewer_update_and_undo_stop(): - nuke.delete(node) diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/collect_backdrop.py b/server_addon/nuke/client/ayon_nuke/plugins/publish/collect_backdrop.py deleted file mode 100644 index 1471159380..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/collect_backdrop.py +++ /dev/null @@ -1,62 +0,0 @@ -from pprint import pformat -import pyblish.api -from ayon_nuke.api import lib as pnlib -import nuke - - -class CollectBackdrops(pyblish.api.InstancePlugin): - """Collect Backdrop node instance and its content - """ - - order = pyblish.api.CollectorOrder + 0.22 - label = "Collect Backdrop" - hosts = ["nuke"] - families = ["nukenodes"] - - settings_category = "nuke" - - def process(self, instance): - self.log.debug(pformat(instance.data)) - - bckn = instance.data["transientData"]["node"] - - # define size of the backdrop - left = bckn.xpos() - top = bckn.ypos() - right = left + bckn['bdwidth'].value() - bottom = top + bckn['bdheight'].value() - - instance.data["transientData"]["childNodes"] = [] - # iterate all nodes - for node in nuke.allNodes(): - - # exclude viewer - if node.Class() == "Viewer": - continue - - # find all related nodes - if (node.xpos() > left) \ - and (node.xpos() + node.screenWidth() < right) \ - and (node.ypos() > top) \ - and (node.ypos() + node.screenHeight() < bottom): - - # add contained nodes to instance's node list - instance.data["transientData"]["childNodes"].append(node) - - # get all connections from outside of backdrop - nodes = instance.data["transientData"]["childNodes"] - connections_in, connections_out = pnlib.get_dependent_nodes(nodes) - instance.data["transientData"]["nodeConnectionsIn"] = connections_in - instance.data["transientData"]["nodeConnectionsOut"] = connections_out - - # make label nicer - instance.data["label"] = "{0} ({1} nodes)".format( - bckn.name(), len(instance.data["transientData"]["childNodes"])) - - # get version - version = instance.context.data.get('version') - - if version: - instance.data['version'] = version - - self.log.debug("Backdrop instance collected: `{}`".format(instance)) diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/collect_context_data.py b/server_addon/nuke/client/ayon_nuke/plugins/publish/collect_context_data.py deleted file mode 100644 index 33c8e63e82..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/collect_context_data.py +++ /dev/null @@ -1,69 +0,0 @@ -import os -import nuke -import pyblish.api -from ayon_core.lib import get_version_from_path -import ayon_nuke.api as napi -from ayon_core.pipeline import KnownPublishError - - -class CollectContextData(pyblish.api.ContextPlugin): - """Collect current context publish.""" - - order = pyblish.api.CollectorOrder - 0.499 - label = "Collect context data" - hosts = ['nuke'] - - settings_category = "nuke" - - def process(self, context): # sourcery skip: avoid-builtin-shadow - root_node = nuke.root() - - current_file = os.path.normpath(root_node.name()) - - if current_file.lower() == "root": - raise KnownPublishError( - "Workfile is not correct file name. \n" - "Use workfile tool to manage the name correctly." - ) - - # Get frame range - first_frame = int(root_node["first_frame"].getValue()) - last_frame = int(root_node["last_frame"].getValue()) - - # get instance data from root - root_instance_context = napi.get_node_data( - root_node, napi.INSTANCE_DATA_KNOB - ) - - handle_start = root_instance_context["handleStart"] - handle_end = root_instance_context["handleEnd"] - - # Get format - format = root_node['format'].value() - resolution_width = format.width() - resolution_height = format.height() - pixel_aspect = format.pixelAspect() - - script_data = { - "frameStart": first_frame + handle_start, - "frameEnd": last_frame - handle_end, - "resolutionWidth": resolution_width, - "resolutionHeight": resolution_height, - "pixelAspect": pixel_aspect, - - "handleStart": handle_start, - "handleEnd": handle_end, - "step": 1, - "fps": root_node['fps'].value(), - - "currentFile": current_file, - "version": int(get_version_from_path(current_file)), - - "host": pyblish.api.current_host(), - "hostVersion": nuke.NUKE_VERSION_STRING - } - - context.data["scriptData"] = script_data - context.data.update(script_data) - - self.log.debug('Context from Nuke script collected') diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/collect_framerate.py b/server_addon/nuke/client/ayon_nuke/plugins/publish/collect_framerate.py deleted file mode 100644 index cd77eab0f1..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/collect_framerate.py +++ /dev/null @@ -1,19 +0,0 @@ -import nuke - -import pyblish.api - - -class CollectFramerate(pyblish.api.ContextPlugin): - """Collect framerate.""" - - order = pyblish.api.CollectorOrder - label = "Collect Framerate" - hosts = [ - "nuke", - "nukeassist" - ] - - settings_category = "nuke" - - def process(self, context): - context.data["fps"] = nuke.root()["fps"].getValue() diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/collect_gizmo.py b/server_addon/nuke/client/ayon_nuke/plugins/publish/collect_gizmo.py deleted file mode 100644 index ece9823b37..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/collect_gizmo.py +++ /dev/null @@ -1,49 +0,0 @@ -import pyblish.api -import nuke - - -class CollectGizmo(pyblish.api.InstancePlugin): - """Collect Gizmo (group) node instance and its content - """ - - order = pyblish.api.CollectorOrder + 0.22 - label = "Collect Gizmo (group)" - hosts = ["nuke"] - families = ["gizmo"] - - settings_category = "nuke" - - def process(self, instance): - - gizmo_node = instance.data["transientData"]["node"] - - # add product type to familiess - instance.data["families"].insert(0, instance.data["productType"]) - # make label nicer - instance.data["label"] = gizmo_node.name() - - # Get frame range - handle_start = instance.context.data["handleStart"] - handle_end = instance.context.data["handleEnd"] - first_frame = int(nuke.root()["first_frame"].getValue()) - last_frame = int(nuke.root()["last_frame"].getValue()) - families = [instance.data["productType"]] + instance.data["families"] - - # Add version data to instance - version_data = { - "handleStart": handle_start, - "handleEnd": handle_end, - "frameStart": first_frame + handle_start, - "frameEnd": last_frame - handle_end, - "colorspace": nuke.root().knob('workingSpaceLUT').value(), - "families": families, - "productName": instance.data["productName"], - "fps": instance.context.data["fps"] - } - - instance.data.update({ - "versionData": version_data, - "frameStart": first_frame, - "frameEnd": last_frame - }) - self.log.debug("Gizmo instance collected: `{}`".format(instance)) diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/collect_headless_farm.py b/server_addon/nuke/client/ayon_nuke/plugins/publish/collect_headless_farm.py deleted file mode 100644 index c00b9a8f5d..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/collect_headless_farm.py +++ /dev/null @@ -1,58 +0,0 @@ -import pyblish.api - -from ayon_core.pipeline.publish import ( - AYONPyblishPluginMixin -) - - -class CollectRenderOnFarm(pyblish.api.ContextPlugin): - """Setup instances for render on farm submission.""" - - # Needs to be after CollectFromCreateContext - order = pyblish.api.CollectorOrder - 0.49 - label = "Collect Render On Farm" - hosts = ["nuke"] - - settings_category = "nuke" - - def process(self, context): - if not context.data.get("render_on_farm", False): - return - - for instance in context: - if instance.data["family"] == "workfile": - instance.data["active"] = False - continue - - # Filter out all other instances. - node = instance.data["transientData"]["node"] - if node.name() != instance.context.data["node_name"]: - instance.data["active"] = False - continue - - instance.data["families"].append("render_on_farm") - - # Enable for farm publishing. - instance.data["farm"] = True - - # Skip workfile version incremental save. - instance.context.data["increment_script_version"] = False - - -class SetupRenderOnFarm(pyblish.api.InstancePlugin, AYONPyblishPluginMixin): - """Setup instance for render on farm submission.""" - - order = pyblish.api.CollectorOrder + 0.4999 - label = "Setup Render On Farm" - hosts = ["nuke"] - families = ["render_on_farm"] - - def process(self, instance): - # Clear the families as we only want the main family, ei. no review - # etc. - instance.data["families"] = ["render_on_farm"] - - # Use the workfile instead of published. - publish_attributes = instance.data["publish_attributes"] - plugin_attributes = publish_attributes["NukeSubmitDeadline"] - plugin_attributes["use_published_workfile"] = False diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/collect_model.py b/server_addon/nuke/client/ayon_nuke/plugins/publish/collect_model.py deleted file mode 100644 index f4266bbbcb..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/collect_model.py +++ /dev/null @@ -1,48 +0,0 @@ -import pyblish.api -import nuke - - -class CollectModel(pyblish.api.InstancePlugin): - """Collect Model node instance and its content - """ - - order = pyblish.api.CollectorOrder + 0.22 - label = "Collect Model" - hosts = ["nuke"] - families = ["model"] - - settings_category = "nuke" - - def process(self, instance): - - geo_node = instance.data["transientData"]["node"] - - # add product type to familiess - instance.data["families"].insert(0, instance.data["productType"]) - # make label nicer - instance.data["label"] = geo_node.name() - - # Get frame range - handle_start = instance.context.data["handleStart"] - handle_end = instance.context.data["handleEnd"] - first_frame = int(nuke.root()["first_frame"].getValue()) - last_frame = int(nuke.root()["last_frame"].getValue()) - families = [instance.data["productType"]] + instance.data["families"] - # Add version data to instance - version_data = { - "handleStart": handle_start, - "handleEnd": handle_end, - "frameStart": first_frame + handle_start, - "frameEnd": last_frame - handle_end, - "colorspace": nuke.root().knob('workingSpaceLUT').value(), - "families": families, - "productName": instance.data["productName"], - "fps": instance.context.data["fps"] - } - - instance.data.update({ - "versionData": version_data, - "frameStart": first_frame, - "frameEnd": last_frame - }) - self.log.debug("Model instance collected: `{}`".format(instance)) diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/collect_nuke_instance_data.py b/server_addon/nuke/client/ayon_nuke/plugins/publish/collect_nuke_instance_data.py deleted file mode 100644 index d1392a8460..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/collect_nuke_instance_data.py +++ /dev/null @@ -1,57 +0,0 @@ -import nuke -import pyblish.api - - -class CollectInstanceData(pyblish.api.InstancePlugin): - """Collect Nuke instance data - - """ - - order = pyblish.api.CollectorOrder - 0.49 - label = "Collect Nuke Instance Data" - hosts = ["nuke", "nukeassist"] - - settings_category = "nuke" - - # presets - sync_workfile_version_on_families = [] - - def process(self, instance): - product_type = instance.data["productType"] - - # Get format - root = nuke.root() - format_ = root['format'].value() - resolution_width = format_.width() - resolution_height = format_.height() - pixel_aspect = format_.pixelAspect() - - # sync workfile version - if product_type in self.sync_workfile_version_on_families: - self.log.debug( - "Syncing version with workfile for '{}'".format( - product_type - ) - ) - # get version to instance for integration - instance.data['version'] = instance.context.data['version'] - - instance.data.update({ - "step": 1, - "fps": root['fps'].value(), - "resolutionWidth": resolution_width, - "resolutionHeight": resolution_height, - "pixelAspect": pixel_aspect - - }) - - # add creator attributes to instance - creator_attributes = instance.data["creator_attributes"] - instance.data.update(creator_attributes) - - # add review family if review activated on instance - if instance.data.get("review"): - instance.data["families"].append("review") - - self.log.debug("Collected instance: {}".format( - instance.data)) diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/collect_reads.py b/server_addon/nuke/client/ayon_nuke/plugins/publish/collect_reads.py deleted file mode 100644 index 439374e825..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/collect_reads.py +++ /dev/null @@ -1,124 +0,0 @@ -import os -import re -import nuke -import pyblish.api - - -class CollectNukeReads(pyblish.api.InstancePlugin): - """Collect all read nodes.""" - - order = pyblish.api.CollectorOrder + 0.04 - label = "Collect Source Reads" - hosts = ["nuke", "nukeassist"] - families = ["source"] - - settings_category = "nuke" - - def process(self, instance): - self.log.debug("checking instance: {}".format(instance)) - - node = instance.data["transientData"]["node"] - if node.Class() != "Read": - return - - file_path = node["file"].value() - file_name = os.path.basename(file_path) - items = file_name.split(".") - - if len(items) < 2: - raise ValueError - - ext = items[-1] - - # Get frame range - handle_start = instance.context.data["handleStart"] - handle_end = instance.context.data["handleEnd"] - first_frame = node['first'].value() - last_frame = node['last'].value() - - # colorspace - colorspace = node["colorspace"].value() - if "default" in colorspace: - colorspace = colorspace.replace("default (", "").replace(")", "") - - # # Easier way to sequence - Not tested - # isSequence = True - # if first_frame == last_frame: - # isSequence = False - - isSequence = False - if len(items) > 1: - sequence = items[-2] - hash_regex = re.compile(r'([#*])') - seq_regex = re.compile(r'[%0-9*d]') - hash_match = re.match(hash_regex, sequence) - seq_match = re.match(seq_regex, sequence) - if hash_match or seq_match: - isSequence = True - - # get source path - path = nuke.filename(node) - source_dir = os.path.dirname(path) - self.log.debug('source dir: {}'.format(source_dir)) - - if isSequence: - source_files = [f for f in os.listdir(source_dir) - if ext in f - if items[0] in f] - else: - source_files = file_name - - # Include start and end render frame in label - name = node.name() - label = "{0} ({1}-{2})".format( - name, - int(first_frame), - int(last_frame) - ) - - self.log.debug("collected_frames: {}".format(label)) - - if "representations" not in instance.data: - instance.data["representations"] = [] - - representation = { - 'name': ext, - 'ext': ext, - 'files': source_files, - "stagingDir": source_dir, - "frameStart": "%0{}d".format( - len(str(last_frame))) % first_frame - } - instance.data["representations"].append(representation) - - transfer = node["publish"] if "publish" in node.knobs() else False - instance.data['transfer'] = transfer - - # Add version data to instance - version_data = { - "handleStart": handle_start, - "handleEnd": handle_end, - "frameStart": first_frame + handle_start, - "frameEnd": last_frame - handle_end, - "colorspace": colorspace, - "families": [instance.data["productType"]], - "productName": instance.data["productName"], - "fps": instance.context.data["fps"] - } - - instance.data.update({ - "versionData": version_data, - "path": path, - "stagingDir": source_dir, - "ext": ext, - "label": label, - "frameStart": first_frame, - "frameEnd": last_frame, - "colorspace": colorspace, - "handleStart": handle_start, - "handleEnd": handle_end, - "step": 1, - "fps": int(nuke.root()['fps'].value()) - }) - - self.log.debug("instance.data: {}".format(instance.data)) diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/collect_slate_node.py b/server_addon/nuke/client/ayon_nuke/plugins/publish/collect_slate_node.py deleted file mode 100644 index bb3b0083ab..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/collect_slate_node.py +++ /dev/null @@ -1,48 +0,0 @@ -import pyblish.api -import nuke - - -class CollectSlate(pyblish.api.InstancePlugin): - """Check if SLATE node is in scene and connected to rendering tree""" - - order = pyblish.api.CollectorOrder + 0.002 - label = "Collect Slate Node" - hosts = ["nuke"] - families = ["render"] - - settings_category = "nuke" - - def process(self, instance): - node = instance.data["transientData"]["node"] - - slate = next( - ( - n_ for n_ in nuke.allNodes() - if "slate" in n_.name().lower() - if not n_["disable"].getValue() and - "publish_instance" not in n_.knobs() # Exclude instance nodes. - ), - None - ) - - if slate: - # check if slate node is connected to write node tree - slate_check = 0 - slate_node = None - while slate_check == 0: - try: - node = node.dependencies()[0] - if slate.name() in node.name(): - slate_node = node - slate_check = 1 - except IndexError: - break - - if slate_node: - instance.data["slateNode"] = slate_node - instance.data["slate"] = True - instance.data["families"].append("slate") - self.log.debug( - "Slate node is in node graph: `{}`".format(slate.name())) - self.log.debug( - "__ instance.data: `{}`".format(instance.data)) diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/collect_workfile.py b/server_addon/nuke/client/ayon_nuke/plugins/publish/collect_workfile.py deleted file mode 100644 index e4bd5ed129..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/collect_workfile.py +++ /dev/null @@ -1,44 +0,0 @@ -import os -import nuke -import pyblish.api - - -class CollectWorkfile(pyblish.api.InstancePlugin): - """Collect current script for publish.""" - - order = pyblish.api.CollectorOrder - label = "Collect Workfile" - hosts = ['nuke'] - families = ["workfile"] - - settings_category = "nuke" - - def process(self, instance): # sourcery skip: avoid-builtin-shadow - - script_data = instance.context.data["scriptData"] - current_file = os.path.normpath(nuke.root().name()) - - # creating instances per write node - staging_dir = os.path.dirname(current_file) - base_name = os.path.basename(current_file) - - # creating representation - representation = { - 'name': 'nk', - 'ext': 'nk', - 'files': base_name, - "stagingDir": staging_dir, - } - - # creating instance data - instance.data.update({ - "name": base_name, - "representations": [representation] - }) - - # adding basic script data - instance.data.update(script_data) - - self.log.debug( - "Collected current script version: {}".format(current_file) - ) diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/collect_writes.py b/server_addon/nuke/client/ayon_nuke/plugins/publish/collect_writes.py deleted file mode 100644 index 816f493d72..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/collect_writes.py +++ /dev/null @@ -1,402 +0,0 @@ -import os -import nuke -import pyblish.api -from ayon_nuke import api as napi -from ayon_core.pipeline import publish - - -class CollectNukeWrites(pyblish.api.InstancePlugin, - publish.ColormanagedPyblishPluginMixin): - """Collect all write nodes.""" - - order = pyblish.api.CollectorOrder + 0.0021 - label = "Collect Writes" - hosts = ["nuke", "nukeassist"] - families = ["render", "prerender", "image"] - - settings_category = "nuke" - - # cache - _write_nodes = {} - _frame_ranges = {} - - def process(self, instance): - - group_node = instance.data["transientData"]["node"] - render_target = instance.data["render_target"] - - write_node = self._write_node_helper(instance) - - if write_node is None: - self.log.warning( - "Created node '{}' is missing write node!".format( - group_node.name() - ) - ) - return - - # get colorspace and add to version data - colorspace = napi.get_colorspace_from_node(write_node) - - if render_target == "frames": - self._set_existing_files_data(instance, colorspace) - - elif render_target == "frames_farm": - collected_frames = self._set_existing_files_data( - instance, colorspace) - - self._set_expected_files(instance, collected_frames) - - self._add_farm_instance_data(instance) - - elif render_target == "farm": - self._add_farm_instance_data(instance) - - # set additional instance data - self._set_additional_instance_data(instance, render_target, colorspace) - - def _set_existing_files_data(self, instance, colorspace): - """Set existing files data to instance data. - - Args: - instance (pyblish.api.Instance): pyblish instance - colorspace (str): colorspace - - Returns: - list: collected frames - """ - collected_frames = self._get_collected_frames(instance) - - representation = self._get_existing_frames_representation( - instance, collected_frames - ) - - # inject colorspace data - self.set_representation_colorspace( - representation, instance.context, - colorspace=colorspace - ) - - instance.data["representations"].append(representation) - - return collected_frames - - def _set_expected_files(self, instance, collected_frames): - """Set expected files to instance data. - - Args: - instance (pyblish.api.Instance): pyblish instance - collected_frames (list): collected frames - """ - write_node = self._write_node_helper(instance) - - write_file_path = nuke.filename(write_node) - output_dir = os.path.dirname(write_file_path) - - instance.data["expectedFiles"] = [ - os.path.join(output_dir, source_file) - for source_file in collected_frames - ] - - def _get_frame_range_data(self, instance): - """Get frame range data from instance. - - Args: - instance (pyblish.api.Instance): pyblish instance - - Returns: - tuple: first_frame, last_frame - """ - - instance_name = instance.data["name"] - - if self._frame_ranges.get(instance_name): - # return cashed write node - return self._frame_ranges[instance_name] - - write_node = self._write_node_helper(instance) - - # Get frame range from workfile - first_frame = int(nuke.root()["first_frame"].getValue()) - last_frame = int(nuke.root()["last_frame"].getValue()) - - # Get frame range from write node if activated - if write_node["use_limit"].getValue(): - first_frame = int(write_node["first"].getValue()) - last_frame = int(write_node["last"].getValue()) - - # add to cache - self._frame_ranges[instance_name] = (first_frame, last_frame) - - return first_frame, last_frame - - def _set_additional_instance_data( - self, instance, render_target, colorspace - ): - """Set additional instance data. - - Args: - instance (pyblish.api.Instance): pyblish instance - render_target (str): render target - colorspace (str): colorspace - """ - product_type = instance.data["productType"] - - # add targeted family to families - instance.data["families"].append( - "{}.{}".format(product_type, render_target) - ) - self.log.debug("Appending render target to families: {}.{}".format( - product_type, render_target) - ) - - write_node = self._write_node_helper(instance) - - # Determine defined file type - ext = write_node["file_type"].value() - - # determine defined channel type - color_channels = write_node["channels"].value() - - # get frame range data - handle_start = instance.context.data["handleStart"] - handle_end = instance.context.data["handleEnd"] - first_frame, last_frame = self._get_frame_range_data(instance) - - # get output paths - write_file_path = nuke.filename(write_node) - output_dir = os.path.dirname(write_file_path) - - # TODO: remove this when we have proper colorspace support - version_data = { - "colorspace": colorspace - } - - instance.data.update({ - "versionData": version_data, - "path": write_file_path, - "outputDir": output_dir, - "ext": ext, - "colorspace": colorspace, - "color_channels": color_channels - }) - - if product_type == "render": - instance.data.update({ - "handleStart": handle_start, - "handleEnd": handle_end, - "frameStart": first_frame + handle_start, - "frameEnd": last_frame - handle_end, - "frameStartHandle": first_frame, - "frameEndHandle": last_frame, - }) - else: - instance.data.update({ - "handleStart": 0, - "handleEnd": 0, - "frameStart": first_frame, - "frameEnd": last_frame, - "frameStartHandle": first_frame, - "frameEndHandle": last_frame, - }) - - # TODO temporarily set stagingDir as persistent for backward - # compatibility. This is mainly focused on `renders`folders which - # were previously not cleaned up (and could be used in read notes) - # this logic should be removed and replaced with custom staging dir - instance.data["stagingDir_persistent"] = True - - def _write_node_helper(self, instance): - """Helper function to get write node from instance. - - Also sets instance transient data with child nodes. - - Args: - instance (pyblish.api.Instance): pyblish instance - - Returns: - nuke.Node: write node - """ - instance_name = instance.data["name"] - - if self._write_nodes.get(instance_name): - # return cashed write node - return self._write_nodes[instance_name] - - # get all child nodes from group node - child_nodes = napi.get_instance_group_node_childs(instance) - - # set child nodes to instance transient data - instance.data["transientData"]["childNodes"] = child_nodes - - write_node = None - for node_ in child_nodes: - if node_.Class() == "Write": - write_node = node_ - - if write_node: - # for slate frame extraction - instance.data["transientData"]["writeNode"] = write_node - # add to cache - self._write_nodes[instance_name] = write_node - - return self._write_nodes[instance_name] - - def _get_existing_frames_representation( - self, - instance, - collected_frames - ): - """Get existing frames representation. - - Args: - instance (pyblish.api.Instance): pyblish instance - collected_frames (list): collected frames - - Returns: - dict: representation - """ - - first_frame, last_frame = self._get_frame_range_data(instance) - - write_node = self._write_node_helper(instance) - - write_file_path = nuke.filename(write_node) - output_dir = os.path.dirname(write_file_path) - - # Determine defined file type - ext = write_node["file_type"].value() - - representation = { - "name": ext, - "ext": ext, - "stagingDir": output_dir, - "tags": [] - } - - # set slate frame - collected_frames = self._add_slate_frame_to_collected_frames( - instance, - collected_frames, - first_frame, - last_frame - ) - - if len(collected_frames) == 1: - representation['files'] = collected_frames.pop() - else: - representation['files'] = collected_frames - - return representation - - def _get_frame_start_str(self, first_frame, last_frame): - """Get frame start string. - - Args: - first_frame (int): first frame - last_frame (int): last frame - - Returns: - str: frame start string - """ - # convert first frame to string with padding - return ( - "{{:0{}d}}".format(len(str(last_frame))) - ).format(first_frame) - - def _add_slate_frame_to_collected_frames( - self, - instance, - collected_frames, - first_frame, - last_frame - ): - """Add slate frame to collected frames. - - Args: - instance (pyblish.api.Instance): pyblish instance - collected_frames (list): collected frames - first_frame (int): first frame - last_frame (int): last frame - - Returns: - list: collected frames - """ - frame_start_str = self._get_frame_start_str(first_frame, last_frame) - frame_length = int(last_frame - first_frame + 1) - - # this will only run if slate frame is not already - # rendered from previews publishes - if ( - "slate" in instance.data["families"] - and frame_length == len(collected_frames) - ): - frame_slate_str = self._get_frame_start_str( - first_frame - 1, - last_frame - ) - - slate_frame = collected_frames[0].replace( - frame_start_str, frame_slate_str) - collected_frames.insert(0, slate_frame) - - return collected_frames - - def _add_farm_instance_data(self, instance): - """Add farm publishing related instance data. - - Args: - instance (pyblish.api.Instance): pyblish instance - """ - - # make sure rendered sequence on farm will - # be used for extract review - if not instance.data.get("review"): - instance.data["useSequenceForReview"] = False - - # Farm rendering - instance.data.update({ - "transfer": False, - "farm": True # to skip integrate - }) - self.log.info("Farm rendering ON ...") - - def _get_collected_frames(self, instance): - """Get collected frames. - - Args: - instance (pyblish.api.Instance): pyblish instance - - Returns: - list: collected frames - """ - - first_frame, last_frame = self._get_frame_range_data(instance) - - write_node = self._write_node_helper(instance) - - write_file_path = nuke.filename(write_node) - output_dir = os.path.dirname(write_file_path) - - # get file path knob - node_file_knob = write_node["file"] - # list file paths based on input frames - expected_paths = list(sorted({ - node_file_knob.evaluate(frame) - for frame in range(first_frame, last_frame + 1) - })) - - # convert only to base names - expected_filenames = { - os.path.basename(filepath) - for filepath in expected_paths - } - - # make sure files are existing at folder - collected_frames = [ - filename - for filename in os.listdir(output_dir) - if filename in expected_filenames - ] - - return collected_frames diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_backdrop.py b/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_backdrop.py deleted file mode 100644 index 8c42920979..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_backdrop.py +++ /dev/null @@ -1,106 +0,0 @@ -import os - -import nuke - -import pyblish.api - -from ayon_core.pipeline import publish -from ayon_nuke.api.lib import ( - maintained_selection, - reset_selection, - select_nodes -) - - -class ExtractBackdropNode(publish.Extractor): - """Extracting content of backdrop nodes - - Will create nuke script only with containing nodes. - Also it will solve Input and Output nodes. - - """ - - order = pyblish.api.ExtractorOrder - label = "Extract Backdrop" - hosts = ["nuke"] - families = ["nukenodes"] - - settings_category = "nuke" - - def process(self, instance): - tmp_nodes = [] - child_nodes = instance.data["transientData"]["childNodes"] - # all connections outside of backdrop - connections_in = instance.data["transientData"]["nodeConnectionsIn"] - connections_out = instance.data["transientData"]["nodeConnectionsOut"] - self.log.debug("_ connections_in: `{}`".format(connections_in)) - self.log.debug("_ connections_out: `{}`".format(connections_out)) - - # Define extract output file path - stagingdir = self.staging_dir(instance) - filename = "{0}.nk".format(instance.name) - path = os.path.join(stagingdir, filename) - - # maintain selection - with maintained_selection(): - # create input child_nodes and name them as passing node (*_INP) - for n, inputs in connections_in.items(): - for i, input in inputs: - inpn = nuke.createNode("Input") - inpn["name"].setValue("{}_{}_INP".format(n.name(), i)) - n.setInput(i, inpn) - inpn.setXYpos(input.xpos(), input.ypos()) - child_nodes.append(inpn) - tmp_nodes.append(inpn) - - reset_selection() - - # connect output node - for n, output in connections_out.items(): - opn = nuke.createNode("Output") - output.setInput( - next((i for i, d in enumerate(output.dependencies()) - if d.name() in n.name()), 0), opn) - opn.setInput(0, n) - opn.autoplace() - child_nodes.append(opn) - tmp_nodes.append(opn) - reset_selection() - - # select child_nodes to copy - reset_selection() - select_nodes(child_nodes) - # create tmp nk file - # save file to the path - nuke.nodeCopy(path) - - # Clean up - for tn in tmp_nodes: - nuke.delete(tn) - - # restore original connections - # reconnect input node - for n, inputs in connections_in.items(): - for i, input in inputs: - n.setInput(i, input) - - # reconnect output node - for n, output in connections_out.items(): - output.setInput( - next((i for i, d in enumerate(output.dependencies()) - if d.name() in n.name()), 0), n) - - if "representations" not in instance.data: - instance.data["representations"] = [] - - # create representation - representation = { - 'name': 'nk', - 'ext': 'nk', - 'files': filename, - "stagingDir": stagingdir - } - instance.data["representations"].append(representation) - - self.log.debug("Extracted instance '{}' to: {}".format( - instance.name, path)) diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_camera.py b/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_camera.py deleted file mode 100644 index 83914087e3..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_camera.py +++ /dev/null @@ -1,185 +0,0 @@ -import os -import math - -import nuke - -import pyblish.api - -from ayon_core.pipeline import publish -from ayon_nuke.api.lib import maintained_selection - - -class ExtractCamera(publish.Extractor): - """ 3D camera extractor - """ - label = 'Extract Camera' - order = pyblish.api.ExtractorOrder - families = ["camera"] - hosts = ["nuke"] - - settings_category = "nuke" - - # presets - write_geo_knobs = [ - ("file_type", "abc"), - ("storageFormat", "Ogawa"), - ("writeGeometries", False), - ("writePointClouds", False), - ("writeAxes", False) - ] - - def process(self, instance): - camera_node = instance.data["transientData"]["node"] - handle_start = instance.context.data["handleStart"] - handle_end = instance.context.data["handleEnd"] - first_frame = int(nuke.root()["first_frame"].getValue()) - last_frame = int(nuke.root()["last_frame"].getValue()) - step = 1 - output_range = str(nuke.FrameRange(first_frame, last_frame, step)) - - rm_nodes = [] - self.log.debug("Creating additional nodes for 3D Camera Extractor") - product_name = instance.data["productName"] - staging_dir = self.staging_dir(instance) - - # get extension form preset - extension = next((k[1] for k in self.write_geo_knobs - if k[0] == "file_type"), None) - if not extension: - raise RuntimeError( - "Bad config for extension in presets. " - "Talk to your supervisor or pipeline admin") - - # create file name and path - filename = product_name + ".{}".format(extension) - file_path = os.path.join(staging_dir, filename).replace("\\", "/") - - with maintained_selection(): - # bake camera with axeses onto word coordinate XYZ - rm_n = bakeCameraWithAxeses( - camera_node, output_range) - rm_nodes.append(rm_n) - - # create scene node - rm_n = nuke.createNode("Scene") - rm_nodes.append(rm_n) - - # create write geo node - wg_n = nuke.createNode("WriteGeo") - wg_n["file"].setValue(file_path) - # add path to write to - for k, v in self.write_geo_knobs: - wg_n[k].setValue(v) - rm_nodes.append(wg_n) - - # write out camera - nuke.execute( - wg_n, - int(first_frame), - int(last_frame) - ) - # erase additional nodes - for n in rm_nodes: - nuke.delete(n) - - # create representation data - if "representations" not in instance.data: - instance.data["representations"] = [] - - representation = { - 'name': extension, - 'ext': extension, - 'files': filename, - "stagingDir": staging_dir, - "frameStart": first_frame, - "frameEnd": last_frame - } - instance.data["representations"].append(representation) - - instance.data.update({ - "path": file_path, - "outputDir": staging_dir, - "ext": extension, - "handleStart": handle_start, - "handleEnd": handle_end, - "frameStart": first_frame + handle_start, - "frameEnd": last_frame - handle_end, - "frameStartHandle": first_frame, - "frameEndHandle": last_frame, - }) - - self.log.debug("Extracted instance '{0}' to: {1}".format( - instance.name, file_path)) - - -def bakeCameraWithAxeses(camera_node, output_range): - """ Baking all perent hierarchy of axeses into camera - with transposition onto word XYZ coordinance - """ - bakeFocal = False - bakeHaperture = False - bakeVaperture = False - - camera_matrix = camera_node['world_matrix'] - - new_cam_n = nuke.createNode("Camera2") - new_cam_n.setInput(0, None) - new_cam_n['rotate'].setAnimated() - new_cam_n['translate'].setAnimated() - - old_focal = camera_node['focal'] - if old_focal.isAnimated() and not (old_focal.animation(0).constant()): - new_cam_n['focal'].setAnimated() - bakeFocal = True - else: - new_cam_n['focal'].setValue(old_focal.value()) - - old_haperture = camera_node['haperture'] - if old_haperture.isAnimated() and not ( - old_haperture.animation(0).constant()): - new_cam_n['haperture'].setAnimated() - bakeHaperture = True - else: - new_cam_n['haperture'].setValue(old_haperture.value()) - - old_vaperture = camera_node['vaperture'] - if old_vaperture.isAnimated() and not ( - old_vaperture.animation(0).constant()): - new_cam_n['vaperture'].setAnimated() - bakeVaperture = True - else: - new_cam_n['vaperture'].setValue(old_vaperture.value()) - - new_cam_n['win_translate'].setValue(camera_node['win_translate'].value()) - new_cam_n['win_scale'].setValue(camera_node['win_scale'].value()) - - for x in nuke.FrameRange(output_range): - math_matrix = nuke.math.Matrix4() - for y in range(camera_matrix.height()): - for z in range(camera_matrix.width()): - matrix_pointer = z + (y * camera_matrix.width()) - math_matrix[matrix_pointer] = camera_matrix.getValueAt( - x, (y + (z * camera_matrix.width()))) - - rot_matrix = nuke.math.Matrix4(math_matrix) - rot_matrix.rotationOnly() - rot = rot_matrix.rotationsZXY() - - new_cam_n['rotate'].setValueAt(math.degrees(rot[0]), x, 0) - new_cam_n['rotate'].setValueAt(math.degrees(rot[1]), x, 1) - new_cam_n['rotate'].setValueAt(math.degrees(rot[2]), x, 2) - new_cam_n['translate'].setValueAt( - camera_matrix.getValueAt(x, 3), x, 0) - new_cam_n['translate'].setValueAt( - camera_matrix.getValueAt(x, 7), x, 1) - new_cam_n['translate'].setValueAt( - camera_matrix.getValueAt(x, 11), x, 2) - - if bakeFocal: - new_cam_n['focal'].setValueAt(old_focal.getValueAt(x), x) - if bakeHaperture: - new_cam_n['haperture'].setValueAt(old_haperture.getValueAt(x), x) - if bakeVaperture: - new_cam_n['vaperture'].setValueAt(old_vaperture.getValueAt(x), x) - - return new_cam_n diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_gizmo.py b/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_gizmo.py deleted file mode 100644 index 05e3164163..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_gizmo.py +++ /dev/null @@ -1,91 +0,0 @@ -import os -import nuke - -import pyblish.api - -from ayon_core.pipeline import publish -from ayon_nuke.api import utils as pnutils -from ayon_nuke.api.lib import ( - maintained_selection, - reset_selection, - select_nodes -) - - -class ExtractGizmo(publish.Extractor): - """Extracting Gizmo (Group) node - - Will create nuke script only with the Gizmo node. - """ - - order = pyblish.api.ExtractorOrder - label = "Extract Gizmo (group)" - hosts = ["nuke"] - families = ["gizmo"] - - settings_category = "nuke" - - def process(self, instance): - tmp_nodes = [] - orig_grpn = instance.data["transientData"]["node"] - - # Define extract output file path - stagingdir = self.staging_dir(instance) - filename = "{0}.nk".format(instance.name) - path = os.path.join(stagingdir, filename) - - # maintain selection - with maintained_selection(): - orig_grpn_name = orig_grpn.name() - tmp_grpn_name = orig_grpn_name + "_tmp" - # select original group node - select_nodes([orig_grpn]) - - # copy to clipboard - nuke.nodeCopy("%clipboard%") - - # reset selection to none - reset_selection() - - # paste clipboard - nuke.nodePaste("%clipboard%") - - # assign pasted node - copy_grpn = nuke.selectedNode() - copy_grpn.setXYpos((orig_grpn.xpos() + 120), orig_grpn.ypos()) - - # convert gizmos to groups - pnutils.bake_gizmos_recursively(copy_grpn) - - # add to temporary nodes - tmp_nodes.append(copy_grpn) - - # swap names - orig_grpn.setName(tmp_grpn_name) - copy_grpn.setName(orig_grpn_name) - - # create tmp nk file - # save file to the path - nuke.nodeCopy(path) - - # Clean up - for tn in tmp_nodes: - nuke.delete(tn) - - # rename back to original - orig_grpn.setName(orig_grpn_name) - - if "representations" not in instance.data: - instance.data["representations"] = [] - - # create representation - representation = { - 'name': 'gizmo', - 'ext': 'nk', - 'files': filename, - "stagingDir": stagingdir - } - instance.data["representations"].append(representation) - - self.log.debug("Extracted instance '{}' to: {}".format( - instance.name, path)) diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_headless_farm.py b/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_headless_farm.py deleted file mode 100644 index 4721fe4462..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_headless_farm.py +++ /dev/null @@ -1,38 +0,0 @@ -import os -from datetime import datetime -import shutil - -import pyblish.api - -from ayon_core.pipeline import registered_host - - -class ExtractRenderOnFarm(pyblish.api.InstancePlugin): - """Copy the workfile to a timestamped copy.""" - - order = pyblish.api.ExtractorOrder + 0.499 - label = "Extract Render On Farm" - hosts = ["nuke"] - families = ["render_on_farm"] - - settings_category = "nuke" - - def process(self, instance): - if not instance.context.data.get("render_on_farm", False): - return - - host = registered_host() - current_datetime = datetime.now() - formatted_timestamp = current_datetime.strftime("%Y%m%d%H%M%S") - base, ext = os.path.splitext(host.current_file()) - - directory = os.path.join(os.path.dirname(base), "farm_submissions") - if not os.path.exists(directory): - os.makedirs(directory) - - filename = "{}_{}{}".format( - os.path.basename(base), formatted_timestamp, ext - ) - path = os.path.join(directory, filename).replace("\\", "/") - instance.context.data["currentFile"] = path - shutil.copy(host.current_file(), path) diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_model.py b/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_model.py deleted file mode 100644 index 58b9d4179b..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_model.py +++ /dev/null @@ -1,110 +0,0 @@ -import os -from pprint import pformat -import nuke -import pyblish.api - -from ayon_core.pipeline import publish -from ayon_nuke.api.lib import ( - maintained_selection, - select_nodes -) - - -class ExtractModel(publish.Extractor): - """ 3D model extractor - """ - label = 'Extract Model' - order = pyblish.api.ExtractorOrder - families = ["model"] - hosts = ["nuke"] - - settings_category = "nuke" - - # presets - write_geo_knobs = [ - ("file_type", "abc"), - ("storageFormat", "Ogawa"), - ("writeGeometries", True), - ("writePointClouds", False), - ("writeAxes", False) - ] - - def process(self, instance): - handle_start = instance.context.data["handleStart"] - handle_end = instance.context.data["handleEnd"] - first_frame = int(nuke.root()["first_frame"].getValue()) - last_frame = int(nuke.root()["last_frame"].getValue()) - - self.log.debug("instance.data: `{}`".format( - pformat(instance.data))) - - rm_nodes = [] - model_node = instance.data["transientData"]["node"] - - self.log.debug("Creating additional nodes for Extract Model") - product_name = instance.data["productName"] - staging_dir = self.staging_dir(instance) - - extension = next((k[1] for k in self.write_geo_knobs - if k[0] == "file_type"), None) - if not extension: - raise RuntimeError( - "Bad config for extension in presets. " - "Talk to your supervisor or pipeline admin") - - # create file name and path - filename = product_name + ".{}".format(extension) - file_path = os.path.join(staging_dir, filename).replace("\\", "/") - - with maintained_selection(): - # select model node - select_nodes([model_node]) - - # create write geo node - wg_n = nuke.createNode("WriteGeo") - wg_n["file"].setValue(file_path) - # add path to write to - for k, v in self.write_geo_knobs: - wg_n[k].setValue(v) - rm_nodes.append(wg_n) - - # write out model - nuke.execute( - wg_n, - int(first_frame), - int(last_frame) - ) - # erase additional nodes - for n in rm_nodes: - nuke.delete(n) - - self.log.debug("Filepath: {}".format(file_path)) - - # create representation data - if "representations" not in instance.data: - instance.data["representations"] = [] - - representation = { - 'name': extension, - 'ext': extension, - 'files': filename, - "stagingDir": staging_dir, - "frameStart": first_frame, - "frameEnd": last_frame - } - instance.data["representations"].append(representation) - - instance.data.update({ - "path": file_path, - "outputDir": staging_dir, - "ext": extension, - "handleStart": handle_start, - "handleEnd": handle_end, - "frameStart": first_frame + handle_start, - "frameEnd": last_frame - handle_end, - "frameStartHandle": first_frame, - "frameEndHandle": last_frame, - }) - - self.log.debug("Extracted instance '{0}' to: {1}".format( - instance.name, file_path)) diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_ouput_node.py b/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_ouput_node.py deleted file mode 100644 index 52072cddc5..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_ouput_node.py +++ /dev/null @@ -1,45 +0,0 @@ -import nuke -import pyblish.api -from ayon_nuke.api.lib import maintained_selection - - -class CreateOutputNode(pyblish.api.ContextPlugin): - """Adding output node for each output write node - So when latly user will want to Load .nk as LifeGroup or Precomp - Nuke will not complain about missing Output node - """ - label = 'Output Node Create' - order = pyblish.api.ExtractorOrder + 0.4 - families = ["workfile"] - hosts = ["nuke"] - - settings_category = "nuke" - - def process(self, context): - # capture selection state - with maintained_selection(): - - active_node = [ - inst.data.get("transientData", {}).get("node") - for inst in context - if inst.data.get("transientData", {}).get("node") - if inst.data.get( - "transientData", {}).get("node").Class() != "Root" - ] - - if active_node: - active_node = active_node.pop() - self.log.debug("Active node: {}".format(active_node)) - active_node['selected'].setValue(True) - - # select only instance render node - output_node = nuke.createNode("Output") - - # deselect all and select the original selection - output_node['selected'].setValue(False) - - # save script - nuke.scriptSave() - - # add node to instance node list - context.data["outputNode"] = output_node diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_output_directory.py b/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_output_directory.py deleted file mode 100644 index 45156ca9ae..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_output_directory.py +++ /dev/null @@ -1,26 +0,0 @@ -import os - -import pyblish.api - - -class ExtractOutputDirectory(pyblish.api.InstancePlugin): - """Extracts the output path for any collection or single output_path.""" - - order = pyblish.api.ExtractorOrder - 0.05 - label = "Output Directory" - optional = True - - settings_category = "nuke" - - def process(self, instance): - - path = None - - if "output_path" in instance.data.keys(): - path = instance.data["path"] - - if not path: - return - - if not os.path.exists(os.path.dirname(path)): - os.makedirs(os.path.dirname(path)) diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_render_local.py b/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_render_local.py deleted file mode 100644 index c865684e7a..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_render_local.py +++ /dev/null @@ -1,218 +0,0 @@ -import os -import shutil - -import pyblish.api -import clique -import nuke -from ayon_nuke import api as napi -from ayon_core.pipeline import publish -from ayon_core.lib import collect_frames - - -class NukeRenderLocal(publish.Extractor, - publish.ColormanagedPyblishPluginMixin): - """Render the current Nuke composition locally. - - Extract the result of savers by starting a comp render - This will run the local render of Fusion. - - Allows to use last published frames and overwrite only specific ones - (set in instance.data.get("frames_to_fix")) - """ - - order = pyblish.api.ExtractorOrder - label = "Render Local" - hosts = ["nuke"] - families = ["render.local", "prerender.local", "image.local"] - - settings_category = "nuke" - - def process(self, instance): - child_nodes = ( - instance.data.get("transientData", {}).get("childNodes") - or instance - ) - - node = None - for x in child_nodes: - if x.Class() == "Write": - node = x - - self.log.debug("instance collected: {}".format(instance.data)) - - node_product_name = instance.data.get("name", None) - - first_frame = instance.data.get("frameStartHandle", None) - last_frame = instance.data.get("frameEndHandle", None) - - filenames = [] - node_file = node["file"] - # Collect expected filepaths for each frame - # - for cases that output is still image is first created set of - # paths which is then sorted and converted to list - expected_paths = list(sorted({ - node_file.evaluate(frame) - for frame in range(first_frame, last_frame + 1) - })) - # Extract only filenames for representation - filenames.extend([ - os.path.basename(filepath) - for filepath in expected_paths - ]) - - # Ensure output directory exists. - out_dir = os.path.dirname(expected_paths[0]) - if not os.path.exists(out_dir): - os.makedirs(out_dir) - - frames_to_render = [(first_frame, last_frame)] - - frames_to_fix = instance.data.get("frames_to_fix") - if instance.data.get("last_version_published_files") and frames_to_fix: - frames_to_render = self._get_frames_to_render(frames_to_fix) - anatomy = instance.context.data["anatomy"] - self._copy_last_published(anatomy, instance, out_dir, - filenames) - - for render_first_frame, render_last_frame in frames_to_render: - - self.log.info("Starting render") - self.log.info("Start frame: {}".format(render_first_frame)) - self.log.info("End frame: {}".format(render_last_frame)) - - # Render frames - nuke.execute( - str(node_product_name), - int(render_first_frame), - int(render_last_frame) - ) - - ext = node["file_type"].value() - colorspace = napi.get_colorspace_from_node(node) - - if "representations" not in instance.data: - instance.data["representations"] = [] - - if len(filenames) == 1: - repre = { - 'name': ext, - 'ext': ext, - 'files': filenames[0], - "stagingDir": out_dir - } - else: - repre = { - 'name': ext, - 'ext': ext, - 'frameStart': ( - "{{:0>{}}}" - .format(len(str(last_frame))) - .format(first_frame) - ), - 'files': filenames, - "stagingDir": out_dir - } - - # inject colorspace data - self.set_representation_colorspace( - repre, instance.context, - colorspace=colorspace - ) - - instance.data["representations"].append(repre) - - self.log.debug("Extracted instance '{0}' to: {1}".format( - instance.name, - out_dir - )) - - families = instance.data["families"] - anatomy_data = instance.data["anatomyData"] - # redefinition of families - if "render.local" in families: - instance.data["family"] = "render" - instance.data["productType"] = "render" - families.remove("render.local") - families.insert(0, "render2d") - anatomy_data["family"] = "render" - anatomy_data["product"]["type"] = "render" - elif "prerender.local" in families: - instance.data["family"] = "prerender" - instance.data["productType"] = "prerender" - families.remove("prerender.local") - families.insert(0, "prerender") - anatomy_data["family"] = "prerender" - anatomy_data["product"]["type"] = "prerender" - elif "image.local" in families: - instance.data["family"] = "image" - instance.data["productType"] = "image" - families.remove("image.local") - anatomy_data["family"] = "image" - anatomy_data["product"]["type"] = "image" - instance.data["families"] = families - - collections, remainder = clique.assemble(filenames) - self.log.debug('collections: {}'.format(str(collections))) - - if collections: - collection = collections[0] - instance.data['collection'] = collection - - self.log.info('Finished render') - - self.log.debug("_ instance.data: {}".format(instance.data)) - - def _copy_last_published(self, anatomy, instance, out_dir, - expected_filenames): - """Copies last published files to temporary out_dir. - - These are base of files which will be extended/fixed for specific - frames. - Renames published file to expected file name based on frame, eg. - test_project_test_asset_product_v005.1001.exr > new_render.1001.exr - """ - last_published = instance.data["last_version_published_files"] - last_published_and_frames = collect_frames(last_published) - - expected_and_frames = collect_frames(expected_filenames) - frames_and_expected = {v: k for k, v in expected_and_frames.items()} - for file_path, frame in last_published_and_frames.items(): - file_path = anatomy.fill_root(file_path) - if not os.path.exists(file_path): - continue - target_file_name = frames_and_expected.get(frame) - if not target_file_name: - continue - - out_path = os.path.join(out_dir, target_file_name) - self.log.debug("Copying '{}' -> '{}'".format(file_path, out_path)) - shutil.copy(file_path, out_path) - - # TODO shouldn't this be uncommented - # instance.context.data["cleanupFullPaths"].append(out_path) - - def _get_frames_to_render(self, frames_to_fix): - """Return list of frame range tuples to render - - Args: - frames_to_fix (str): specific or range of frames to be rerendered - (1005, 1009-1010) - Returns: - (list): [(1005, 1005), (1009-1010)] - """ - frames_to_render = [] - - for frame_range in frames_to_fix.split(","): - if frame_range.isdigit(): - render_first_frame = frame_range - render_last_frame = frame_range - elif '-' in frame_range: - frames = frame_range.split('-') - render_first_frame = int(frames[0]) - render_last_frame = int(frames[1]) - else: - raise ValueError("Wrong format of frames to fix {}" - .format(frames_to_fix)) - frames_to_render.append((render_first_frame, - render_last_frame)) - return frames_to_render diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_review_data.py b/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_review_data.py deleted file mode 100644 index 856616898b..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_review_data.py +++ /dev/null @@ -1,50 +0,0 @@ -import os -from pprint import pformat -import pyblish.api - -from ayon_core.pipeline import publish - - -class ExtractReviewData(publish.Extractor): - """Extracts review tag into available representation - """ - - order = pyblish.api.ExtractorOrder + 0.01 - # order = pyblish.api.CollectorOrder + 0.499 - label = "Extract Review Data" - - families = ["review"] - hosts = ["nuke"] - - settings_category = "nuke" - - def process(self, instance): - fpath = instance.data["path"] - ext = os.path.splitext(fpath)[-1][1:] - - representations = instance.data.get("representations", []) - - # review can be removed since `ProcessSubmittedJobOnFarm` will create - # reviewable representation if needed - if ( - instance.data.get("farm") - and "review" in instance.data["families"] - ): - instance.data["families"].remove("review") - - # iterate representations and add `review` tag - for repre in representations: - if ext != repre["ext"]: - continue - - if not repre.get("tags"): - repre["tags"] = [] - - if "review" not in repre["tags"]: - repre["tags"].append("review") - - self.log.debug("Matching representation: {}".format( - pformat(repre) - )) - - instance.data["representations"] = representations diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_review_data_lut.py b/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_review_data_lut.py deleted file mode 100644 index d3377807ea..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_review_data_lut.py +++ /dev/null @@ -1,64 +0,0 @@ -import os -import pyblish.api - -from ayon_core.pipeline import publish -from ayon_nuke.api import plugin -from ayon_nuke.api.lib import maintained_selection - - -class ExtractReviewDataLut(publish.Extractor): - """Extracts movie and thumbnail with baked in luts - - must be run after extract_render_local.py - - """ - - order = pyblish.api.ExtractorOrder + 0.005 - label = "Extract Review Data Lut" - - families = ["review"] - hosts = ["nuke"] - - settings_category = "nuke" - - def process(self, instance): - self.log.debug("Creating staging dir...") - if "representations" in instance.data: - staging_dir = instance.data[ - "representations"][0]["stagingDir"].replace("\\", "/") - instance.data["stagingDir"] = staging_dir - instance.data["representations"][0]["tags"] = ["review"] - else: - instance.data["representations"] = [] - # get output path - render_path = instance.data['path'] - staging_dir = os.path.normpath(os.path.dirname(render_path)) - instance.data["stagingDir"] = staging_dir - - self.log.debug( - "StagingDir `{0}`...".format(instance.data["stagingDir"])) - - # generate data - with maintained_selection(): - exporter = plugin.ExporterReviewLut( - self, instance - ) - data = exporter.generate_lut() - - # assign to representations - instance.data["lutPath"] = os.path.join( - exporter.stagingDir, exporter.file).replace("\\", "/") - instance.data["representations"] += data["representations"] - - # review can be removed since `ProcessSubmittedJobOnFarm` will create - # reviewable representation if needed - if ( - instance.data.get("farm") - and "review" in instance.data["families"] - ): - instance.data["families"].remove("review") - - self.log.debug( - "_ lutPath: {}".format(instance.data["lutPath"])) - self.log.debug( - "_ representations: {}".format(instance.data["representations"])) diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_review_intermediates.py b/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_review_intermediates.py deleted file mode 100644 index 48c9988c5b..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_review_intermediates.py +++ /dev/null @@ -1,161 +0,0 @@ -import os -import re -from pprint import pformat -import pyblish.api - -from ayon_core.pipeline import publish -from ayon_nuke.api import plugin -from ayon_nuke.api.lib import maintained_selection - - -class ExtractReviewIntermediates(publish.Extractor): - """Extracting intermediate videos or sequences with - thumbnail for transcoding. - - must be run after extract_render_local.py - - """ - - order = pyblish.api.ExtractorOrder + 0.01 - label = "Extract Review Intermediates" - - families = ["review"] - hosts = ["nuke"] - - settings_category = "nuke" - - # presets - viewer_lut_raw = None - outputs = {} - - def process(self, instance): - # TODO 'families' should not be included for filtering of outputs - families = set(instance.data["families"]) - - # Add product type to families - families.add(instance.data["productType"]) - - task_type = instance.context.data["taskType"] - product_name = instance.data["productName"] - self.log.debug("Creating staging dir...") - - if "representations" not in instance.data: - instance.data["representations"] = [] - - staging_dir = os.path.normpath( - os.path.dirname(instance.data["path"])) - - instance.data["stagingDir"] = staging_dir - - self.log.debug( - "StagingDir `{0}`...".format(instance.data["stagingDir"])) - - self.log.debug("Outputs: {}".format(self.outputs)) - - # generate data - with maintained_selection(): - generated_repres = [] - for o_data in self.outputs: - o_name = o_data["name"] - self.log.debug( - "o_name: {}, o_data: {}".format(o_name, pformat(o_data))) - f_product_types = o_data["filter"]["product_types"] - f_task_types = o_data["filter"]["task_types"] - product_names = o_data["filter"]["product_names"] - - self.log.debug( - "f_product_types `{}` > families: {}".format( - f_product_types, families)) - - self.log.debug( - "f_task_types `{}` > task_type: {}".format( - f_task_types, task_type)) - - self.log.debug( - "product_names `{}` > product: {}".format( - product_names, product_name)) - - # test if family found in context - # using intersection to make sure all defined - # families are present in combination - if ( - f_product_types - and not families.intersection(f_product_types) - ): - continue - - # test task types from filter - if f_task_types and task_type not in f_task_types: - continue - - # test products from filter - if product_names and not any( - re.search(p, product_name) for p in product_names - ): - continue - - self.log.debug( - "Baking output `{}` with settings: {}".format( - o_name, o_data) - ) - - # check if settings have more then one preset - # so we dont need to add outputName to representation - # in case there is only one preset - multiple_presets = len(self.outputs) > 1 - - # adding bake presets to instance data for other plugins - if not instance.data.get("bakePresets"): - instance.data["bakePresets"] = {} - # add preset to bakePresets - instance.data["bakePresets"][o_name] = o_data - - # create exporter instance - exporter = plugin.ExporterReviewMov( - self, instance, o_name, o_data["extension"], - multiple_presets) - - delete = not o_data.get("publish", False) - - if instance.data.get("farm"): - if "review" in instance.data["families"]: - instance.data["families"].remove("review") - - data = exporter.generate_mov( - farm=True, delete=delete, **o_data - ) - - self.log.debug( - "_ data: {}".format(data)) - - if not instance.data.get("bakingNukeScripts"): - instance.data["bakingNukeScripts"] = [] - - instance.data["bakingNukeScripts"].append({ - "bakeRenderPath": data.get("bakeRenderPath"), - "bakeScriptPath": data.get("bakeScriptPath"), - "bakeWriteNodeName": data.get("bakeWriteNodeName") - }) - else: - data = exporter.generate_mov(delete=delete, **o_data) - - # add representation generated by exporter - generated_repres.extend(data["representations"]) - self.log.debug( - "__ generated_repres: {}".format(generated_repres)) - - if generated_repres: - # assign to representations - instance.data["representations"] += generated_repres - instance.data["useSequenceForReview"] = False - else: - instance.data["families"].remove("review") - self.log.debug( - "Removing `review` from families. " - "Not available baking profile." - ) - self.log.debug(instance.data["families"]) - - self.log.debug( - "_ representations: {}".format( - instance.data["representations"])) diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_script_save.py b/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_script_save.py deleted file mode 100644 index ea584b6529..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_script_save.py +++ /dev/null @@ -1,16 +0,0 @@ -import nuke -import pyblish.api - - -class ExtractScriptSave(pyblish.api.InstancePlugin): - """Save current Nuke workfile script""" - label = 'Script Save' - order = pyblish.api.ExtractorOrder - 0.1 - hosts = ["nuke"] - - settings_category = "nuke" - - def process(self, instance): - - self.log.debug('Saving current script') - nuke.scriptSave() diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_slate_frame.py b/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_slate_frame.py deleted file mode 100644 index 47750ea637..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/extract_slate_frame.py +++ /dev/null @@ -1,366 +0,0 @@ -import os -from pprint import pformat -import nuke -import copy - -import pyblish.api -import six - -from ayon_core.pipeline import publish -from ayon_nuke.api import ( - maintained_selection, - duplicate_node, - get_view_process_node -) - - -class ExtractSlateFrame(publish.Extractor): - """Extracts movie and thumbnail with baked in luts - - must be run after extract_render_local.py - - """ - - order = pyblish.api.ExtractorOrder + 0.011 - label = "Extract Slate Frame" - - families = ["slate"] - hosts = ["nuke"] - - settings_category = "nuke" - - # Settings values - key_value_mapping = { - "f_submission_note": { - "enabled": True, "template": "{comment}" - }, - "f_submitting_for": { - "enabled": True, "template": "{intent[value]}" - }, - "f_vfx_scope_of_work": { - "enabled": False, "template": "" - } - } - - def process(self, instance): - - if "representations" not in instance.data: - instance.data["representations"] = [] - - self._create_staging_dir(instance) - - with maintained_selection(): - self.log.debug("instance: {}".format(instance)) - self.log.debug("instance.data[families]: {}".format( - instance.data["families"])) - - if instance.data.get("bakePresets"): - for o_name, o_data in instance.data["bakePresets"].items(): - self.log.debug("_ o_name: {}, o_data: {}".format( - o_name, pformat(o_data))) - self.render_slate( - instance, - o_name, - o_data["bake_viewer_process"], - o_data["bake_viewer_input_process"] - ) - else: - # backward compatibility - self.render_slate(instance) - - # also render image to sequence - self._render_slate_to_sequence(instance) - - def _create_staging_dir(self, instance): - - self.log.debug("Creating staging dir...") - - staging_dir = os.path.normpath( - os.path.dirname(instance.data["path"])) - - instance.data["stagingDir"] = staging_dir - - self.log.debug( - "StagingDir `{0}`...".format(instance.data["stagingDir"])) - - def _check_frames_exists(self, instance): - # rendering path from group write node - fpath = instance.data["path"] - - # instance frame range with handles - first = instance.data["frameStartHandle"] - last = instance.data["frameEndHandle"] - - padding = fpath.count('#') - - test_path_template = fpath - if padding: - repl_string = "#" * padding - test_path_template = fpath.replace( - repl_string, "%0{}d".format(padding)) - - for frame in range(first, last + 1): - test_file = test_path_template % frame - if not os.path.exists(test_file): - self.log.debug("__ test_file: `{}`".format(test_file)) - return None - - return True - - def render_slate( - self, - instance, - output_name=None, - bake_viewer_process=True, - bake_viewer_input_process=True - ): - """Slate frame renderer - - Args: - instance (PyblishInstance): Pyblish instance with product data - output_name (str, optional): - Slate variation name. Defaults to None. - bake_viewer_process (bool, optional): - Switch for viewer profile baking. Defaults to True. - bake_viewer_input_process (bool, optional): - Switch for input process node baking. Defaults to True. - """ - slate_node = instance.data["slateNode"] - - # rendering path from group write node - fpath = instance.data["path"] - - # instance frame range with handles - first_frame = instance.data["frameStartHandle"] - last_frame = instance.data["frameEndHandle"] - - # fill slate node with comments - self.add_comment_slate_node(instance, slate_node) - - # solve output name if any is set - _output_name = output_name or "" - if _output_name: - _output_name = "_" + _output_name - - slate_first_frame = first_frame - 1 - - collection = instance.data.get("collection", None) - - if collection: - # get path - fname = os.path.basename(collection.format( - "{head}{padding}{tail}")) - fhead = collection.format("{head}") - else: - fname = os.path.basename(fpath) - fhead = os.path.splitext(fname)[0] + "." - - if "#" in fhead: - fhead = fhead.replace("#", "")[:-1] - - self.log.debug("__ first_frame: {}".format(first_frame)) - self.log.debug("__ slate_first_frame: {}".format(slate_first_frame)) - - above_slate_node = slate_node.dependencies().pop() - # fallback if files does not exists - if self._check_frames_exists(instance): - # Read node - r_node = nuke.createNode("Read") - r_node["file"].setValue(fpath) - r_node["first"].setValue(first_frame) - r_node["origfirst"].setValue(first_frame) - r_node["last"].setValue(last_frame) - r_node["origlast"].setValue(last_frame) - r_node["colorspace"].setValue(instance.data["colorspace"]) - previous_node = r_node - temporary_nodes = [previous_node] - - # adding copy metadata node for correct frame metadata - cm_node = nuke.createNode("CopyMetaData") - cm_node.setInput(0, previous_node) - cm_node.setInput(1, above_slate_node) - previous_node = cm_node - temporary_nodes.append(cm_node) - - else: - previous_node = above_slate_node - temporary_nodes = [] - - # only create colorspace baking if toggled on - if bake_viewer_process: - if bake_viewer_input_process: - # get input process and connect it to baking - ipn = get_view_process_node() - if ipn is not None: - ipn.setInput(0, previous_node) - previous_node = ipn - temporary_nodes.append(ipn) - - # add duplicate slate node and connect to previous - duply_slate_node = duplicate_node(slate_node) - duply_slate_node.setInput(0, previous_node) - previous_node = duply_slate_node - temporary_nodes.append(duply_slate_node) - - # add viewer display transformation node - dag_node = nuke.createNode("OCIODisplay") - dag_node.setInput(0, previous_node) - previous_node = dag_node - temporary_nodes.append(dag_node) - - else: - # add duplicate slate node and connect to previous - duply_slate_node = duplicate_node(slate_node) - duply_slate_node.setInput(0, previous_node) - previous_node = duply_slate_node - temporary_nodes.append(duply_slate_node) - - # create write node - write_node = nuke.createNode("Write") - file = fhead[:-1] + _output_name + "_slate.png" - path = os.path.join( - instance.data["stagingDir"], file).replace("\\", "/") - - # add slate path to `slateFrames` instance data attr - if not instance.data.get("slateFrames"): - instance.data["slateFrames"] = {} - - instance.data["slateFrames"][output_name or "*"] = path - - # create write node - write_node["file"].setValue(path) - write_node["file_type"].setValue("png") - write_node["raw"].setValue(1) - write_node.setInput(0, previous_node) - temporary_nodes.append(write_node) - - # Render frames - nuke.execute( - write_node.name(), int(slate_first_frame), int(slate_first_frame)) - - # Clean up - for node in temporary_nodes: - nuke.delete(node) - - def _render_slate_to_sequence(self, instance): - # set slate frame - first_frame = instance.data["frameStartHandle"] - last_frame = instance.data["frameEndHandle"] - slate_first_frame = first_frame - 1 - - # render slate as sequence frame - nuke.execute( - instance.data["name"], - int(slate_first_frame), - int(slate_first_frame) - ) - - # Add file to representation files - # - get write node - write_node = instance.data["transientData"]["writeNode"] - # - evaluate filepaths for first frame and slate frame - first_filename = os.path.basename( - write_node["file"].evaluate(first_frame)) - slate_filename = os.path.basename( - write_node["file"].evaluate(slate_first_frame)) - - # Find matching representation based on first filename - matching_repre = None - is_sequence = None - for repre in instance.data["representations"]: - files = repre["files"] - if ( - not isinstance(files, six.string_types) - and first_filename in files - ): - matching_repre = repre - is_sequence = True - break - - elif files == first_filename: - matching_repre = repre - is_sequence = False - break - - if not matching_repre: - self.log.info( - "Matching representation was not found." - " Representation files were not filled with slate." - ) - return - - # Add frame to matching representation files - if not is_sequence: - matching_repre["files"] = [first_filename, slate_filename] - elif slate_filename not in matching_repre["files"]: - matching_repre["files"].insert(0, slate_filename) - matching_repre["frameStart"] = ( - "{{:0>{}}}" - .format(len(str(last_frame))) - .format(slate_first_frame) - ) - self.log.debug( - "__ matching_repre: {}".format(pformat(matching_repre))) - - data = matching_repre.get("data", {}) - data["slateFrames"] = 1 - matching_repre["data"] = data - - self.log.info("Added slate frame to representation files") - - def add_comment_slate_node(self, instance, node): - - comment = instance.data["comment"] - intent = instance.context.data.get("intent") - if not isinstance(intent, dict): - intent = { - "label": intent, - "value": intent - } - - fill_data = copy.deepcopy(instance.data["anatomyData"]) - fill_data.update({ - "custom": copy.deepcopy( - instance.data.get("customData") or {} - ), - "comment": comment, - "intent": intent - }) - - for key, _values in self.key_value_mapping.items(): - if not _values["enabled"]: - self.log.debug("Key \"{}\" is disabled".format(key)) - continue - - template = _values["template"] - try: - value = template.format(**fill_data) - - except ValueError: - self.log.warning( - "Couldn't fill template \"{}\" with data: {}".format( - template, fill_data - ), - exc_info=True - ) - continue - - except KeyError: - self.log.warning( - ( - "Template contains unknown key." - " Template \"{}\" Data: {}" - ).format(template, fill_data), - exc_info=True - ) - continue - - try: - node[key].setValue(value) - self.log.debug("Change key \"{}\" to value \"{}\"".format( - key, value - )) - except NameError: - self.log.warning(( - "Failed to set value \"{0}\" on node attribute \"{0}\"" - ).format(value)) diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/help/validate_asset_context.xml b/server_addon/nuke/client/ayon_nuke/plugins/publish/help/validate_asset_context.xml deleted file mode 100644 index 1e7d340a13..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/help/validate_asset_context.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - Folder path - -## Publishing to a different folder context - -There are publish instances present which are publishing into a different folder than your current context. - -Usually this is not what you want but there can be cases where you might want to publish into another folder/shot or task. - -If that's the case you can disable the validation on the instance to ignore it. - -The wrong node's name is: \`{node_name}\` - -### Correct context keys and values: - -\`{correct_values}\` - -### Wrong keys and values: - -\`{wrong_values}\`. - - -## How to repair? - -1. Use \"Repair\" button. -2. Hit Reload button on the publisher. - - - diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/help/validate_backdrop.xml b/server_addon/nuke/client/ayon_nuke/plugins/publish/help/validate_backdrop.xml deleted file mode 100644 index ab1b650773..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/help/validate_backdrop.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - Found multiple outputs - -## Invalid output amount - -Backdrop is having more than one outgoing connections. - -### How to repair? - -1. Use button `Center node in node graph` and navigate to the backdrop. -2. Reorganize nodes the way only one outgoing connection is present. -3. Hit reload button on the publisher. - - -### How could this happen? - -More than one node, which are found above the backdrop, are linked downstream or more output connections from a node also linked downstream. - - - - Empty backdrop - -## Invalid empty backdrop - -Backdrop is empty and no nodes are found above it. - -### How to repair? - -1. Use button `Center node in node graph` and navigate to the backdrop. -2. Add any node above it or delete it. -3. Hit reload button on the publisher. - - - \ No newline at end of file diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/help/validate_gizmo.xml b/server_addon/nuke/client/ayon_nuke/plugins/publish/help/validate_gizmo.xml deleted file mode 100644 index f39a41a4f9..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/help/validate_gizmo.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - Found multiple outputs - -## Invalid amount of Output nodes - -Group node `{node_name}` is having more than one Output node. - -### How to repair? - -1. Use button `Open Group`. -2. Remove redundant Output node. -3. Hit reload button on the publisher. - - -### How could this happen? - -Perhaps you had created exciently more than one Output node. - - - - Missing Input nodes - -## Missing Input nodes - -Make sure there is at least one connected Input node inside the group node with name `{node_name}` - -### How to repair? - -1. Use button `Open Group`. -2. Add at least one Input node and connect to other nodes. -3. Hit reload button on the publisher. - - - \ No newline at end of file diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/help/validate_knobs.xml b/server_addon/nuke/client/ayon_nuke/plugins/publish/help/validate_knobs.xml deleted file mode 100644 index 76c184f653..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/help/validate_knobs.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - Knobs value - -## Invalid node's knobs values - -Following node knobs needs to be repaired: - -{invalid_items} - -### How to repair? - -1. Use Repair button. -2. Hit Reload button on the publisher. - - - \ No newline at end of file diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/help/validate_output_resolution.xml b/server_addon/nuke/client/ayon_nuke/plugins/publish/help/validate_output_resolution.xml deleted file mode 100644 index 08a88a993e..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/help/validate_output_resolution.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - Output format - -## Invalid format setting - -Either the Reformat node inside of the render group is missing or the Reformat node output format knob is not set to `root.format`. - -### How to repair? - -1. Use Repair button. -2. Hit Reload button on the publisher. - - - \ No newline at end of file diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/help/validate_proxy_mode.xml b/server_addon/nuke/client/ayon_nuke/plugins/publish/help/validate_proxy_mode.xml deleted file mode 100644 index 6fe5d5d43e..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/help/validate_proxy_mode.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - Proxy mode - -## Invalid proxy mode value - -Nuke is set to use Proxy. This is not supported by publisher. - -### How to repair? - -1. Use Repair button. -2. Hit Reload button on the publisher. - - - \ No newline at end of file diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/help/validate_rendered_frames.xml b/server_addon/nuke/client/ayon_nuke/plugins/publish/help/validate_rendered_frames.xml deleted file mode 100644 index 434081c269..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/help/validate_rendered_frames.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - Rendered Frames - -## Missing Rendered Frames - -Render node "{node_name}" is set to "Use existing frames", but frames are missing. - -### How to repair? - -1. Use Repair button. -2. Set different target. -2. Hit Reload button on the publisher. - - - \ No newline at end of file diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/help/validate_script_attributes.xml b/server_addon/nuke/client/ayon_nuke/plugins/publish/help/validate_script_attributes.xml deleted file mode 100644 index 871fc629ce..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/help/validate_script_attributes.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - Script attributes - -## Invalid Script attributes - -Following script root attributes need to be fixed: - -{failed_attributes} - -### How to repair? - -1. Use Repair. -2. Hit Reload button on the publisher. - - - \ No newline at end of file diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/help/validate_write_nodes.xml b/server_addon/nuke/client/ayon_nuke/plugins/publish/help/validate_write_nodes.xml deleted file mode 100644 index 96aa6e4494..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/help/validate_write_nodes.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - Knobs values - - ## Invalid node's knobs values - - Following write node knobs needs to be repaired: - - {xml_msg} - - ### How to repair? - - 1. Use Repair button. - 2. Hit Reload button on the publisher. - - - - Legacy knob types - - ## Knobs are in obsolete configuration - - Settings needs to be fixed. - - ### How to repair? - - Contact your supervisor or fix it in project settings at - 'project_settings/nuke/imageio/nodes/required_nodes' at knobs. - Each '__legacy__' type has to be defined accordingly to its type. - - - \ No newline at end of file diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/increment_script_version.py b/server_addon/nuke/client/ayon_nuke/plugins/publish/increment_script_version.py deleted file mode 100644 index 36659aa2d2..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/increment_script_version.py +++ /dev/null @@ -1,26 +0,0 @@ -import nuke -import pyblish.api - - -class IncrementScriptVersion(pyblish.api.ContextPlugin): - """Increment current script version.""" - - order = pyblish.api.IntegratorOrder + 0.9 - label = "Increment Script Version" - optional = True - families = ["workfile"] - hosts = ["nuke"] - - settings_category = "nuke" - - def process(self, context): - if not context.data.get("increment_script_version", True): - return - - assert all(result["success"] for result in context.data["results"]), ( - "Publishing not successful so version is not increased.") - - from ayon_core.lib import version_up - path = context.data["currentFile"] - nuke.scriptSaveAs(version_up(path)) - self.log.info('Incrementing script version') diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/remove_ouput_node.py b/server_addon/nuke/client/ayon_nuke/plugins/publish/remove_ouput_node.py deleted file mode 100644 index 4c17cb5f56..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/remove_ouput_node.py +++ /dev/null @@ -1,24 +0,0 @@ -import nuke -import pyblish.api - - -class RemoveOutputNode(pyblish.api.ContextPlugin): - """Removing output node for each output write node - - """ - label = 'Output Node Remove' - order = pyblish.api.IntegratorOrder + 0.4 - families = ["workfile"] - hosts = ["nuke"] - - settings_category = "nuke" - - def process(self, context): - try: - output_node = context.data["outputNode"] - name = output_node["name"].value() - self.log.info("Removing output node: '{}'".format(name)) - - nuke.delete(output_node) - except Exception: - return diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/validate_asset_context.py b/server_addon/nuke/client/ayon_nuke/plugins/publish/validate_asset_context.py deleted file mode 100644 index 903648fd1b..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/validate_asset_context.py +++ /dev/null @@ -1,114 +0,0 @@ -# -*- coding: utf-8 -*- -"""Validate if instance folder is the same as context folder.""" -from __future__ import absolute_import - -import pyblish.api - -from ayon_core.pipeline.publish import ( - RepairAction, - ValidateContentsOrder, - PublishXmlValidationError, - OptionalPyblishPluginMixin -) -from ayon_nuke.api import SelectInstanceNodeAction - - -class ValidateCorrectAssetContext( - pyblish.api.InstancePlugin, - OptionalPyblishPluginMixin -): - """Validator to check if instance folder context match context folder. - - When working in per-shot style you always publish data in context of - current folder (shot). This validator checks if this is so. It is optional - so it can be disabled when needed. - - Checking `folderPath` and `task` keys. - """ - order = ValidateContentsOrder - label = "Validate Folder context" - hosts = ["nuke"] - actions = [ - RepairAction, - SelectInstanceNodeAction - ] - optional = True - - settings_category = "nuke" - - @classmethod - def apply_settings(cls, project_settings): - """Apply deprecated settings from project settings. - """ - nuke_publish = project_settings["nuke"]["publish"] - if "ValidateCorrectAssetName" in nuke_publish: - settings = nuke_publish["ValidateCorrectAssetName"] - else: - settings = nuke_publish["ValidateCorrectAssetContext"] - - cls.enabled = settings["enabled"] - cls.optional = settings["optional"] - cls.active = settings["active"] - - def process(self, instance): - if not self.is_active(instance.data): - return - - invalid_keys = self.get_invalid(instance) - - if not invalid_keys: - return - - message_values = { - "node_name": instance.data["transientData"]["node"].name(), - "correct_values": ", ".join([ - "{} > {}".format(_key, instance.context.data[_key]) - for _key in invalid_keys - ]), - "wrong_values": ", ".join([ - "{} > {}".format(_key, instance.data.get(_key)) - for _key in invalid_keys - ]) - } - - msg = ( - "Instance `{node_name}` has wrong context keys:\n" - "Correct: `{correct_values}` | Wrong: `{wrong_values}`").format( - **message_values) - - self.log.debug(msg) - - raise PublishXmlValidationError( - self, msg, formatting_data=message_values - ) - - @classmethod - def get_invalid(cls, instance): - """Get invalid keys from instance data and context data.""" - - invalid_keys = [] - testing_keys = ["folderPath", "task"] - for _key in testing_keys: - if _key not in instance.data: - invalid_keys.append(_key) - continue - if instance.data[_key] != instance.context.data[_key]: - invalid_keys.append(_key) - - return invalid_keys - - @classmethod - def repair(cls, instance): - """Repair instance data with context data.""" - invalid_keys = cls.get_invalid(instance) - - create_context = instance.context.data["create_context"] - - instance_id = instance.data.get("instance_id") - created_instance = create_context.get_instance_by_id( - instance_id - ) - for _key in invalid_keys: - created_instance[_key] = instance.context.data[_key] - - create_context.save_changes() diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/validate_backdrop.py b/server_addon/nuke/client/ayon_nuke/plugins/publish/validate_backdrop.py deleted file mode 100644 index f7b94e0c82..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/validate_backdrop.py +++ /dev/null @@ -1,101 +0,0 @@ -import nuke -import pyblish -from ayon_nuke import api as napi - -from ayon_core.pipeline.publish import ( - ValidateContentsOrder, - PublishXmlValidationError, - OptionalPyblishPluginMixin -) - -class SelectCenterInNodeGraph(pyblish.api.Action): - """ - Centering failed instance node in node grap - """ - - label = "Center node in node graph" - icon = "wrench" - on = "failed" - - def process(self, context, plugin): - - # Get the errored instances - failed = [] - for result in context.data["results"]: - if (result["error"] is not None and result["instance"] is not None - and result["instance"] not in failed): - failed.append(result["instance"]) - - # Apply pyblish.logic to get the instances for the plug-in - instances = pyblish.api.instances_by_plugin(failed, plugin) - - all_xC = [] - all_yC = [] - - # maintain selection - with napi.maintained_selection(): - # collect all failed nodes xpos and ypos - for instance in instances: - bdn = instance.data["transientData"]["node"] - xC = bdn.xpos() + bdn.screenWidth() / 2 - yC = bdn.ypos() + bdn.screenHeight() / 2 - - all_xC.append(xC) - all_yC.append(yC) - - self.log.debug("all_xC: `{}`".format(all_xC)) - self.log.debug("all_yC: `{}`".format(all_yC)) - - # zoom to nodes in node graph - nuke.zoom(2, [min(all_xC), min(all_yC)]) - - -class ValidateBackdrop( - pyblish.api.InstancePlugin, - OptionalPyblishPluginMixin -): - """ Validate amount of nodes on backdrop node in case user - forgotten to add nodes above the publishing backdrop node. - """ - - order = ValidateContentsOrder - optional = True - families = ["nukenodes"] - label = "Validate Backdrop" - hosts = ["nuke"] - actions = [SelectCenterInNodeGraph] - - settings_category = "nuke" - - def process(self, instance): - if not self.is_active(instance.data): - return - - child_nodes = instance.data["transientData"]["childNodes"] - connections_out = instance.data["transientData"]["nodeConnectionsOut"] - - msg_multiple_outputs = ( - "Only one outcoming connection from " - "\"{}\" is allowed").format(instance.data["name"]) - - if len(connections_out.keys()) > 1: - raise PublishXmlValidationError( - self, - msg_multiple_outputs, - "multiple_outputs" - ) - - msg_no_nodes = "No content on backdrop node: \"{}\"".format( - instance.data["name"]) - - self.log.debug( - "Amount of nodes on instance: {}".format( - len(child_nodes)) - ) - - if child_nodes == []: - raise PublishXmlValidationError( - self, - msg_no_nodes, - "no_nodes" - ) diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/validate_exposed_knobs.py b/server_addon/nuke/client/ayon_nuke/plugins/publish/validate_exposed_knobs.py deleted file mode 100644 index d1b7c146fb..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/validate_exposed_knobs.py +++ /dev/null @@ -1,82 +0,0 @@ -import pyblish.api - -from ayon_core.pipeline.publish import get_errored_instances_from_context -from ayon_nuke.api.lib import link_knobs -from ayon_core.pipeline.publish import ( - OptionalPyblishPluginMixin, - PublishValidationError -) - - -class RepairExposedKnobs(pyblish.api.Action): - label = "Repair" - on = "failed" - icon = "wrench" - - def process(self, context, plugin): - instances = get_errored_instances_from_context(context) - - for instance in instances: - child_nodes = ( - instance.data.get("transientData", {}).get("childNodes") - or instance - ) - - write_group_node = instance.data["transientData"]["node"] - # get write node from inside of group - write_node = None - for x in child_nodes: - if x.Class() == "Write": - write_node = x - - product_type = instance.data["productType"] - plugin_name = plugin.product_types_mapping[product_type] - nuke_settings = instance.context.data["project_settings"]["nuke"] - create_settings = nuke_settings["create"][plugin_name] - exposed_knobs = create_settings["exposed_knobs"] - link_knobs(exposed_knobs, write_node, write_group_node) - - -class ValidateExposedKnobs( - OptionalPyblishPluginMixin, - pyblish.api.InstancePlugin -): - """ Validate write node exposed knobs. - - Compare exposed linked knobs to settings. - """ - - order = pyblish.api.ValidatorOrder - optional = True - families = ["render", "prerender", "image"] - label = "Validate Exposed Knobs" - actions = [RepairExposedKnobs] - hosts = ["nuke"] - - settings_category = "nuke" - - product_types_mapping = { - "render": "CreateWriteRender", - "prerender": "CreateWritePrerender", - "image": "CreateWriteImage" - } - - def process(self, instance): - if not self.is_active(instance.data): - return - - product_type = instance.data["productType"] - plugin = self.product_types_mapping[product_type] - group_node = instance.data["transientData"]["node"] - nuke_settings = instance.context.data["project_settings"]["nuke"] - create_settings = nuke_settings["create"][plugin] - exposed_knobs = create_settings.get("exposed_knobs", []) - unexposed_knobs = [] - for knob in exposed_knobs: - if knob not in group_node.knobs(): - unexposed_knobs.append(knob) - - if unexposed_knobs: - raise PublishValidationError( - "Missing exposed knobs: {}".format(unexposed_knobs) - ) diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/validate_gizmo.py b/server_addon/nuke/client/ayon_nuke/plugins/publish/validate_gizmo.py deleted file mode 100644 index 55249ae931..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/validate_gizmo.py +++ /dev/null @@ -1,72 +0,0 @@ -import pyblish -from ayon_core.pipeline import PublishXmlValidationError -from ayon_nuke import api as napi -import nuke - - -class OpenFailedGroupNode(pyblish.api.Action): - """ - Centering failed instance node in node grap - """ - - label = "Open Group" - icon = "wrench" - on = "failed" - - def process(self, context, plugin): - - # Get the errored instances - failed = [] - for result in context.data["results"]: - if (result["error"] is not None and result["instance"] is not None - and result["instance"] not in failed): - failed.append(result["instance"]) - - # Apply pyblish.logic to get the instances for the plug-in - instances = pyblish.api.instances_by_plugin(failed, plugin) - - # maintain selection - with napi.maintained_selection(): - # collect all failed nodes xpos and ypos - for instance in instances: - grpn = instance.data["transientData"]["node"] - nuke.showDag(grpn) - - -class ValidateGizmo(pyblish.api.InstancePlugin): - """Validate amount of output nodes in gizmo (group) node""" - - order = pyblish.api.ValidatorOrder - optional = True - families = ["gizmo"] - label = "Validate Gizmo (group)" - hosts = ["nuke"] - actions = [OpenFailedGroupNode] - - settings_category = "nuke" - - def process(self, instance): - grpn = instance.data["transientData"]["node"] - - with grpn: - connections_out = nuke.allNodes('Output') - if len(connections_out) > 1: - msg_multiple_outputs = ( - "Only one outcoming connection from " - "\"{}\" is allowed").format(instance.data["name"]) - - raise PublishXmlValidationError( - self, msg_multiple_outputs, "multiple_outputs", - {"node_name": grpn["name"].value()} - ) - - connections_in = nuke.allNodes('Input') - if len(connections_in) == 0: - msg_missing_inputs = ( - "At least one Input node has to be inside Group: " - "\"{}\"").format(instance.data["name"]) - - raise PublishXmlValidationError( - self, msg_missing_inputs, "no_inputs", - {"node_name": grpn["name"].value()} - ) diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/validate_knobs.py b/server_addon/nuke/client/ayon_nuke/plugins/publish/validate_knobs.py deleted file mode 100644 index ea03bd94b2..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/validate_knobs.py +++ /dev/null @@ -1,133 +0,0 @@ -import json - -import nuke -import six -import pyblish.api - -from ayon_core.pipeline.publish import ( - RepairContextAction, - PublishXmlValidationError, -) - - -class ValidateKnobs(pyblish.api.ContextPlugin): - """Ensure knobs are consistent. - - Knobs to validate and their values comes from the - - Controlled by plugin settings that require json in following structure: - "ValidateKnobs": { - "enabled": true, - "knobs": { - "family": { - "knob_name": knob_value - } - } - } - """ - - order = pyblish.api.ValidatorOrder - label = "Validate Knobs" - hosts = ["nuke"] - actions = [RepairContextAction] - optional = True - - settings_category = "nuke" - - knobs = "{}" - - def process(self, context): - invalid = self.get_invalid(context, compute=True) - if invalid: - invalid_items = [ - ( - "Node __{node_name}__ with knob _{label}_ " - "expecting _{expected}_, " - "but is set to _{current}_" - ).format(**i) - for i in invalid - ] - raise PublishXmlValidationError( - self, - "Found knobs with invalid values:\n{}".format(invalid), - formatting_data={ - "invalid_items": "\n".join(invalid_items)} - ) - - @classmethod - def get_invalid(cls, context, compute=False): - invalid = context.data.get("invalid_knobs", []) - if compute: - invalid = cls.get_invalid_knobs(context) - - return invalid - - @classmethod - def get_invalid_knobs(cls, context): - invalid_knobs = [] - - for instance in context: - # Load fresh knobs data for each instance - settings_knobs = json.loads(cls.knobs) - - # Filter families. - families = [instance.data["productType"]] - families += instance.data.get("families", []) - - # Get all knobs to validate. - knobs = {} - for family in families: - # check if dot in family - if "." in family: - family = family.split(".")[0] - - # avoid families not in settings - if family not in settings_knobs: - continue - - # get presets of knobs - for preset in settings_knobs[family]: - knobs[preset] = settings_knobs[family][preset] - - # Get invalid knobs. - nodes = [] - - for node in nuke.allNodes(): - nodes.append(node) - if node.Class() == "Group": - node.begin() - nodes.extend(iter(nuke.allNodes())) - node.end() - - for node in nodes: - for knob in node.knobs(): - if knob not in knobs.keys(): - continue - - expected = knobs[knob] - if node[knob].value() != expected: - invalid_knobs.append( - { - "node_name": node.name(), - "knob": node[knob], - "name": node[knob].name(), - "label": node[knob].label(), - "expected": expected, - "current": node[knob].value() - } - ) - - context.data["invalid_knobs"] = invalid_knobs - return invalid_knobs - - @classmethod - def repair(cls, instance): - invalid = cls.get_invalid(instance) - for data in invalid: - # TODO: will need to improve type definitions - # with the new settings for knob types - if isinstance(data["expected"], six.text_type): - data["knob"].setValue(str(data["expected"])) - continue - - data["knob"].setValue(data["expected"]) diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/validate_output_resolution.py b/server_addon/nuke/client/ayon_nuke/plugins/publish/validate_output_resolution.py deleted file mode 100644 index 440cb8b758..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/validate_output_resolution.py +++ /dev/null @@ -1,114 +0,0 @@ -import pyblish.api - -from ayon_nuke import api as napi -from ayon_core.pipeline.publish import RepairAction -from ayon_core.pipeline import ( - PublishXmlValidationError, - OptionalPyblishPluginMixin -) - -import nuke - - -class ValidateOutputResolution( - OptionalPyblishPluginMixin, - pyblish.api.InstancePlugin -): - """Validates Output Resolution. - - It is making sure the resolution of write's input is the same as - Format definition of script in Root node. - """ - - order = pyblish.api.ValidatorOrder - optional = True - families = ["render"] - label = "Validate Write resolution" - hosts = ["nuke"] - actions = [RepairAction] - - settings_category = "nuke" - - missing_msg = "Missing Reformat node in render group node" - resolution_msg = "Reformat is set to wrong format" - - def process(self, instance): - if not self.is_active(instance.data): - return - - invalid = self.get_invalid(instance) - if invalid: - raise PublishXmlValidationError(self, invalid) - - @classmethod - def get_reformat(cls, instance): - child_nodes = ( - instance.data.get("transientData", {}).get("childNodes") - or instance - ) - - reformat = None - for inode in child_nodes: - if inode.Class() != "Reformat": - continue - reformat = inode - - return reformat - - @classmethod - def get_invalid(cls, instance): - def _check_resolution(instance, reformat): - root_width = instance.data["resolutionWidth"] - root_height = instance.data["resolutionHeight"] - - write_width = reformat.format().width() - write_height = reformat.format().height() - - if (root_width != write_width) or (root_height != write_height): - return None - else: - return True - - # check if reformat is in render node - reformat = cls.get_reformat(instance) - if not reformat: - return cls.missing_msg - - # check if reformat is set to correct root format - correct_format = _check_resolution(instance, reformat) - if not correct_format: - return cls.resolution_msg - - @classmethod - def repair(cls, instance): - child_nodes = ( - instance.data.get("transientData", {}).get("childNodes") - or instance - ) - - invalid = cls.get_invalid(instance) - grp_node = instance.data["transientData"]["node"] - - if cls.missing_msg == invalid: - # make sure we are inside of the group node - with grp_node: - # find input node and select it - _input = None - for inode in child_nodes: - if inode.Class() != "Input": - continue - _input = inode - - # add reformat node under it - with napi.maintained_selection(): - _input['selected'].setValue(True) - _rfn = nuke.createNode("Reformat", "name Reformat01") - _rfn["resize"].setValue(0) - _rfn["black_outside"].setValue(1) - - cls.log.info("Adding reformat node") - - if cls.resolution_msg == invalid: - reformat = cls.get_reformat(instance) - reformat["format"].setValue(nuke.root()["format"].value()) - cls.log.info("Fixing reformat to root.format") diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/validate_proxy_mode.py b/server_addon/nuke/client/ayon_nuke/plugins/publish/validate_proxy_mode.py deleted file mode 100644 index 1eb858b17e..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/validate_proxy_mode.py +++ /dev/null @@ -1,38 +0,0 @@ -import pyblish -import nuke -from ayon_core.pipeline import PublishXmlValidationError - - -class FixProxyMode(pyblish.api.Action): - """ - Togger off proxy switch OFF - """ - - label = "Repair" - icon = "wrench" - on = "failed" - - def process(self, context, plugin): - rootNode = nuke.root() - rootNode["proxy"].setValue(False) - - -class ValidateProxyMode(pyblish.api.ContextPlugin): - """Validate active proxy mode""" - - order = pyblish.api.ValidatorOrder - label = "Validate Proxy Mode" - hosts = ["nuke"] - actions = [FixProxyMode] - - settings_category = "nuke" - - def process(self, context): - - rootNode = nuke.root() - isProxy = rootNode["proxy"].value() - - if isProxy: - raise PublishXmlValidationError( - self, "Proxy mode should be toggled OFF" - ) diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/validate_rendered_frames.py b/server_addon/nuke/client/ayon_nuke/plugins/publish/validate_rendered_frames.py deleted file mode 100644 index 20b7f6a6ac..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/validate_rendered_frames.py +++ /dev/null @@ -1,139 +0,0 @@ -import pyblish.api -import clique - -from ayon_core.pipeline import PublishXmlValidationError -from ayon_core.pipeline.publish import get_errored_instances_from_context - - -class RepairActionBase(pyblish.api.Action): - on = "failed" - icon = "wrench" - - @staticmethod - def get_instance(context, plugin): - # Get the errored instances - return get_errored_instances_from_context(context, plugin=plugin) - - def repair_knob(self, context, instances, state): - create_context = context.data["create_context"] - for instance in instances: - # Reset the render knob - instance_id = instance.data.get("instance_id") - created_instance = create_context.get_instance_by_id( - instance_id - ) - created_instance.creator_attributes["render_target"] = state - self.log.info("Rendering toggled to `{}`".format(state)) - - create_context.save_changes() - - -class RepairCollectionActionToLocal(RepairActionBase): - label = "Repair - rerender with \"Local\"" - - def process(self, context, plugin): - instances = self.get_instance(context, plugin) - self.repair_knob(context, instances, "local") - - -class RepairCollectionActionToFarm(RepairActionBase): - label = "Repair - rerender with \"On farm\"" - - def process(self, context, plugin): - instances = self.get_instance(context, plugin) - self.repair_knob(context, instances, "farm") - - -class ValidateRenderedFrames(pyblish.api.InstancePlugin): - """ Validates file output. """ - - order = pyblish.api.ValidatorOrder + 0.1 - families = ["render", "prerender", "still"] - - label = "Validate rendered frame" - hosts = ["nuke", "nukestudio"] - actions = [RepairCollectionActionToLocal, RepairCollectionActionToFarm] - - settings_category = "nuke" - - def process(self, instance): - node = instance.data["transientData"]["node"] - - f_data = { - "node_name": node.name() - } - - for repre in instance.data["representations"]: - - if not repre.get("files"): - msg = ("no frames were collected, " - "you need to render them.\n" - "Check properties of write node (group) and" - "select 'Local' option in 'Publish' dropdown.") - self.log.error(msg) - raise PublishXmlValidationError( - self, msg, formatting_data=f_data) - - if isinstance(repre["files"], str): - return - - collections, remainder = clique.assemble(repre["files"]) - self.log.debug("collections: {}".format(str(collections))) - self.log.debug("remainder: {}".format(str(remainder))) - - collection = collections[0] - - f_start_h = instance.data["frameStartHandle"] - f_end_h = instance.data["frameEndHandle"] - - frame_length = int(f_end_h - f_start_h + 1) - - if frame_length != 1: - if len(collections) != 1: - msg = "There are multiple collections in the folder" - self.log.error(msg) - raise PublishXmlValidationError( - self, msg, formatting_data=f_data) - - if not collection.is_contiguous(): - msg = "Some frames appear to be missing" - self.log.error(msg) - raise PublishXmlValidationError( - self, msg, formatting_data=f_data) - - collected_frames_len = len(collection.indexes) - coll_start = min(collection.indexes) - coll_end = max(collection.indexes) - - self.log.debug("frame_length: {}".format(frame_length)) - self.log.debug("collected_frames_len: {}".format( - collected_frames_len)) - self.log.debug("f_start_h-f_end_h: {}-{}".format( - f_start_h, f_end_h)) - self.log.debug( - "coll_start-coll_end: {}-{}".format(coll_start, coll_end)) - - self.log.debug( - "len(collection.indexes): {}".format(collected_frames_len) - ) - - if ("slate" in instance.data["families"]) \ - and (frame_length != collected_frames_len): - collected_frames_len -= 1 - f_start_h += 1 - - if ( - collected_frames_len != frame_length - and coll_start <= f_start_h - and coll_end >= f_end_h - ): - raise PublishXmlValidationError( - self, ( - "{} missing frames. Use repair to " - "render all frames" - ).format(__name__), formatting_data=f_data - ) - - instance.data["collection"] = collection - - return diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/validate_script_attributes.py b/server_addon/nuke/client/ayon_nuke/plugins/publish/validate_script_attributes.py deleted file mode 100644 index 617d8d835b..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/validate_script_attributes.py +++ /dev/null @@ -1,103 +0,0 @@ -from copy import deepcopy -import pyblish.api -from ayon_core.pipeline import ( - PublishXmlValidationError, - OptionalPyblishPluginMixin -) -from ayon_core.pipeline.publish import RepairAction -from ayon_nuke.api.lib import ( - WorkfileSettings -) - - -class ValidateScriptAttributes( - OptionalPyblishPluginMixin, - pyblish.api.InstancePlugin -): - """ Validates file output. """ - - order = pyblish.api.ValidatorOrder + 0.1 - families = ["workfile"] - label = "Validate script attributes" - hosts = ["nuke"] - optional = True - actions = [RepairAction] - - settings_category = "nuke" - - def process(self, instance): - if not self.is_active(instance.data): - return - - script_data = deepcopy(instance.context.data["scriptData"]) - - src_folder_attributes = instance.data["folderEntity"]["attrib"] - - # These attributes will be checked - attributes = [ - "fps", - "frameStart", - "frameEnd", - "resolutionWidth", - "resolutionHeight", - "handleStart", - "handleEnd" - ] - - # get only defined attributes from folder data - folder_attributes = { - attr: src_folder_attributes[attr] - for attr in attributes - if attr in src_folder_attributes - } - # fix frame values to include handles - folder_attributes["fps"] = float("{0:.4f}".format( - folder_attributes["fps"])) - script_data["fps"] = float("{0:.4f}".format( - script_data["fps"])) - - # Compare folder's values Nukescript X Database - not_matching = [] - for attr in attributes: - self.log.debug( - "Folder vs Script attribute \"{}\": {}, {}".format( - attr, - folder_attributes[attr], - script_data[attr] - ) - ) - if folder_attributes[attr] != script_data[attr]: - not_matching.append({ - "name": attr, - "expected": folder_attributes[attr], - "actual": script_data[attr] - }) - - # Raise error if not matching - if not_matching: - msg = "Following attributes are not set correctly: \n{}" - attrs_wrong_str = "\n".join([ - ( - "`{0}` is set to `{1}`, " - "but should be set to `{2}`" - ).format(at["name"], at["actual"], at["expected"]) - for at in not_matching - ]) - attrs_wrong_html = "
".join([ - ( - "-- __{0}__ is set to __{1}__, " - "but should be set to __{2}__" - ).format(at["name"], at["actual"], at["expected"]) - for at in not_matching - ]) - raise PublishXmlValidationError( - self, msg.format(attrs_wrong_str), - formatting_data={ - "failed_attributes": attrs_wrong_html - } - ) - - @classmethod - def repair(cls, instance): - cls.log.debug("__ repairing instance: {}".format(instance)) - WorkfileSettings().set_context_settings() diff --git a/server_addon/nuke/client/ayon_nuke/plugins/publish/validate_write_nodes.py b/server_addon/nuke/client/ayon_nuke/plugins/publish/validate_write_nodes.py deleted file mode 100644 index d642a4314c..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/publish/validate_write_nodes.py +++ /dev/null @@ -1,156 +0,0 @@ -from collections import defaultdict - -import pyblish.api -from ayon_core.pipeline.publish import get_errored_instances_from_context -from ayon_nuke.api.lib import ( - get_write_node_template_attr, - set_node_knobs_from_settings, - color_gui_to_int -) - -from ayon_core.pipeline.publish import ( - PublishXmlValidationError, - OptionalPyblishPluginMixin -) - - -class RepairNukeWriteNodeAction(pyblish.api.Action): - label = "Repair" - on = "failed" - icon = "wrench" - - def process(self, context, plugin): - instances = get_errored_instances_from_context(context) - - for instance in instances: - child_nodes = ( - instance.data.get("transientData", {}).get("childNodes") - or instance - ) - - write_group_node = instance.data["transientData"]["node"] - # get write node from inside of group - write_node = None - for x in child_nodes: - if x.Class() == "Write": - write_node = x - - correct_data = get_write_node_template_attr(write_group_node) - - set_node_knobs_from_settings(write_node, correct_data["knobs"]) - - self.log.debug("Node attributes were fixed") - - -class ValidateNukeWriteNode( - OptionalPyblishPluginMixin, - pyblish.api.InstancePlugin -): - """ Validate Write node's knobs. - - Compare knobs on write node inside the render group - with settings. At the moment supporting only `file` knob. - """ - - order = pyblish.api.ValidatorOrder - optional = True - families = ["render"] - label = "Validate write node" - actions = [RepairNukeWriteNodeAction] - hosts = ["nuke"] - - settings_category = "nuke" - - def process(self, instance): - if not self.is_active(instance.data): - return - - child_nodes = ( - instance.data.get("transientData", {}).get("childNodes") - or instance - ) - - write_group_node = instance.data["transientData"]["node"] - - # get write node from inside of group - write_node = None - for x in child_nodes: - if x.Class() == "Write": - write_node = x - - if write_node is None: - return - - correct_data = get_write_node_template_attr(write_group_node) - - check = [] - - # Collect key values of same type in a list. - values_by_name = defaultdict(list) - for knob_data in correct_data["knobs"]: - knob_type = knob_data["type"] - knob_value = knob_data[knob_type] - - values_by_name[knob_data["name"]].append(knob_value) - - for knob_data in correct_data["knobs"]: - knob_type = knob_data["type"] - - if ( - knob_type == "__legacy__" - ): - raise PublishXmlValidationError( - self, ( - "Please update data in settings 'project_settings" - "/nuke/imageio/nodes/required_nodes'" - ), - key="legacy" - ) - - key = knob_data["name"] - values = values_by_name[key] - node_value = write_node[key].value() - - # fix type differences - fixed_values = [] - for value in values: - if type(node_value) in (int, float): - try: - if isinstance(value, list): - value = color_gui_to_int(value) - else: - value = float(value) - node_value = float(node_value) - except ValueError: - value = str(value) - else: - value = str(value) - node_value = str(node_value) - - fixed_values.append(value) - - if ( - node_value not in fixed_values - and key != "file" - and key != "tile_color" - ): - check.append([key, fixed_values, write_node[key].value()]) - - if check: - self._make_error(check) - - def _make_error(self, check): - # sourcery skip: merge-assign-and-aug-assign, move-assign-in-block - dbg_msg = "Write node's knobs values are not correct!\n" - msg_add = "Knob '{0}' > Expected: `{1}` > Current: `{2}`" - - details = [ - msg_add.format(item[0], item[1], item[2]) - for item in check - ] - xml_msg = "
".join(details) - dbg_msg += "\n\t".join(details) - - raise PublishXmlValidationError( - self, dbg_msg, formatting_data={"xml_msg": xml_msg} - ) diff --git a/server_addon/nuke/client/ayon_nuke/plugins/workfile_build/create_placeholder.py b/server_addon/nuke/client/ayon_nuke/plugins/workfile_build/create_placeholder.py deleted file mode 100644 index 4d43d59bad..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/workfile_build/create_placeholder.py +++ /dev/null @@ -1,428 +0,0 @@ -import nuke - -from ayon_core.pipeline.workfile.workfile_template_builder import ( - CreatePlaceholderItem, - PlaceholderCreateMixin, -) -from ayon_nuke.api.lib import ( - find_free_space_to_paste_nodes, - get_extreme_positions, - get_group_io_nodes, - imprint, - refresh_node, - refresh_nodes, - reset_selection, - get_names_from_nodes, - get_nodes_by_names, - select_nodes, - duplicate_node, - node_tempfile, -) -from ayon_nuke.api.workfile_template_builder import ( - NukePlaceholderPlugin -) - - -class NukePlaceholderCreatePlugin( - NukePlaceholderPlugin, PlaceholderCreateMixin -): - identifier = "nuke.create" - label = "Nuke create" - - def _parse_placeholder_node_data(self, node): - placeholder_data = super( - NukePlaceholderCreatePlugin, self - )._parse_placeholder_node_data(node) - - node_knobs = node.knobs() - nb_children = 0 - if "nb_children" in node_knobs: - nb_children = int(node_knobs["nb_children"].getValue()) - placeholder_data["nb_children"] = nb_children - - siblings = [] - if "siblings" in node_knobs: - siblings = node_knobs["siblings"].values() - placeholder_data["siblings"] = siblings - - node_full_name = node.fullName() - placeholder_data["group_name"] = node_full_name.rpartition(".")[0] - placeholder_data["last_loaded"] = [] - placeholder_data["delete"] = False - return placeholder_data - - def _before_instance_create(self, placeholder): - placeholder.data["nodes_init"] = nuke.allNodes() - - def collect_placeholders(self): - output = [] - scene_placeholders = self._collect_scene_placeholders() - for node_name, node in scene_placeholders.items(): - plugin_identifier_knob = node.knob("plugin_identifier") - if ( - plugin_identifier_knob is None - or plugin_identifier_knob.getValue() != self.identifier - ): - continue - - placeholder_data = self._parse_placeholder_node_data(node) - - output.append( - CreatePlaceholderItem(node_name, placeholder_data, self) - ) - - return output - - def populate_placeholder(self, placeholder): - self.populate_create_placeholder(placeholder) - - def repopulate_placeholder(self, placeholder): - self.populate_create_placeholder(placeholder) - - def get_placeholder_options(self, options=None): - return self.get_create_plugin_options(options) - - def post_placeholder_process(self, placeholder, failed): - """Cleanup placeholder after load of its corresponding representations. - - Args: - placeholder (PlaceholderItem): Item which was just used to load - representation. - failed (bool): Loading of representation failed. - """ - # deselect all selected nodes - placeholder_node = nuke.toNode(placeholder.scene_identifier) - - # getting the latest nodes added - nodes_init = placeholder.data["nodes_init"] - nodes_created = list(set(nuke.allNodes()) - set(nodes_init)) - self.log.debug("Created nodes: {}".format(nodes_created)) - if not nodes_created: - return - - placeholder.data["delete"] = True - - nodes_created = self._move_to_placeholder_group( - placeholder, nodes_created - ) - placeholder.data["last_created"] = nodes_created - refresh_nodes(nodes_created) - - # positioning of the created nodes - min_x, min_y, _, _ = get_extreme_positions(nodes_created) - for node in nodes_created: - xpos = (node.xpos() - min_x) + placeholder_node.xpos() - ypos = (node.ypos() - min_y) + placeholder_node.ypos() - node.setXYpos(xpos, ypos) - refresh_nodes(nodes_created) - - # fix the problem of z_order for backdrops - self._fix_z_order(placeholder) - - if placeholder.data.get("keep_placeholder"): - self._imprint_siblings(placeholder) - - if placeholder.data["nb_children"] == 0: - # save initial nodes positions and dimensions, update them - # and set inputs and outputs of created nodes - - if placeholder.data.get("keep_placeholder"): - self._imprint_inits() - self._update_nodes(placeholder, nuke.allNodes(), nodes_created) - - self._set_created_connections(placeholder) - - elif placeholder.data["siblings"]: - # create copies of placeholder siblings for the new created nodes, - # set their inputs and outputs and update all nodes positions and - # dimensions and siblings names - - siblings = get_nodes_by_names(placeholder.data["siblings"]) - refresh_nodes(siblings) - copies = self._create_sib_copies(placeholder) - new_nodes = list(copies.values()) # copies nodes - self._update_nodes(new_nodes, nodes_created) - placeholder_node.removeKnob(placeholder_node.knob("siblings")) - new_nodes_name = get_names_from_nodes(new_nodes) - imprint(placeholder_node, {"siblings": new_nodes_name}) - self._set_copies_connections(placeholder, copies) - - self._update_nodes( - nuke.allNodes(), - new_nodes + nodes_created, - 20 - ) - - new_siblings = get_names_from_nodes(new_nodes) - placeholder.data["siblings"] = new_siblings - - else: - # if the placeholder doesn't have siblings, the created - # nodes will be placed in a free space - - xpointer, ypointer = find_free_space_to_paste_nodes( - nodes_created, direction="bottom", offset=200 - ) - node = nuke.createNode("NoOp") - reset_selection() - nuke.delete(node) - for node in nodes_created: - xpos = (node.xpos() - min_x) + xpointer - ypos = (node.ypos() - min_y) + ypointer - node.setXYpos(xpos, ypos) - - placeholder.data["nb_children"] += 1 - reset_selection() - - # go back to root group - nuke.root().begin() - - def _move_to_placeholder_group(self, placeholder, nodes_created): - """ - opening the placeholder's group and copying created nodes in it. - - Returns : - nodes_created (list): the new list of pasted nodes - """ - groups_name = placeholder.data["group_name"] - reset_selection() - select_nodes(nodes_created) - if groups_name: - with node_tempfile() as filepath: - nuke.nodeCopy(filepath) - for node in nuke.selectedNodes(): - nuke.delete(node) - group = nuke.toNode(groups_name) - group.begin() - nuke.nodePaste(filepath) - nodes_created = nuke.selectedNodes() - return nodes_created - - def _fix_z_order(self, placeholder): - """Fix the problem of z_order when a backdrop is create.""" - - nodes_created = placeholder.data["last_created"] - created_backdrops = [] - bd_orders = set() - for node in nodes_created: - if isinstance(node, nuke.BackdropNode): - created_backdrops.append(node) - bd_orders.add(node.knob("z_order").getValue()) - - if not bd_orders: - return - - sib_orders = set() - for node_name in placeholder.data["siblings"]: - node = nuke.toNode(node_name) - if isinstance(node, nuke.BackdropNode): - sib_orders.add(node.knob("z_order").getValue()) - - if not sib_orders: - return - - min_order = min(bd_orders) - max_order = max(sib_orders) - for backdrop_node in created_backdrops: - z_order = backdrop_node.knob("z_order").getValue() - backdrop_node.knob("z_order").setValue( - z_order + max_order - min_order + 1) - - def _imprint_siblings(self, placeholder): - """ - - add siblings names to placeholder attributes (nodes created with it) - - add Id to the attributes of all the other nodes - """ - - created_nodes = placeholder.data["last_created"] - created_nodes_set = set(created_nodes) - - for node in created_nodes: - node_knobs = node.knobs() - - if ( - "is_placeholder" not in node_knobs - or ( - "is_placeholder" in node_knobs - and node.knob("is_placeholder").value() - ) - ): - siblings = list(created_nodes_set - {node}) - siblings_name = get_names_from_nodes(siblings) - siblings = {"siblings": siblings_name} - imprint(node, siblings) - - def _imprint_inits(self): - """Add initial positions and dimensions to the attributes""" - - for node in nuke.allNodes(): - refresh_node(node) - imprint(node, {"x_init": node.xpos(), "y_init": node.ypos()}) - node.knob("x_init").setVisible(False) - node.knob("y_init").setVisible(False) - width = node.screenWidth() - height = node.screenHeight() - if "bdwidth" in node.knobs(): - imprint(node, {"w_init": width, "h_init": height}) - node.knob("w_init").setVisible(False) - node.knob("h_init").setVisible(False) - refresh_node(node) - - def _update_nodes( - self, placeholder, nodes, considered_nodes, offset_y=None - ): - """Adjust backdrop nodes dimensions and positions. - - Considering some nodes sizes. - - Args: - nodes (list): list of nodes to update - considered_nodes (list): list of nodes to consider while updating - positions and dimensions - offset (int): distance between copies - """ - - placeholder_node = nuke.toNode(placeholder.scene_identifier) - - min_x, min_y, max_x, max_y = get_extreme_positions(considered_nodes) - - diff_x = diff_y = 0 - contained_nodes = [] # for backdrops - - if offset_y is None: - width_ph = placeholder_node.screenWidth() - height_ph = placeholder_node.screenHeight() - diff_y = max_y - min_y - height_ph - diff_x = max_x - min_x - width_ph - contained_nodes = [placeholder_node] - min_x = placeholder_node.xpos() - min_y = placeholder_node.ypos() - else: - siblings = get_nodes_by_names(placeholder.data["siblings"]) - minX, _, maxX, _ = get_extreme_positions(siblings) - diff_y = max_y - min_y + 20 - diff_x = abs(max_x - min_x - maxX + minX) - contained_nodes = considered_nodes - - if diff_y <= 0 and diff_x <= 0: - return - - for node in nodes: - refresh_node(node) - - if ( - node == placeholder_node - or node in considered_nodes - ): - continue - - if ( - not isinstance(node, nuke.BackdropNode) - or ( - isinstance(node, nuke.BackdropNode) - and not set(contained_nodes) <= set(node.getNodes()) - ) - ): - if offset_y is None and node.xpos() >= min_x: - node.setXpos(node.xpos() + diff_x) - - if node.ypos() >= min_y: - node.setYpos(node.ypos() + diff_y) - - else: - width = node.screenWidth() - height = node.screenHeight() - node.knob("bdwidth").setValue(width + diff_x) - node.knob("bdheight").setValue(height + diff_y) - - refresh_node(node) - - def _set_created_connections(self, placeholder): - """ - set inputs and outputs of created nodes""" - - placeholder_node = nuke.toNode(placeholder.scene_identifier) - input_node, output_node = get_group_io_nodes( - placeholder.data["last_created"] - ) - for node in placeholder_node.dependent(): - for idx in range(node.inputs()): - if node.input(idx) == placeholder_node and output_node: - node.setInput(idx, output_node) - - for node in placeholder_node.dependencies(): - for idx in range(placeholder_node.inputs()): - if placeholder_node.input(idx) == node and input_node: - input_node.setInput(0, node) - - def _create_sib_copies(self, placeholder): - """ creating copies of the palce_holder siblings (the ones who were - created with it) for the new nodes added - - Returns : - copies (dict) : with copied nodes names and their copies - """ - - copies = {} - siblings = get_nodes_by_names(placeholder.data["siblings"]) - for node in siblings: - new_node = duplicate_node(node) - - x_init = int(new_node.knob("x_init").getValue()) - y_init = int(new_node.knob("y_init").getValue()) - new_node.setXYpos(x_init, y_init) - if isinstance(new_node, nuke.BackdropNode): - w_init = new_node.knob("w_init").getValue() - h_init = new_node.knob("h_init").getValue() - new_node.knob("bdwidth").setValue(w_init) - new_node.knob("bdheight").setValue(h_init) - refresh_node(node) - - if "repre_id" in node.knobs().keys(): - node.removeKnob(node.knob("repre_id")) - copies[node.name()] = new_node - return copies - - def _set_copies_connections(self, placeholder, copies): - """Set inputs and outputs of the copies. - - Args: - copies (dict): Copied nodes by their names. - """ - - last_input, last_output = get_group_io_nodes( - placeholder.data["last_created"] - ) - siblings = get_nodes_by_names(placeholder.data["siblings"]) - siblings_input, siblings_output = get_group_io_nodes(siblings) - copy_input = copies[siblings_input.name()] - copy_output = copies[siblings_output.name()] - - for node_init in siblings: - if node_init == siblings_output: - continue - - node_copy = copies[node_init.name()] - for node in node_init.dependent(): - for idx in range(node.inputs()): - if node.input(idx) != node_init: - continue - - if node in siblings: - copies[node.name()].setInput(idx, node_copy) - else: - last_input.setInput(0, node_copy) - - for node in node_init.dependencies(): - for idx in range(node_init.inputs()): - if node_init.input(idx) != node: - continue - - if node_init == siblings_input: - copy_input.setInput(idx, node) - elif node in siblings: - node_copy.setInput(idx, copies[node.name()]) - else: - node_copy.setInput(idx, last_output) - - siblings_input.setInput(0, copy_output) diff --git a/server_addon/nuke/client/ayon_nuke/plugins/workfile_build/load_placeholder.py b/server_addon/nuke/client/ayon_nuke/plugins/workfile_build/load_placeholder.py deleted file mode 100644 index 68bc10e41b..0000000000 --- a/server_addon/nuke/client/ayon_nuke/plugins/workfile_build/load_placeholder.py +++ /dev/null @@ -1,455 +0,0 @@ -import nuke - -from ayon_core.pipeline.workfile.workfile_template_builder import ( - LoadPlaceholderItem, - PlaceholderLoadMixin, -) -from ayon_nuke.api.lib import ( - find_free_space_to_paste_nodes, - get_extreme_positions, - get_group_io_nodes, - imprint, - refresh_node, - refresh_nodes, - reset_selection, - get_names_from_nodes, - get_nodes_by_names, - select_nodes, - duplicate_node, - node_tempfile, -) -from ayon_nuke.api.workfile_template_builder import ( - NukePlaceholderPlugin -) - - -class NukePlaceholderLoadPlugin(NukePlaceholderPlugin, PlaceholderLoadMixin): - identifier = "nuke.load" - label = "Nuke load" - - def _parse_placeholder_node_data(self, node): - placeholder_data = super( - NukePlaceholderLoadPlugin, self - )._parse_placeholder_node_data(node) - - node_knobs = node.knobs() - nb_children = 0 - if "nb_children" in node_knobs: - nb_children = int(node_knobs["nb_children"].getValue()) - placeholder_data["nb_children"] = nb_children - - siblings = [] - if "siblings" in node_knobs: - siblings = node_knobs["siblings"].values() - placeholder_data["siblings"] = siblings - - node_full_name = node.fullName() - placeholder_data["group_name"] = node_full_name.rpartition(".")[0] - placeholder_data["last_loaded"] = [] - placeholder_data["delete"] = False - return placeholder_data - - def _get_loaded_repre_ids(self): - loaded_representation_ids = self.builder.get_shared_populate_data( - "loaded_representation_ids" - ) - if loaded_representation_ids is None: - loaded_representation_ids = set() - for node in nuke.allNodes(): - if "repre_id" in node.knobs(): - loaded_representation_ids.add( - node.knob("repre_id").getValue() - ) - - self.builder.set_shared_populate_data( - "loaded_representation_ids", loaded_representation_ids - ) - return loaded_representation_ids - - def _before_placeholder_load(self, placeholder): - placeholder.data["nodes_init"] = nuke.allNodes() - - def _before_repre_load(self, placeholder, representation): - placeholder.data["last_repre_id"] = representation["id"] - - def collect_placeholders(self): - output = [] - scene_placeholders = self._collect_scene_placeholders() - for node_name, node in scene_placeholders.items(): - plugin_identifier_knob = node.knob("plugin_identifier") - if ( - plugin_identifier_knob is None - or plugin_identifier_knob.getValue() != self.identifier - ): - continue - - placeholder_data = self._parse_placeholder_node_data(node) - # TODO do data validations and maybe updgrades if are invalid - output.append( - LoadPlaceholderItem(node_name, placeholder_data, self) - ) - - return output - - def populate_placeholder(self, placeholder): - self.populate_load_placeholder(placeholder) - - def repopulate_placeholder(self, placeholder): - repre_ids = self._get_loaded_repre_ids() - self.populate_load_placeholder(placeholder, repre_ids) - - def get_placeholder_options(self, options=None): - return self.get_load_plugin_options(options) - - def post_placeholder_process(self, placeholder, failed): - """Cleanup placeholder after load of its corresponding representations. - - Args: - placeholder (PlaceholderItem): Item which was just used to load - representation. - failed (bool): Loading of representation failed. - """ - # deselect all selected nodes - placeholder_node = nuke.toNode(placeholder.scene_identifier) - - # getting the latest nodes added - # TODO get from shared populate data! - nodes_init = placeholder.data["nodes_init"] - nodes_loaded = list(set(nuke.allNodes()) - set(nodes_init)) - self.log.debug("Loaded nodes: {}".format(nodes_loaded)) - if not nodes_loaded: - return - - placeholder.data["delete"] = True - - nodes_loaded = self._move_to_placeholder_group( - placeholder, nodes_loaded - ) - placeholder.data["last_loaded"] = nodes_loaded - refresh_nodes(nodes_loaded) - - # positioning of the loaded nodes - min_x, min_y, _, _ = get_extreme_positions(nodes_loaded) - for node in nodes_loaded: - xpos = (node.xpos() - min_x) + placeholder_node.xpos() - ypos = (node.ypos() - min_y) + placeholder_node.ypos() - node.setXYpos(xpos, ypos) - refresh_nodes(nodes_loaded) - - # fix the problem of z_order for backdrops - self._fix_z_order(placeholder) - - if placeholder.data.get("keep_placeholder"): - self._imprint_siblings(placeholder) - - if placeholder.data["nb_children"] == 0: - # save initial nodes positions and dimensions, update them - # and set inputs and outputs of loaded nodes - if placeholder.data.get("keep_placeholder"): - self._imprint_inits() - self._update_nodes(placeholder, nuke.allNodes(), nodes_loaded) - - self._set_loaded_connections(placeholder) - - elif placeholder.data["siblings"]: - # create copies of placeholder siblings for the new loaded nodes, - # set their inputs and outputs and update all nodes positions and - # dimensions and siblings names - - siblings = get_nodes_by_names(placeholder.data["siblings"]) - refresh_nodes(siblings) - copies = self._create_sib_copies(placeholder) - new_nodes = list(copies.values()) # copies nodes - self._update_nodes(new_nodes, nodes_loaded) - placeholder_node.removeKnob(placeholder_node.knob("siblings")) - new_nodes_name = get_names_from_nodes(new_nodes) - imprint(placeholder_node, {"siblings": new_nodes_name}) - self._set_copies_connections(placeholder, copies) - - self._update_nodes( - nuke.allNodes(), - new_nodes + nodes_loaded, - 20 - ) - - new_siblings = get_names_from_nodes(new_nodes) - placeholder.data["siblings"] = new_siblings - - else: - # if the placeholder doesn't have siblings, the loaded - # nodes will be placed in a free space - - xpointer, ypointer = find_free_space_to_paste_nodes( - nodes_loaded, direction="bottom", offset=200 - ) - node = nuke.createNode("NoOp") - reset_selection() - nuke.delete(node) - for node in nodes_loaded: - xpos = (node.xpos() - min_x) + xpointer - ypos = (node.ypos() - min_y) + ypointer - node.setXYpos(xpos, ypos) - - placeholder.data["nb_children"] += 1 - reset_selection() - - # go back to root group - nuke.root().begin() - - def _move_to_placeholder_group(self, placeholder, nodes_loaded): - """ - opening the placeholder's group and copying loaded nodes in it. - - Returns : - nodes_loaded (list): the new list of pasted nodes - """ - - groups_name = placeholder.data["group_name"] - reset_selection() - select_nodes(nodes_loaded) - if groups_name: - with node_tempfile() as filepath: - nuke.nodeCopy(filepath) - for node in nuke.selectedNodes(): - nuke.delete(node) - group = nuke.toNode(groups_name) - group.begin() - nuke.nodePaste(filepath) - nodes_loaded = nuke.selectedNodes() - return nodes_loaded - - def _fix_z_order(self, placeholder): - """Fix the problem of z_order when a backdrop is loaded.""" - - nodes_loaded = placeholder.data["last_loaded"] - loaded_backdrops = [] - bd_orders = set() - for node in nodes_loaded: - if isinstance(node, nuke.BackdropNode): - loaded_backdrops.append(node) - bd_orders.add(node.knob("z_order").getValue()) - - if not bd_orders: - return - - sib_orders = set() - for node_name in placeholder.data["siblings"]: - node = nuke.toNode(node_name) - if isinstance(node, nuke.BackdropNode): - sib_orders.add(node.knob("z_order").getValue()) - - if not sib_orders: - return - - min_order = min(bd_orders) - max_order = max(sib_orders) - for backdrop_node in loaded_backdrops: - z_order = backdrop_node.knob("z_order").getValue() - backdrop_node.knob("z_order").setValue( - z_order + max_order - min_order + 1) - - def _imprint_siblings(self, placeholder): - """ - - add siblings names to placeholder attributes (nodes loaded with it) - - add Id to the attributes of all the other nodes - """ - - loaded_nodes = placeholder.data["last_loaded"] - loaded_nodes_set = set(loaded_nodes) - data = {"repre_id": str(placeholder.data["last_repre_id"])} - - for node in loaded_nodes: - node_knobs = node.knobs() - if "builder_type" not in node_knobs: - # save the id of representation for all imported nodes - imprint(node, data) - node.knob("repre_id").setVisible(False) - refresh_node(node) - continue - - if ( - "is_placeholder" not in node_knobs - or ( - "is_placeholder" in node_knobs - and node.knob("is_placeholder").value() - ) - ): - siblings = list(loaded_nodes_set - {node}) - siblings_name = get_names_from_nodes(siblings) - siblings = {"siblings": siblings_name} - imprint(node, siblings) - - def _imprint_inits(self): - """Add initial positions and dimensions to the attributes""" - - for node in nuke.allNodes(): - refresh_node(node) - imprint(node, {"x_init": node.xpos(), "y_init": node.ypos()}) - node.knob("x_init").setVisible(False) - node.knob("y_init").setVisible(False) - width = node.screenWidth() - height = node.screenHeight() - if "bdwidth" in node.knobs(): - imprint(node, {"w_init": width, "h_init": height}) - node.knob("w_init").setVisible(False) - node.knob("h_init").setVisible(False) - refresh_node(node) - - def _update_nodes( - self, placeholder, nodes, considered_nodes, offset_y=None - ): - """Adjust backdrop nodes dimensions and positions. - - Considering some nodes sizes. - - Args: - nodes (list): list of nodes to update - considered_nodes (list): list of nodes to consider while updating - positions and dimensions - offset (int): distance between copies - """ - - placeholder_node = nuke.toNode(placeholder.scene_identifier) - - min_x, min_y, max_x, max_y = get_extreme_positions(considered_nodes) - - diff_x = diff_y = 0 - contained_nodes = [] # for backdrops - - if offset_y is None: - width_ph = placeholder_node.screenWidth() - height_ph = placeholder_node.screenHeight() - diff_y = max_y - min_y - height_ph - diff_x = max_x - min_x - width_ph - contained_nodes = [placeholder_node] - min_x = placeholder_node.xpos() - min_y = placeholder_node.ypos() - else: - siblings = get_nodes_by_names(placeholder.data["siblings"]) - minX, _, maxX, _ = get_extreme_positions(siblings) - diff_y = max_y - min_y + 20 - diff_x = abs(max_x - min_x - maxX + minX) - contained_nodes = considered_nodes - - if diff_y <= 0 and diff_x <= 0: - return - - for node in nodes: - refresh_node(node) - - if ( - node == placeholder_node - or node in considered_nodes - ): - continue - - if ( - not isinstance(node, nuke.BackdropNode) - or ( - isinstance(node, nuke.BackdropNode) - and not set(contained_nodes) <= set(node.getNodes()) - ) - ): - if offset_y is None and node.xpos() >= min_x: - node.setXpos(node.xpos() + diff_x) - - if node.ypos() >= min_y: - node.setYpos(node.ypos() + diff_y) - - else: - width = node.screenWidth() - height = node.screenHeight() - node.knob("bdwidth").setValue(width + diff_x) - node.knob("bdheight").setValue(height + diff_y) - - refresh_node(node) - - def _set_loaded_connections(self, placeholder): - """ - set inputs and outputs of loaded nodes""" - - placeholder_node = nuke.toNode(placeholder.scene_identifier) - input_node, output_node = get_group_io_nodes( - placeholder.data["last_loaded"] - ) - for node in placeholder_node.dependent(): - for idx in range(node.inputs()): - if node.input(idx) == placeholder_node and output_node: - node.setInput(idx, output_node) - - for node in placeholder_node.dependencies(): - for idx in range(placeholder_node.inputs()): - if placeholder_node.input(idx) == node and input_node: - input_node.setInput(0, node) - - def _create_sib_copies(self, placeholder): - """ creating copies of the palce_holder siblings (the ones who were - loaded with it) for the new nodes added - - Returns : - copies (dict) : with copied nodes names and their copies - """ - - copies = {} - siblings = get_nodes_by_names(placeholder.data["siblings"]) - for node in siblings: - new_node = duplicate_node(node) - - x_init = int(new_node.knob("x_init").getValue()) - y_init = int(new_node.knob("y_init").getValue()) - new_node.setXYpos(x_init, y_init) - if isinstance(new_node, nuke.BackdropNode): - w_init = new_node.knob("w_init").getValue() - h_init = new_node.knob("h_init").getValue() - new_node.knob("bdwidth").setValue(w_init) - new_node.knob("bdheight").setValue(h_init) - refresh_node(node) - - if "repre_id" in node.knobs().keys(): - node.removeKnob(node.knob("repre_id")) - copies[node.name()] = new_node - return copies - - def _set_copies_connections(self, placeholder, copies): - """Set inputs and outputs of the copies. - - Args: - copies (dict): Copied nodes by their names. - """ - - last_input, last_output = get_group_io_nodes( - placeholder.data["last_loaded"] - ) - siblings = get_nodes_by_names(placeholder.data["siblings"]) - siblings_input, siblings_output = get_group_io_nodes(siblings) - copy_input = copies[siblings_input.name()] - copy_output = copies[siblings_output.name()] - - for node_init in siblings: - if node_init == siblings_output: - continue - - node_copy = copies[node_init.name()] - for node in node_init.dependent(): - for idx in range(node.inputs()): - if node.input(idx) != node_init: - continue - - if node in siblings: - copies[node.name()].setInput(idx, node_copy) - else: - last_input.setInput(0, node_copy) - - for node in node_init.dependencies(): - for idx in range(node_init.inputs()): - if node_init.input(idx) != node: - continue - - if node_init == siblings_input: - copy_input.setInput(idx, node) - elif node in siblings: - node_copy.setInput(idx, copies[node.name()]) - else: - node_copy.setInput(idx, last_output) - - siblings_input.setInput(0, copy_output) diff --git a/server_addon/nuke/client/ayon_nuke/startup/__init__.py b/server_addon/nuke/client/ayon_nuke/startup/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/server_addon/nuke/client/ayon_nuke/startup/clear_rendered.py b/server_addon/nuke/client/ayon_nuke/startup/clear_rendered.py deleted file mode 100644 index 8072aae14f..0000000000 --- a/server_addon/nuke/client/ayon_nuke/startup/clear_rendered.py +++ /dev/null @@ -1,12 +0,0 @@ -import os - -from ayon_core.lib import Logger - - -def clear_rendered(dir_path): - log = Logger.get_logger(__name__) - - for _f in os.listdir(dir_path): - _f_path = os.path.join(dir_path, _f) - log.info("Removing: `{}`".format(_f_path)) - os.remove(_f_path) diff --git a/server_addon/nuke/client/ayon_nuke/startup/custom_write_node.py b/server_addon/nuke/client/ayon_nuke/startup/custom_write_node.py deleted file mode 100644 index 5b0f240a49..0000000000 --- a/server_addon/nuke/client/ayon_nuke/startup/custom_write_node.py +++ /dev/null @@ -1,153 +0,0 @@ -""" AYON custom script for setting up write nodes for non-publish """ -import os -import nuke -import nukescripts -from ayon_core.pipeline import Anatomy, get_current_project_name -from ayon_nuke.api.lib import ( - set_node_knobs_from_settings, - get_nuke_imageio_settings -) - - -temp_rendering_path_template = ( - "{work}/renders/nuke/{subset}/{subset}.{frame}.{ext}") - -knobs_setting = { - "knobs": [ - { - "type": "text", - "name": "file_type", - "value": "exr" - }, - { - "type": "text", - "name": "datatype", - "value": "16 bit half" - }, - { - "type": "text", - "name": "compression", - "value": "Zip (1 scanline)" - }, - { - "type": "bool", - "name": "autocrop", - "value": True - }, - { - "type": "color_gui", - "name": "tile_color", - "value": [ - 186, - 35, - 35, - 255 - ] - }, - { - "type": "text", - "name": "channels", - "value": "rgb" - }, - { - "type": "bool", - "name": "create_directories", - "value": True - } - ] -} - - -class WriteNodeKnobSettingPanel(nukescripts.PythonPanel): - """ Write Node's Knobs Settings Panel """ - def __init__(self): - nukescripts.PythonPanel.__init__(self, "Set Knobs Value(Write Node)") - - preset_name, _ = self.get_node_knobs_setting() - # create knobs - - self.selected_preset_name = nuke.Enumeration_Knob( - 'preset_selector', 'presets', preset_name) - # add knobs to panel - self.addKnob(self.selected_preset_name) - - def process(self): - """ Process the panel values. """ - write_selected_nodes = [ - selected_nodes for selected_nodes in nuke.selectedNodes() - if selected_nodes.Class() == "Write"] - - selected_preset = self.selected_preset_name.value() - ext = None - knobs = knobs_setting["knobs"] - preset_name, node_knobs_presets = ( - self.get_node_knobs_setting(selected_preset) - ) - - if selected_preset and preset_name: - if not node_knobs_presets: - nuke.message( - "No knobs value found in subset group.." - "\nDefault setting will be used..") - else: - knobs = node_knobs_presets - - ext_knob_list = [knob for knob in knobs if knob["name"] == "file_type"] - if not ext_knob_list: - nuke.message( - "ERROR: No file type found in the subset's knobs." - "\nPlease add one to complete setting up the node") - return - else: - for knob in ext_knob_list: - ext = knob["value"] - - anatomy = Anatomy(get_current_project_name()) - - frame_padding = anatomy.templates_obj.frame_padding - for write_node in write_selected_nodes: - # data for mapping the path - # TODO add more fill data - product_name = write_node["name"].value() - data = { - "work": os.getenv("AYON_WORKDIR"), - "subset": product_name, - "product": { - "name": product_name, - }, - "frame": "#" * frame_padding, - "ext": ext - } - file_path = temp_rendering_path_template.format(**data) - file_path = file_path.replace("\\", "/") - write_node["file"].setValue(file_path) - set_node_knobs_from_settings(write_node, knobs) - - def get_node_knobs_setting(self, selected_preset=None): - preset_name = [] - knobs_nodes = [] - settings = [ - node_settings for node_settings - in get_nuke_imageio_settings()["nodes"]["override_nodes"] - if node_settings["nuke_node_class"] == "Write" - and node_settings["subsets"] - ] - if not settings: - return - - for i, _ in enumerate(settings): - if selected_preset in settings[i]["subsets"]: - knobs_nodes = settings[i]["knobs"] - - for setting in settings: - # TODO change 'subsets' to 'product_names' in settings - for product_name in setting["subsets"]: - preset_name.append(product_name) - - return preset_name, knobs_nodes - - -def main(): - p_ = WriteNodeKnobSettingPanel() - if p_.showModalDialog(): - print(p_.process()) diff --git a/server_addon/nuke/client/ayon_nuke/startup/frame_setting_for_read_nodes.py b/server_addon/nuke/client/ayon_nuke/startup/frame_setting_for_read_nodes.py deleted file mode 100644 index 3e1430c3b1..0000000000 --- a/server_addon/nuke/client/ayon_nuke/startup/frame_setting_for_read_nodes.py +++ /dev/null @@ -1,47 +0,0 @@ -""" AYON custom script for resetting read nodes start frame values """ - -import nuke -import nukescripts - - -class FrameSettingsPanel(nukescripts.PythonPanel): - """ Frame Settings Panel """ - def __init__(self): - nukescripts.PythonPanel.__init__(self, "Set Frame Start (Read Node)") - - # create knobs - self.frame = nuke.Int_Knob( - 'frame', 'Frame Number') - self.selected = nuke.Boolean_Knob("selection") - # add knobs to panel - self.addKnob(self.selected) - self.addKnob(self.frame) - - # set values - self.selected.setValue(False) - self.frame.setValue(nuke.root().firstFrame()) - - def process(self): - """ Process the panel values. """ - # get values - frame = self.frame.value() - if self.selected.value(): - # selected nodes processing - if not nuke.selectedNodes(): - return - for rn_ in nuke.selectedNodes(): - if rn_.Class() != "Read": - continue - rn_["frame_mode"].setValue("start_at") - rn_["frame"].setValue(str(frame)) - else: - # all nodes processing - for rn_ in nuke.allNodes(filter="Read"): - rn_["frame_mode"].setValue("start_at") - rn_["frame"].setValue(str(frame)) - - -def main(): - p_ = FrameSettingsPanel() - if p_.showModalDialog(): - print(p_.process()) diff --git a/server_addon/nuke/client/ayon_nuke/startup/menu.py b/server_addon/nuke/client/ayon_nuke/startup/menu.py deleted file mode 100644 index c3dd8cda8f..0000000000 --- a/server_addon/nuke/client/ayon_nuke/startup/menu.py +++ /dev/null @@ -1,5 +0,0 @@ -from ayon_core.pipeline import install_host -from ayon_nuke.api import NukeHost - -host = NukeHost() -install_host(host) diff --git a/server_addon/nuke/client/ayon_nuke/startup/write_to_read.py b/server_addon/nuke/client/ayon_nuke/startup/write_to_read.py deleted file mode 100644 index 8a8ffb8d3d..0000000000 --- a/server_addon/nuke/client/ayon_nuke/startup/write_to_read.py +++ /dev/null @@ -1,151 +0,0 @@ -import re -import os -import glob -import nuke -from ayon_core.lib import Logger -log = Logger.get_logger(__name__) - -SINGLE_FILE_FORMATS = ['avi', 'mp4', 'mxf', 'mov', 'mpg', 'mpeg', 'wmv', 'm4v', - 'm2v'] - - -def evaluate_filepath_new( - k_value, k_eval, project_dir, first_frame, allow_relative): - - # get combined relative path - combined_relative_path = None - if k_eval is not None and project_dir is not None: - combined_relative_path = os.path.abspath( - os.path.join(project_dir, k_eval)) - combined_relative_path = combined_relative_path.replace('\\', '/') - filetype = combined_relative_path.split('.')[-1] - frame_number = re.findall(r'\d+', combined_relative_path)[-1] - basename = combined_relative_path[: combined_relative_path.rfind( - frame_number)] - filepath_glob = basename + '*' + filetype - glob_search_results = glob.glob(filepath_glob) - if len(glob_search_results) <= 0: - combined_relative_path = None - - try: - # k_value = k_value % first_frame - if os.path.isdir(os.path.basename(k_value)): - # doesn't check for file, only parent dir - filepath = k_value - elif os.path.exists(k_eval): - filepath = k_eval - elif not isinstance(project_dir, type(None)) and \ - not isinstance(combined_relative_path, type(None)): - filepath = combined_relative_path - - filepath = os.path.abspath(filepath) - except Exception as E: - log.error("Cannot create Read node. Perhaps it needs to be \ - rendered first :) Error: `{}`".format(E)) - return None - - filepath = filepath.replace('\\', '/') - # assumes last number is a sequence counter - current_frame = re.findall(r'\d+', filepath)[-1] - padding = len(current_frame) - basename = filepath[: filepath.rfind(current_frame)] - filetype = filepath.split('.')[-1] - - # sequence or not? - if filetype in SINGLE_FILE_FORMATS: - pass - else: - # Image sequence needs hashes - # to do still with no number not handled - filepath = basename + '#' * padding + '.' + filetype - - # relative path? make it relative again - if allow_relative: - if (not isinstance(project_dir, type(None))) and project_dir != "": - filepath = filepath.replace(project_dir, '.') - - # get first and last frame from disk - frames = [] - firstframe = 0 - lastframe = 0 - filepath_glob = basename + '*' + filetype - glob_search_results = glob.glob(filepath_glob) - for f in glob_search_results: - frame = re.findall(r'\d+', f)[-1] - frames.append(frame) - frames = sorted(frames) - firstframe = frames[0] - lastframe = frames[len(frames) - 1] - - if int(lastframe) < 0: - lastframe = firstframe - - return filepath, firstframe, lastframe - - -def create_read_node(ndata, comp_start): - read = nuke.createNode('Read', 'file "' + ndata['filepath'] + '"') - read.knob('colorspace').setValue(int(ndata['colorspace'])) - read.knob('raw').setValue(ndata['rawdata']) - read.knob('first').setValue(int(ndata['firstframe'])) - read.knob('last').setValue(int(ndata['lastframe'])) - read.knob('origfirst').setValue(int(ndata['firstframe'])) - read.knob('origlast').setValue(int(ndata['lastframe'])) - if comp_start == int(ndata['firstframe']): - read.knob('frame_mode').setValue("1") - read.knob('frame').setValue(str(comp_start)) - else: - read.knob('frame_mode').setValue("0") - read.knob('xpos').setValue(ndata['new_xpos']) - read.knob('ypos').setValue(ndata['new_ypos']) - nuke.inputs(read, 0) - return - - -def write_to_read(gn, - allow_relative=False): - - comp_start = nuke.Root().knob('first_frame').value() - project_dir = nuke.Root().knob('project_directory').getValue() - if not os.path.exists(project_dir): - project_dir = nuke.Root().knob('project_directory').evaluate() - - group_read_nodes = [] - with gn: - height = gn.screenHeight() # get group height and position - new_xpos = int(gn.knob('xpos').value()) - new_ypos = int(gn.knob('ypos').value()) + height + 20 - group_writes = [n for n in nuke.allNodes() if n.Class() == "Write"] - if group_writes != []: - # there can be only 1 write node, taking first - n = group_writes[0] - - if n.knob('file') is not None: - myfile, firstFrame, lastFrame = evaluate_filepath_new( - n.knob('file').getValue(), - n.knob('file').evaluate(), - project_dir, - comp_start, - allow_relative - ) - if not myfile: - return - - # get node data - ndata = { - 'filepath': myfile, - 'firstframe': int(firstFrame), - 'lastframe': int(lastFrame), - 'new_xpos': new_xpos, - 'new_ypos': new_ypos, - 'colorspace': n.knob('colorspace').getValue(), - 'rawdata': n.knob('raw').value(), - 'write_frame_mode': str(n.knob('frame_mode').value()), - 'write_frame': n.knob('frame').value() - } - group_read_nodes.append(ndata) - - # create reads in one go - for oneread in group_read_nodes: - # create read node - create_read_node(oneread, comp_start) diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/__init__.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/__init__.py deleted file mode 100644 index 03f3b29ee7..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/__init__.py +++ /dev/null @@ -1,33 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -# Copyright 2007 Google Inc. All Rights Reserved. - -__version__ = '3.20.1' diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/any_pb2.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/any_pb2.py deleted file mode 100644 index 9121193d11..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/any_pb2.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/any.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x19google/protobuf/any.proto\x12\x0fgoogle.protobuf\"&\n\x03\x41ny\x12\x10\n\x08type_url\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x0c\x42v\n\x13\x63om.google.protobufB\x08\x41nyProtoP\x01Z,google.golang.org/protobuf/types/known/anypb\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.any_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.google.protobufB\010AnyProtoP\001Z,google.golang.org/protobuf/types/known/anypb\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' - _ANY._serialized_start=46 - _ANY._serialized_end=84 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/api_pb2.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/api_pb2.py deleted file mode 100644 index 1721b10a75..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/api_pb2.py +++ /dev/null @@ -1,32 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/api.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.protobuf import source_context_pb2 as google_dot_protobuf_dot_source__context__pb2 -from google.protobuf import type_pb2 as google_dot_protobuf_dot_type__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x19google/protobuf/api.proto\x12\x0fgoogle.protobuf\x1a$google/protobuf/source_context.proto\x1a\x1agoogle/protobuf/type.proto\"\x81\x02\n\x03\x41pi\x12\x0c\n\x04name\x18\x01 \x01(\t\x12(\n\x07methods\x18\x02 \x03(\x0b\x32\x17.google.protobuf.Method\x12(\n\x07options\x18\x03 \x03(\x0b\x32\x17.google.protobuf.Option\x12\x0f\n\x07version\x18\x04 \x01(\t\x12\x36\n\x0esource_context\x18\x05 \x01(\x0b\x32\x1e.google.protobuf.SourceContext\x12&\n\x06mixins\x18\x06 \x03(\x0b\x32\x16.google.protobuf.Mixin\x12\'\n\x06syntax\x18\x07 \x01(\x0e\x32\x17.google.protobuf.Syntax\"\xd5\x01\n\x06Method\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x18\n\x10request_type_url\x18\x02 \x01(\t\x12\x19\n\x11request_streaming\x18\x03 \x01(\x08\x12\x19\n\x11response_type_url\x18\x04 \x01(\t\x12\x1a\n\x12response_streaming\x18\x05 \x01(\x08\x12(\n\x07options\x18\x06 \x03(\x0b\x32\x17.google.protobuf.Option\x12\'\n\x06syntax\x18\x07 \x01(\x0e\x32\x17.google.protobuf.Syntax\"#\n\x05Mixin\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04root\x18\x02 \x01(\tBv\n\x13\x63om.google.protobufB\x08\x41piProtoP\x01Z,google.golang.org/protobuf/types/known/apipb\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.api_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.google.protobufB\010ApiProtoP\001Z,google.golang.org/protobuf/types/known/apipb\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' - _API._serialized_start=113 - _API._serialized_end=370 - _METHOD._serialized_start=373 - _METHOD._serialized_end=586 - _MIXIN._serialized_start=588 - _MIXIN._serialized_end=623 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/compiler/__init__.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/compiler/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/compiler/plugin_pb2.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/compiler/plugin_pb2.py deleted file mode 100644 index 715a891370..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/compiler/plugin_pb2.py +++ /dev/null @@ -1,35 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/compiler/plugin.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n%google/protobuf/compiler/plugin.proto\x12\x18google.protobuf.compiler\x1a google/protobuf/descriptor.proto\"F\n\x07Version\x12\r\n\x05major\x18\x01 \x01(\x05\x12\r\n\x05minor\x18\x02 \x01(\x05\x12\r\n\x05patch\x18\x03 \x01(\x05\x12\x0e\n\x06suffix\x18\x04 \x01(\t\"\xba\x01\n\x14\x43odeGeneratorRequest\x12\x18\n\x10\x66ile_to_generate\x18\x01 \x03(\t\x12\x11\n\tparameter\x18\x02 \x01(\t\x12\x38\n\nproto_file\x18\x0f \x03(\x0b\x32$.google.protobuf.FileDescriptorProto\x12;\n\x10\x63ompiler_version\x18\x03 \x01(\x0b\x32!.google.protobuf.compiler.Version\"\xc1\x02\n\x15\x43odeGeneratorResponse\x12\r\n\x05\x65rror\x18\x01 \x01(\t\x12\x1a\n\x12supported_features\x18\x02 \x01(\x04\x12\x42\n\x04\x66ile\x18\x0f \x03(\x0b\x32\x34.google.protobuf.compiler.CodeGeneratorResponse.File\x1a\x7f\n\x04\x46ile\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x17\n\x0finsertion_point\x18\x02 \x01(\t\x12\x0f\n\x07\x63ontent\x18\x0f \x01(\t\x12?\n\x13generated_code_info\x18\x10 \x01(\x0b\x32\".google.protobuf.GeneratedCodeInfo\"8\n\x07\x46\x65\x61ture\x12\x10\n\x0c\x46\x45\x41TURE_NONE\x10\x00\x12\x1b\n\x17\x46\x45\x41TURE_PROTO3_OPTIONAL\x10\x01\x42W\n\x1c\x63om.google.protobuf.compilerB\x0cPluginProtosZ)google.golang.org/protobuf/types/pluginpb') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.compiler.plugin_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\034com.google.protobuf.compilerB\014PluginProtosZ)google.golang.org/protobuf/types/pluginpb' - _VERSION._serialized_start=101 - _VERSION._serialized_end=171 - _CODEGENERATORREQUEST._serialized_start=174 - _CODEGENERATORREQUEST._serialized_end=360 - _CODEGENERATORRESPONSE._serialized_start=363 - _CODEGENERATORRESPONSE._serialized_end=684 - _CODEGENERATORRESPONSE_FILE._serialized_start=499 - _CODEGENERATORRESPONSE_FILE._serialized_end=626 - _CODEGENERATORRESPONSE_FEATURE._serialized_start=628 - _CODEGENERATORRESPONSE_FEATURE._serialized_end=684 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/descriptor.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/descriptor.py deleted file mode 100644 index ad70be9a11..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/descriptor.py +++ /dev/null @@ -1,1224 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Descriptors essentially contain exactly the information found in a .proto -file, in types that make this information accessible in Python. -""" - -__author__ = 'robinson@google.com (Will Robinson)' - -import threading -import warnings - -from google.protobuf.internal import api_implementation - -_USE_C_DESCRIPTORS = False -if api_implementation.Type() == 'cpp': - # Used by MakeDescriptor in cpp mode - import binascii - import os - from google.protobuf.pyext import _message - _USE_C_DESCRIPTORS = True - - -class Error(Exception): - """Base error for this module.""" - - -class TypeTransformationError(Error): - """Error transforming between python proto type and corresponding C++ type.""" - - -if _USE_C_DESCRIPTORS: - # This metaclass allows to override the behavior of code like - # isinstance(my_descriptor, FieldDescriptor) - # and make it return True when the descriptor is an instance of the extension - # type written in C++. - class DescriptorMetaclass(type): - def __instancecheck__(cls, obj): - if super(DescriptorMetaclass, cls).__instancecheck__(obj): - return True - if isinstance(obj, cls._C_DESCRIPTOR_CLASS): - return True - return False -else: - # The standard metaclass; nothing changes. - DescriptorMetaclass = type - - -class _Lock(object): - """Wrapper class of threading.Lock(), which is allowed by 'with'.""" - - def __new__(cls): - self = object.__new__(cls) - self._lock = threading.Lock() # pylint: disable=protected-access - return self - - def __enter__(self): - self._lock.acquire() - - def __exit__(self, exc_type, exc_value, exc_tb): - self._lock.release() - - -_lock = threading.Lock() - - -def _Deprecated(name): - if _Deprecated.count > 0: - _Deprecated.count -= 1 - warnings.warn( - 'Call to deprecated create function %s(). Note: Create unlinked ' - 'descriptors is going to go away. Please use get/find descriptors from ' - 'generated code or query the descriptor_pool.' - % name, - category=DeprecationWarning, stacklevel=3) - - -# Deprecated warnings will print 100 times at most which should be enough for -# users to notice and do not cause timeout. -_Deprecated.count = 100 - - -_internal_create_key = object() - - -class DescriptorBase(metaclass=DescriptorMetaclass): - - """Descriptors base class. - - This class is the base of all descriptor classes. It provides common options - related functionality. - - Attributes: - has_options: True if the descriptor has non-default options. Usually it - is not necessary to read this -- just call GetOptions() which will - happily return the default instance. However, it's sometimes useful - for efficiency, and also useful inside the protobuf implementation to - avoid some bootstrapping issues. - """ - - if _USE_C_DESCRIPTORS: - # The class, or tuple of classes, that are considered as "virtual - # subclasses" of this descriptor class. - _C_DESCRIPTOR_CLASS = () - - def __init__(self, options, serialized_options, options_class_name): - """Initialize the descriptor given its options message and the name of the - class of the options message. The name of the class is required in case - the options message is None and has to be created. - """ - self._options = options - self._options_class_name = options_class_name - self._serialized_options = serialized_options - - # Does this descriptor have non-default options? - self.has_options = (options is not None) or (serialized_options is not None) - - def _SetOptions(self, options, options_class_name): - """Sets the descriptor's options - - This function is used in generated proto2 files to update descriptor - options. It must not be used outside proto2. - """ - self._options = options - self._options_class_name = options_class_name - - # Does this descriptor have non-default options? - self.has_options = options is not None - - def GetOptions(self): - """Retrieves descriptor options. - - This method returns the options set or creates the default options for the - descriptor. - """ - if self._options: - return self._options - - from google.protobuf import descriptor_pb2 - try: - options_class = getattr(descriptor_pb2, - self._options_class_name) - except AttributeError: - raise RuntimeError('Unknown options class name %s!' % - (self._options_class_name)) - - with _lock: - if self._serialized_options is None: - self._options = options_class() - else: - self._options = _ParseOptions(options_class(), - self._serialized_options) - - return self._options - - -class _NestedDescriptorBase(DescriptorBase): - """Common class for descriptors that can be nested.""" - - def __init__(self, options, options_class_name, name, full_name, - file, containing_type, serialized_start=None, - serialized_end=None, serialized_options=None): - """Constructor. - - Args: - options: Protocol message options or None - to use default message options. - options_class_name (str): The class name of the above options. - name (str): Name of this protocol message type. - full_name (str): Fully-qualified name of this protocol message type, - which will include protocol "package" name and the name of any - enclosing types. - file (FileDescriptor): Reference to file info. - containing_type: if provided, this is a nested descriptor, with this - descriptor as parent, otherwise None. - serialized_start: The start index (inclusive) in block in the - file.serialized_pb that describes this descriptor. - serialized_end: The end index (exclusive) in block in the - file.serialized_pb that describes this descriptor. - serialized_options: Protocol message serialized options or None. - """ - super(_NestedDescriptorBase, self).__init__( - options, serialized_options, options_class_name) - - self.name = name - # TODO(falk): Add function to calculate full_name instead of having it in - # memory? - self.full_name = full_name - self.file = file - self.containing_type = containing_type - - self._serialized_start = serialized_start - self._serialized_end = serialized_end - - def CopyToProto(self, proto): - """Copies this to the matching proto in descriptor_pb2. - - Args: - proto: An empty proto instance from descriptor_pb2. - - Raises: - Error: If self couldn't be serialized, due to to few constructor - arguments. - """ - if (self.file is not None and - self._serialized_start is not None and - self._serialized_end is not None): - proto.ParseFromString(self.file.serialized_pb[ - self._serialized_start:self._serialized_end]) - else: - raise Error('Descriptor does not contain serialization.') - - -class Descriptor(_NestedDescriptorBase): - - """Descriptor for a protocol message type. - - Attributes: - name (str): Name of this protocol message type. - full_name (str): Fully-qualified name of this protocol message type, - which will include protocol "package" name and the name of any - enclosing types. - containing_type (Descriptor): Reference to the descriptor of the type - containing us, or None if this is top-level. - fields (list[FieldDescriptor]): Field descriptors for all fields in - this type. - fields_by_number (dict(int, FieldDescriptor)): Same - :class:`FieldDescriptor` objects as in :attr:`fields`, but indexed - by "number" attribute in each FieldDescriptor. - fields_by_name (dict(str, FieldDescriptor)): Same - :class:`FieldDescriptor` objects as in :attr:`fields`, but indexed by - "name" attribute in each :class:`FieldDescriptor`. - nested_types (list[Descriptor]): Descriptor references - for all protocol message types nested within this one. - nested_types_by_name (dict(str, Descriptor)): Same Descriptor - objects as in :attr:`nested_types`, but indexed by "name" attribute - in each Descriptor. - enum_types (list[EnumDescriptor]): :class:`EnumDescriptor` references - for all enums contained within this type. - enum_types_by_name (dict(str, EnumDescriptor)): Same - :class:`EnumDescriptor` objects as in :attr:`enum_types`, but - indexed by "name" attribute in each EnumDescriptor. - enum_values_by_name (dict(str, EnumValueDescriptor)): Dict mapping - from enum value name to :class:`EnumValueDescriptor` for that value. - extensions (list[FieldDescriptor]): All extensions defined directly - within this message type (NOT within a nested type). - extensions_by_name (dict(str, FieldDescriptor)): Same FieldDescriptor - objects as :attr:`extensions`, but indexed by "name" attribute of each - FieldDescriptor. - is_extendable (bool): Does this type define any extension ranges? - oneofs (list[OneofDescriptor]): The list of descriptors for oneof fields - in this message. - oneofs_by_name (dict(str, OneofDescriptor)): Same objects as in - :attr:`oneofs`, but indexed by "name" attribute. - file (FileDescriptor): Reference to file descriptor. - - """ - - if _USE_C_DESCRIPTORS: - _C_DESCRIPTOR_CLASS = _message.Descriptor - - def __new__( - cls, - name=None, - full_name=None, - filename=None, - containing_type=None, - fields=None, - nested_types=None, - enum_types=None, - extensions=None, - options=None, - serialized_options=None, - is_extendable=True, - extension_ranges=None, - oneofs=None, - file=None, # pylint: disable=redefined-builtin - serialized_start=None, - serialized_end=None, - syntax=None, - create_key=None): - _message.Message._CheckCalledFromGeneratedFile() - return _message.default_pool.FindMessageTypeByName(full_name) - - # NOTE(tmarek): The file argument redefining a builtin is nothing we can - # fix right now since we don't know how many clients already rely on the - # name of the argument. - def __init__(self, name, full_name, filename, containing_type, fields, - nested_types, enum_types, extensions, options=None, - serialized_options=None, - is_extendable=True, extension_ranges=None, oneofs=None, - file=None, serialized_start=None, serialized_end=None, # pylint: disable=redefined-builtin - syntax=None, create_key=None): - """Arguments to __init__() are as described in the description - of Descriptor fields above. - - Note that filename is an obsolete argument, that is not used anymore. - Please use file.name to access this as an attribute. - """ - if create_key is not _internal_create_key: - _Deprecated('Descriptor') - - super(Descriptor, self).__init__( - options, 'MessageOptions', name, full_name, file, - containing_type, serialized_start=serialized_start, - serialized_end=serialized_end, serialized_options=serialized_options) - - # We have fields in addition to fields_by_name and fields_by_number, - # so that: - # 1. Clients can index fields by "order in which they're listed." - # 2. Clients can easily iterate over all fields with the terse - # syntax: for f in descriptor.fields: ... - self.fields = fields - for field in self.fields: - field.containing_type = self - self.fields_by_number = dict((f.number, f) for f in fields) - self.fields_by_name = dict((f.name, f) for f in fields) - self._fields_by_camelcase_name = None - - self.nested_types = nested_types - for nested_type in nested_types: - nested_type.containing_type = self - self.nested_types_by_name = dict((t.name, t) for t in nested_types) - - self.enum_types = enum_types - for enum_type in self.enum_types: - enum_type.containing_type = self - self.enum_types_by_name = dict((t.name, t) for t in enum_types) - self.enum_values_by_name = dict( - (v.name, v) for t in enum_types for v in t.values) - - self.extensions = extensions - for extension in self.extensions: - extension.extension_scope = self - self.extensions_by_name = dict((f.name, f) for f in extensions) - self.is_extendable = is_extendable - self.extension_ranges = extension_ranges - self.oneofs = oneofs if oneofs is not None else [] - self.oneofs_by_name = dict((o.name, o) for o in self.oneofs) - for oneof in self.oneofs: - oneof.containing_type = self - self.syntax = syntax or "proto2" - - @property - def fields_by_camelcase_name(self): - """Same FieldDescriptor objects as in :attr:`fields`, but indexed by - :attr:`FieldDescriptor.camelcase_name`. - """ - if self._fields_by_camelcase_name is None: - self._fields_by_camelcase_name = dict( - (f.camelcase_name, f) for f in self.fields) - return self._fields_by_camelcase_name - - def EnumValueName(self, enum, value): - """Returns the string name of an enum value. - - This is just a small helper method to simplify a common operation. - - Args: - enum: string name of the Enum. - value: int, value of the enum. - - Returns: - string name of the enum value. - - Raises: - KeyError if either the Enum doesn't exist or the value is not a valid - value for the enum. - """ - return self.enum_types_by_name[enum].values_by_number[value].name - - def CopyToProto(self, proto): - """Copies this to a descriptor_pb2.DescriptorProto. - - Args: - proto: An empty descriptor_pb2.DescriptorProto. - """ - # This function is overridden to give a better doc comment. - super(Descriptor, self).CopyToProto(proto) - - -# TODO(robinson): We should have aggressive checking here, -# for example: -# * If you specify a repeated field, you should not be allowed -# to specify a default value. -# * [Other examples here as needed]. -# -# TODO(robinson): for this and other *Descriptor classes, we -# might also want to lock things down aggressively (e.g., -# prevent clients from setting the attributes). Having -# stronger invariants here in general will reduce the number -# of runtime checks we must do in reflection.py... -class FieldDescriptor(DescriptorBase): - - """Descriptor for a single field in a .proto file. - - Attributes: - name (str): Name of this field, exactly as it appears in .proto. - full_name (str): Name of this field, including containing scope. This is - particularly relevant for extensions. - index (int): Dense, 0-indexed index giving the order that this - field textually appears within its message in the .proto file. - number (int): Tag number declared for this field in the .proto file. - - type (int): (One of the TYPE_* constants below) Declared type. - cpp_type (int): (One of the CPPTYPE_* constants below) C++ type used to - represent this field. - - label (int): (One of the LABEL_* constants below) Tells whether this - field is optional, required, or repeated. - has_default_value (bool): True if this field has a default value defined, - otherwise false. - default_value (Varies): Default value of this field. Only - meaningful for non-repeated scalar fields. Repeated fields - should always set this to [], and non-repeated composite - fields should always set this to None. - - containing_type (Descriptor): Descriptor of the protocol message - type that contains this field. Set by the Descriptor constructor - if we're passed into one. - Somewhat confusingly, for extension fields, this is the - descriptor of the EXTENDED message, not the descriptor - of the message containing this field. (See is_extension and - extension_scope below). - message_type (Descriptor): If a composite field, a descriptor - of the message type contained in this field. Otherwise, this is None. - enum_type (EnumDescriptor): If this field contains an enum, a - descriptor of that enum. Otherwise, this is None. - - is_extension: True iff this describes an extension field. - extension_scope (Descriptor): Only meaningful if is_extension is True. - Gives the message that immediately contains this extension field. - Will be None iff we're a top-level (file-level) extension field. - - options (descriptor_pb2.FieldOptions): Protocol message field options or - None to use default field options. - - containing_oneof (OneofDescriptor): If the field is a member of a oneof - union, contains its descriptor. Otherwise, None. - - file (FileDescriptor): Reference to file descriptor. - """ - - # Must be consistent with C++ FieldDescriptor::Type enum in - # descriptor.h. - # - # TODO(robinson): Find a way to eliminate this repetition. - TYPE_DOUBLE = 1 - TYPE_FLOAT = 2 - TYPE_INT64 = 3 - TYPE_UINT64 = 4 - TYPE_INT32 = 5 - TYPE_FIXED64 = 6 - TYPE_FIXED32 = 7 - TYPE_BOOL = 8 - TYPE_STRING = 9 - TYPE_GROUP = 10 - TYPE_MESSAGE = 11 - TYPE_BYTES = 12 - TYPE_UINT32 = 13 - TYPE_ENUM = 14 - TYPE_SFIXED32 = 15 - TYPE_SFIXED64 = 16 - TYPE_SINT32 = 17 - TYPE_SINT64 = 18 - MAX_TYPE = 18 - - # Must be consistent with C++ FieldDescriptor::CppType enum in - # descriptor.h. - # - # TODO(robinson): Find a way to eliminate this repetition. - CPPTYPE_INT32 = 1 - CPPTYPE_INT64 = 2 - CPPTYPE_UINT32 = 3 - CPPTYPE_UINT64 = 4 - CPPTYPE_DOUBLE = 5 - CPPTYPE_FLOAT = 6 - CPPTYPE_BOOL = 7 - CPPTYPE_ENUM = 8 - CPPTYPE_STRING = 9 - CPPTYPE_MESSAGE = 10 - MAX_CPPTYPE = 10 - - _PYTHON_TO_CPP_PROTO_TYPE_MAP = { - TYPE_DOUBLE: CPPTYPE_DOUBLE, - TYPE_FLOAT: CPPTYPE_FLOAT, - TYPE_ENUM: CPPTYPE_ENUM, - TYPE_INT64: CPPTYPE_INT64, - TYPE_SINT64: CPPTYPE_INT64, - TYPE_SFIXED64: CPPTYPE_INT64, - TYPE_UINT64: CPPTYPE_UINT64, - TYPE_FIXED64: CPPTYPE_UINT64, - TYPE_INT32: CPPTYPE_INT32, - TYPE_SFIXED32: CPPTYPE_INT32, - TYPE_SINT32: CPPTYPE_INT32, - TYPE_UINT32: CPPTYPE_UINT32, - TYPE_FIXED32: CPPTYPE_UINT32, - TYPE_BYTES: CPPTYPE_STRING, - TYPE_STRING: CPPTYPE_STRING, - TYPE_BOOL: CPPTYPE_BOOL, - TYPE_MESSAGE: CPPTYPE_MESSAGE, - TYPE_GROUP: CPPTYPE_MESSAGE - } - - # Must be consistent with C++ FieldDescriptor::Label enum in - # descriptor.h. - # - # TODO(robinson): Find a way to eliminate this repetition. - LABEL_OPTIONAL = 1 - LABEL_REQUIRED = 2 - LABEL_REPEATED = 3 - MAX_LABEL = 3 - - # Must be consistent with C++ constants kMaxNumber, kFirstReservedNumber, - # and kLastReservedNumber in descriptor.h - MAX_FIELD_NUMBER = (1 << 29) - 1 - FIRST_RESERVED_FIELD_NUMBER = 19000 - LAST_RESERVED_FIELD_NUMBER = 19999 - - if _USE_C_DESCRIPTORS: - _C_DESCRIPTOR_CLASS = _message.FieldDescriptor - - def __new__(cls, name, full_name, index, number, type, cpp_type, label, - default_value, message_type, enum_type, containing_type, - is_extension, extension_scope, options=None, - serialized_options=None, - has_default_value=True, containing_oneof=None, json_name=None, - file=None, create_key=None): # pylint: disable=redefined-builtin - _message.Message._CheckCalledFromGeneratedFile() - if is_extension: - return _message.default_pool.FindExtensionByName(full_name) - else: - return _message.default_pool.FindFieldByName(full_name) - - def __init__(self, name, full_name, index, number, type, cpp_type, label, - default_value, message_type, enum_type, containing_type, - is_extension, extension_scope, options=None, - serialized_options=None, - has_default_value=True, containing_oneof=None, json_name=None, - file=None, create_key=None): # pylint: disable=redefined-builtin - """The arguments are as described in the description of FieldDescriptor - attributes above. - - Note that containing_type may be None, and may be set later if necessary - (to deal with circular references between message types, for example). - Likewise for extension_scope. - """ - if create_key is not _internal_create_key: - _Deprecated('FieldDescriptor') - - super(FieldDescriptor, self).__init__( - options, serialized_options, 'FieldOptions') - self.name = name - self.full_name = full_name - self.file = file - self._camelcase_name = None - if json_name is None: - self.json_name = _ToJsonName(name) - else: - self.json_name = json_name - self.index = index - self.number = number - self.type = type - self.cpp_type = cpp_type - self.label = label - self.has_default_value = has_default_value - self.default_value = default_value - self.containing_type = containing_type - self.message_type = message_type - self.enum_type = enum_type - self.is_extension = is_extension - self.extension_scope = extension_scope - self.containing_oneof = containing_oneof - if api_implementation.Type() == 'cpp': - if is_extension: - self._cdescriptor = _message.default_pool.FindExtensionByName(full_name) - else: - self._cdescriptor = _message.default_pool.FindFieldByName(full_name) - else: - self._cdescriptor = None - - @property - def camelcase_name(self): - """Camelcase name of this field. - - Returns: - str: the name in CamelCase. - """ - if self._camelcase_name is None: - self._camelcase_name = _ToCamelCase(self.name) - return self._camelcase_name - - @property - def has_presence(self): - """Whether the field distinguishes between unpopulated and default values. - - Raises: - RuntimeError: singular field that is not linked with message nor file. - """ - if self.label == FieldDescriptor.LABEL_REPEATED: - return False - if (self.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE or - self.containing_oneof): - return True - if hasattr(self.file, 'syntax'): - return self.file.syntax == 'proto2' - if hasattr(self.message_type, 'syntax'): - return self.message_type.syntax == 'proto2' - raise RuntimeError( - 'has_presence is not ready to use because field %s is not' - ' linked with message type nor file' % self.full_name) - - @staticmethod - def ProtoTypeToCppProtoType(proto_type): - """Converts from a Python proto type to a C++ Proto Type. - - The Python ProtocolBuffer classes specify both the 'Python' datatype and the - 'C++' datatype - and they're not the same. This helper method should - translate from one to another. - - Args: - proto_type: the Python proto type (descriptor.FieldDescriptor.TYPE_*) - Returns: - int: descriptor.FieldDescriptor.CPPTYPE_*, the C++ type. - Raises: - TypeTransformationError: when the Python proto type isn't known. - """ - try: - return FieldDescriptor._PYTHON_TO_CPP_PROTO_TYPE_MAP[proto_type] - except KeyError: - raise TypeTransformationError('Unknown proto_type: %s' % proto_type) - - -class EnumDescriptor(_NestedDescriptorBase): - - """Descriptor for an enum defined in a .proto file. - - Attributes: - name (str): Name of the enum type. - full_name (str): Full name of the type, including package name - and any enclosing type(s). - - values (list[EnumValueDescriptor]): List of the values - in this enum. - values_by_name (dict(str, EnumValueDescriptor)): Same as :attr:`values`, - but indexed by the "name" field of each EnumValueDescriptor. - values_by_number (dict(int, EnumValueDescriptor)): Same as :attr:`values`, - but indexed by the "number" field of each EnumValueDescriptor. - containing_type (Descriptor): Descriptor of the immediate containing - type of this enum, or None if this is an enum defined at the - top level in a .proto file. Set by Descriptor's constructor - if we're passed into one. - file (FileDescriptor): Reference to file descriptor. - options (descriptor_pb2.EnumOptions): Enum options message or - None to use default enum options. - """ - - if _USE_C_DESCRIPTORS: - _C_DESCRIPTOR_CLASS = _message.EnumDescriptor - - def __new__(cls, name, full_name, filename, values, - containing_type=None, options=None, - serialized_options=None, file=None, # pylint: disable=redefined-builtin - serialized_start=None, serialized_end=None, create_key=None): - _message.Message._CheckCalledFromGeneratedFile() - return _message.default_pool.FindEnumTypeByName(full_name) - - def __init__(self, name, full_name, filename, values, - containing_type=None, options=None, - serialized_options=None, file=None, # pylint: disable=redefined-builtin - serialized_start=None, serialized_end=None, create_key=None): - """Arguments are as described in the attribute description above. - - Note that filename is an obsolete argument, that is not used anymore. - Please use file.name to access this as an attribute. - """ - if create_key is not _internal_create_key: - _Deprecated('EnumDescriptor') - - super(EnumDescriptor, self).__init__( - options, 'EnumOptions', name, full_name, file, - containing_type, serialized_start=serialized_start, - serialized_end=serialized_end, serialized_options=serialized_options) - - self.values = values - for value in self.values: - value.type = self - self.values_by_name = dict((v.name, v) for v in values) - # Values are reversed to ensure that the first alias is retained. - self.values_by_number = dict((v.number, v) for v in reversed(values)) - - def CopyToProto(self, proto): - """Copies this to a descriptor_pb2.EnumDescriptorProto. - - Args: - proto (descriptor_pb2.EnumDescriptorProto): An empty descriptor proto. - """ - # This function is overridden to give a better doc comment. - super(EnumDescriptor, self).CopyToProto(proto) - - -class EnumValueDescriptor(DescriptorBase): - - """Descriptor for a single value within an enum. - - Attributes: - name (str): Name of this value. - index (int): Dense, 0-indexed index giving the order that this - value appears textually within its enum in the .proto file. - number (int): Actual number assigned to this enum value. - type (EnumDescriptor): :class:`EnumDescriptor` to which this value - belongs. Set by :class:`EnumDescriptor`'s constructor if we're - passed into one. - options (descriptor_pb2.EnumValueOptions): Enum value options message or - None to use default enum value options options. - """ - - if _USE_C_DESCRIPTORS: - _C_DESCRIPTOR_CLASS = _message.EnumValueDescriptor - - def __new__(cls, name, index, number, - type=None, # pylint: disable=redefined-builtin - options=None, serialized_options=None, create_key=None): - _message.Message._CheckCalledFromGeneratedFile() - # There is no way we can build a complete EnumValueDescriptor with the - # given parameters (the name of the Enum is not known, for example). - # Fortunately generated files just pass it to the EnumDescriptor() - # constructor, which will ignore it, so returning None is good enough. - return None - - def __init__(self, name, index, number, - type=None, # pylint: disable=redefined-builtin - options=None, serialized_options=None, create_key=None): - """Arguments are as described in the attribute description above.""" - if create_key is not _internal_create_key: - _Deprecated('EnumValueDescriptor') - - super(EnumValueDescriptor, self).__init__( - options, serialized_options, 'EnumValueOptions') - self.name = name - self.index = index - self.number = number - self.type = type - - -class OneofDescriptor(DescriptorBase): - """Descriptor for a oneof field. - - Attributes: - name (str): Name of the oneof field. - full_name (str): Full name of the oneof field, including package name. - index (int): 0-based index giving the order of the oneof field inside - its containing type. - containing_type (Descriptor): :class:`Descriptor` of the protocol message - type that contains this field. Set by the :class:`Descriptor` constructor - if we're passed into one. - fields (list[FieldDescriptor]): The list of field descriptors this - oneof can contain. - """ - - if _USE_C_DESCRIPTORS: - _C_DESCRIPTOR_CLASS = _message.OneofDescriptor - - def __new__( - cls, name, full_name, index, containing_type, fields, options=None, - serialized_options=None, create_key=None): - _message.Message._CheckCalledFromGeneratedFile() - return _message.default_pool.FindOneofByName(full_name) - - def __init__( - self, name, full_name, index, containing_type, fields, options=None, - serialized_options=None, create_key=None): - """Arguments are as described in the attribute description above.""" - if create_key is not _internal_create_key: - _Deprecated('OneofDescriptor') - - super(OneofDescriptor, self).__init__( - options, serialized_options, 'OneofOptions') - self.name = name - self.full_name = full_name - self.index = index - self.containing_type = containing_type - self.fields = fields - - -class ServiceDescriptor(_NestedDescriptorBase): - - """Descriptor for a service. - - Attributes: - name (str): Name of the service. - full_name (str): Full name of the service, including package name. - index (int): 0-indexed index giving the order that this services - definition appears within the .proto file. - methods (list[MethodDescriptor]): List of methods provided by this - service. - methods_by_name (dict(str, MethodDescriptor)): Same - :class:`MethodDescriptor` objects as in :attr:`methods_by_name`, but - indexed by "name" attribute in each :class:`MethodDescriptor`. - options (descriptor_pb2.ServiceOptions): Service options message or - None to use default service options. - file (FileDescriptor): Reference to file info. - """ - - if _USE_C_DESCRIPTORS: - _C_DESCRIPTOR_CLASS = _message.ServiceDescriptor - - def __new__( - cls, - name=None, - full_name=None, - index=None, - methods=None, - options=None, - serialized_options=None, - file=None, # pylint: disable=redefined-builtin - serialized_start=None, - serialized_end=None, - create_key=None): - _message.Message._CheckCalledFromGeneratedFile() # pylint: disable=protected-access - return _message.default_pool.FindServiceByName(full_name) - - def __init__(self, name, full_name, index, methods, options=None, - serialized_options=None, file=None, # pylint: disable=redefined-builtin - serialized_start=None, serialized_end=None, create_key=None): - if create_key is not _internal_create_key: - _Deprecated('ServiceDescriptor') - - super(ServiceDescriptor, self).__init__( - options, 'ServiceOptions', name, full_name, file, - None, serialized_start=serialized_start, - serialized_end=serialized_end, serialized_options=serialized_options) - self.index = index - self.methods = methods - self.methods_by_name = dict((m.name, m) for m in methods) - # Set the containing service for each method in this service. - for method in self.methods: - method.containing_service = self - - def FindMethodByName(self, name): - """Searches for the specified method, and returns its descriptor. - - Args: - name (str): Name of the method. - Returns: - MethodDescriptor or None: the descriptor for the requested method, if - found. - """ - return self.methods_by_name.get(name, None) - - def CopyToProto(self, proto): - """Copies this to a descriptor_pb2.ServiceDescriptorProto. - - Args: - proto (descriptor_pb2.ServiceDescriptorProto): An empty descriptor proto. - """ - # This function is overridden to give a better doc comment. - super(ServiceDescriptor, self).CopyToProto(proto) - - -class MethodDescriptor(DescriptorBase): - - """Descriptor for a method in a service. - - Attributes: - name (str): Name of the method within the service. - full_name (str): Full name of method. - index (int): 0-indexed index of the method inside the service. - containing_service (ServiceDescriptor): The service that contains this - method. - input_type (Descriptor): The descriptor of the message that this method - accepts. - output_type (Descriptor): The descriptor of the message that this method - returns. - client_streaming (bool): Whether this method uses client streaming. - server_streaming (bool): Whether this method uses server streaming. - options (descriptor_pb2.MethodOptions or None): Method options message, or - None to use default method options. - """ - - if _USE_C_DESCRIPTORS: - _C_DESCRIPTOR_CLASS = _message.MethodDescriptor - - def __new__(cls, - name, - full_name, - index, - containing_service, - input_type, - output_type, - client_streaming=False, - server_streaming=False, - options=None, - serialized_options=None, - create_key=None): - _message.Message._CheckCalledFromGeneratedFile() # pylint: disable=protected-access - return _message.default_pool.FindMethodByName(full_name) - - def __init__(self, - name, - full_name, - index, - containing_service, - input_type, - output_type, - client_streaming=False, - server_streaming=False, - options=None, - serialized_options=None, - create_key=None): - """The arguments are as described in the description of MethodDescriptor - attributes above. - - Note that containing_service may be None, and may be set later if necessary. - """ - if create_key is not _internal_create_key: - _Deprecated('MethodDescriptor') - - super(MethodDescriptor, self).__init__( - options, serialized_options, 'MethodOptions') - self.name = name - self.full_name = full_name - self.index = index - self.containing_service = containing_service - self.input_type = input_type - self.output_type = output_type - self.client_streaming = client_streaming - self.server_streaming = server_streaming - - def CopyToProto(self, proto): - """Copies this to a descriptor_pb2.MethodDescriptorProto. - - Args: - proto (descriptor_pb2.MethodDescriptorProto): An empty descriptor proto. - - Raises: - Error: If self couldn't be serialized, due to too few constructor - arguments. - """ - if self.containing_service is not None: - from google.protobuf import descriptor_pb2 - service_proto = descriptor_pb2.ServiceDescriptorProto() - self.containing_service.CopyToProto(service_proto) - proto.CopyFrom(service_proto.method[self.index]) - else: - raise Error('Descriptor does not contain a service.') - - -class FileDescriptor(DescriptorBase): - """Descriptor for a file. Mimics the descriptor_pb2.FileDescriptorProto. - - Note that :attr:`enum_types_by_name`, :attr:`extensions_by_name`, and - :attr:`dependencies` fields are only set by the - :py:mod:`google.protobuf.message_factory` module, and not by the generated - proto code. - - Attributes: - name (str): Name of file, relative to root of source tree. - package (str): Name of the package - syntax (str): string indicating syntax of the file (can be "proto2" or - "proto3") - serialized_pb (bytes): Byte string of serialized - :class:`descriptor_pb2.FileDescriptorProto`. - dependencies (list[FileDescriptor]): List of other :class:`FileDescriptor` - objects this :class:`FileDescriptor` depends on. - public_dependencies (list[FileDescriptor]): A subset of - :attr:`dependencies`, which were declared as "public". - message_types_by_name (dict(str, Descriptor)): Mapping from message names - to their :class:`Descriptor`. - enum_types_by_name (dict(str, EnumDescriptor)): Mapping from enum names to - their :class:`EnumDescriptor`. - extensions_by_name (dict(str, FieldDescriptor)): Mapping from extension - names declared at file scope to their :class:`FieldDescriptor`. - services_by_name (dict(str, ServiceDescriptor)): Mapping from services' - names to their :class:`ServiceDescriptor`. - pool (DescriptorPool): The pool this descriptor belongs to. When not - passed to the constructor, the global default pool is used. - """ - - if _USE_C_DESCRIPTORS: - _C_DESCRIPTOR_CLASS = _message.FileDescriptor - - def __new__(cls, name, package, options=None, - serialized_options=None, serialized_pb=None, - dependencies=None, public_dependencies=None, - syntax=None, pool=None, create_key=None): - # FileDescriptor() is called from various places, not only from generated - # files, to register dynamic proto files and messages. - # pylint: disable=g-explicit-bool-comparison - if serialized_pb == b'': - # Cpp generated code must be linked in if serialized_pb is '' - try: - return _message.default_pool.FindFileByName(name) - except KeyError: - raise RuntimeError('Please link in cpp generated lib for %s' % (name)) - elif serialized_pb: - return _message.default_pool.AddSerializedFile(serialized_pb) - else: - return super(FileDescriptor, cls).__new__(cls) - - def __init__(self, name, package, options=None, - serialized_options=None, serialized_pb=None, - dependencies=None, public_dependencies=None, - syntax=None, pool=None, create_key=None): - """Constructor.""" - if create_key is not _internal_create_key: - _Deprecated('FileDescriptor') - - super(FileDescriptor, self).__init__( - options, serialized_options, 'FileOptions') - - if pool is None: - from google.protobuf import descriptor_pool - pool = descriptor_pool.Default() - self.pool = pool - self.message_types_by_name = {} - self.name = name - self.package = package - self.syntax = syntax or "proto2" - self.serialized_pb = serialized_pb - - self.enum_types_by_name = {} - self.extensions_by_name = {} - self.services_by_name = {} - self.dependencies = (dependencies or []) - self.public_dependencies = (public_dependencies or []) - - def CopyToProto(self, proto): - """Copies this to a descriptor_pb2.FileDescriptorProto. - - Args: - proto: An empty descriptor_pb2.FileDescriptorProto. - """ - proto.ParseFromString(self.serialized_pb) - - -def _ParseOptions(message, string): - """Parses serialized options. - - This helper function is used to parse serialized options in generated - proto2 files. It must not be used outside proto2. - """ - message.ParseFromString(string) - return message - - -def _ToCamelCase(name): - """Converts name to camel-case and returns it.""" - capitalize_next = False - result = [] - - for c in name: - if c == '_': - if result: - capitalize_next = True - elif capitalize_next: - result.append(c.upper()) - capitalize_next = False - else: - result += c - - # Lower-case the first letter. - if result and result[0].isupper(): - result[0] = result[0].lower() - return ''.join(result) - - -def _OptionsOrNone(descriptor_proto): - """Returns the value of the field `options`, or None if it is not set.""" - if descriptor_proto.HasField('options'): - return descriptor_proto.options - else: - return None - - -def _ToJsonName(name): - """Converts name to Json name and returns it.""" - capitalize_next = False - result = [] - - for c in name: - if c == '_': - capitalize_next = True - elif capitalize_next: - result.append(c.upper()) - capitalize_next = False - else: - result += c - - return ''.join(result) - - -def MakeDescriptor(desc_proto, package='', build_file_if_cpp=True, - syntax=None): - """Make a protobuf Descriptor given a DescriptorProto protobuf. - - Handles nested descriptors. Note that this is limited to the scope of defining - a message inside of another message. Composite fields can currently only be - resolved if the message is defined in the same scope as the field. - - Args: - desc_proto: The descriptor_pb2.DescriptorProto protobuf message. - package: Optional package name for the new message Descriptor (string). - build_file_if_cpp: Update the C++ descriptor pool if api matches. - Set to False on recursion, so no duplicates are created. - syntax: The syntax/semantics that should be used. Set to "proto3" to get - proto3 field presence semantics. - Returns: - A Descriptor for protobuf messages. - """ - if api_implementation.Type() == 'cpp' and build_file_if_cpp: - # The C++ implementation requires all descriptors to be backed by the same - # definition in the C++ descriptor pool. To do this, we build a - # FileDescriptorProto with the same definition as this descriptor and build - # it into the pool. - from google.protobuf import descriptor_pb2 - file_descriptor_proto = descriptor_pb2.FileDescriptorProto() - file_descriptor_proto.message_type.add().MergeFrom(desc_proto) - - # Generate a random name for this proto file to prevent conflicts with any - # imported ones. We need to specify a file name so the descriptor pool - # accepts our FileDescriptorProto, but it is not important what that file - # name is actually set to. - proto_name = binascii.hexlify(os.urandom(16)).decode('ascii') - - if package: - file_descriptor_proto.name = os.path.join(package.replace('.', '/'), - proto_name + '.proto') - file_descriptor_proto.package = package - else: - file_descriptor_proto.name = proto_name + '.proto' - - _message.default_pool.Add(file_descriptor_proto) - result = _message.default_pool.FindFileByName(file_descriptor_proto.name) - - if _USE_C_DESCRIPTORS: - return result.message_types_by_name[desc_proto.name] - - full_message_name = [desc_proto.name] - if package: full_message_name.insert(0, package) - - # Create Descriptors for enum types - enum_types = {} - for enum_proto in desc_proto.enum_type: - full_name = '.'.join(full_message_name + [enum_proto.name]) - enum_desc = EnumDescriptor( - enum_proto.name, full_name, None, [ - EnumValueDescriptor(enum_val.name, ii, enum_val.number, - create_key=_internal_create_key) - for ii, enum_val in enumerate(enum_proto.value)], - create_key=_internal_create_key) - enum_types[full_name] = enum_desc - - # Create Descriptors for nested types - nested_types = {} - for nested_proto in desc_proto.nested_type: - full_name = '.'.join(full_message_name + [nested_proto.name]) - # Nested types are just those defined inside of the message, not all types - # used by fields in the message, so no loops are possible here. - nested_desc = MakeDescriptor(nested_proto, - package='.'.join(full_message_name), - build_file_if_cpp=False, - syntax=syntax) - nested_types[full_name] = nested_desc - - fields = [] - for field_proto in desc_proto.field: - full_name = '.'.join(full_message_name + [field_proto.name]) - enum_desc = None - nested_desc = None - if field_proto.json_name: - json_name = field_proto.json_name - else: - json_name = None - if field_proto.HasField('type_name'): - type_name = field_proto.type_name - full_type_name = '.'.join(full_message_name + - [type_name[type_name.rfind('.')+1:]]) - if full_type_name in nested_types: - nested_desc = nested_types[full_type_name] - elif full_type_name in enum_types: - enum_desc = enum_types[full_type_name] - # Else type_name references a non-local type, which isn't implemented - field = FieldDescriptor( - field_proto.name, full_name, field_proto.number - 1, - field_proto.number, field_proto.type, - FieldDescriptor.ProtoTypeToCppProtoType(field_proto.type), - field_proto.label, None, nested_desc, enum_desc, None, False, None, - options=_OptionsOrNone(field_proto), has_default_value=False, - json_name=json_name, create_key=_internal_create_key) - fields.append(field) - - desc_name = '.'.join(full_message_name) - return Descriptor(desc_proto.name, desc_name, None, None, fields, - list(nested_types.values()), list(enum_types.values()), [], - options=_OptionsOrNone(desc_proto), - create_key=_internal_create_key) diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/descriptor_database.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/descriptor_database.py deleted file mode 100644 index 073eddc711..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/descriptor_database.py +++ /dev/null @@ -1,177 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Provides a container for DescriptorProtos.""" - -__author__ = 'matthewtoia@google.com (Matt Toia)' - -import warnings - - -class Error(Exception): - pass - - -class DescriptorDatabaseConflictingDefinitionError(Error): - """Raised when a proto is added with the same name & different descriptor.""" - - -class DescriptorDatabase(object): - """A container accepting FileDescriptorProtos and maps DescriptorProtos.""" - - def __init__(self): - self._file_desc_protos_by_file = {} - self._file_desc_protos_by_symbol = {} - - def Add(self, file_desc_proto): - """Adds the FileDescriptorProto and its types to this database. - - Args: - file_desc_proto: The FileDescriptorProto to add. - Raises: - DescriptorDatabaseConflictingDefinitionError: if an attempt is made to - add a proto with the same name but different definition than an - existing proto in the database. - """ - proto_name = file_desc_proto.name - if proto_name not in self._file_desc_protos_by_file: - self._file_desc_protos_by_file[proto_name] = file_desc_proto - elif self._file_desc_protos_by_file[proto_name] != file_desc_proto: - raise DescriptorDatabaseConflictingDefinitionError( - '%s already added, but with different descriptor.' % proto_name) - else: - return - - # Add all the top-level descriptors to the index. - package = file_desc_proto.package - for message in file_desc_proto.message_type: - for name in _ExtractSymbols(message, package): - self._AddSymbol(name, file_desc_proto) - for enum in file_desc_proto.enum_type: - self._AddSymbol(('.'.join((package, enum.name))), file_desc_proto) - for enum_value in enum.value: - self._file_desc_protos_by_symbol[ - '.'.join((package, enum_value.name))] = file_desc_proto - for extension in file_desc_proto.extension: - self._AddSymbol(('.'.join((package, extension.name))), file_desc_proto) - for service in file_desc_proto.service: - self._AddSymbol(('.'.join((package, service.name))), file_desc_proto) - - def FindFileByName(self, name): - """Finds the file descriptor proto by file name. - - Typically the file name is a relative path ending to a .proto file. The - proto with the given name will have to have been added to this database - using the Add method or else an error will be raised. - - Args: - name: The file name to find. - - Returns: - The file descriptor proto matching the name. - - Raises: - KeyError if no file by the given name was added. - """ - - return self._file_desc_protos_by_file[name] - - def FindFileContainingSymbol(self, symbol): - """Finds the file descriptor proto containing the specified symbol. - - The symbol should be a fully qualified name including the file descriptor's - package and any containing messages. Some examples: - - 'some.package.name.Message' - 'some.package.name.Message.NestedEnum' - 'some.package.name.Message.some_field' - - The file descriptor proto containing the specified symbol must be added to - this database using the Add method or else an error will be raised. - - Args: - symbol: The fully qualified symbol name. - - Returns: - The file descriptor proto containing the symbol. - - Raises: - KeyError if no file contains the specified symbol. - """ - try: - return self._file_desc_protos_by_symbol[symbol] - except KeyError: - # Fields, enum values, and nested extensions are not in - # _file_desc_protos_by_symbol. Try to find the top level - # descriptor. Non-existent nested symbol under a valid top level - # descriptor can also be found. The behavior is the same with - # protobuf C++. - top_level, _, _ = symbol.rpartition('.') - try: - return self._file_desc_protos_by_symbol[top_level] - except KeyError: - # Raise the original symbol as a KeyError for better diagnostics. - raise KeyError(symbol) - - def FindFileContainingExtension(self, extendee_name, extension_number): - # TODO(jieluo): implement this API. - return None - - def FindAllExtensionNumbers(self, extendee_name): - # TODO(jieluo): implement this API. - return [] - - def _AddSymbol(self, name, file_desc_proto): - if name in self._file_desc_protos_by_symbol: - warn_msg = ('Conflict register for file "' + file_desc_proto.name + - '": ' + name + - ' is already defined in file "' + - self._file_desc_protos_by_symbol[name].name + '"') - warnings.warn(warn_msg, RuntimeWarning) - self._file_desc_protos_by_symbol[name] = file_desc_proto - - -def _ExtractSymbols(desc_proto, package): - """Pulls out all the symbols from a descriptor proto. - - Args: - desc_proto: The proto to extract symbols from. - package: The package containing the descriptor type. - - Yields: - The fully qualified name found in the descriptor. - """ - message_name = package + '.' + desc_proto.name if package else desc_proto.name - yield message_name - for nested_type in desc_proto.nested_type: - for symbol in _ExtractSymbols(nested_type, message_name): - yield symbol - for enum_type in desc_proto.enum_type: - yield '.'.join((message_name, enum_type.name)) diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/descriptor_pb2.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/descriptor_pb2.py deleted file mode 100644 index f570386432..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/descriptor_pb2.py +++ /dev/null @@ -1,1925 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/descriptor.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -if _descriptor._USE_C_DESCRIPTORS == False: - DESCRIPTOR = _descriptor.FileDescriptor( - name='google/protobuf/descriptor.proto', - package='google.protobuf', - syntax='proto2', - serialized_options=None, - create_key=_descriptor._internal_create_key, - serialized_pb=b'\n google/protobuf/descriptor.proto\x12\x0fgoogle.protobuf\"G\n\x11\x46ileDescriptorSet\x12\x32\n\x04\x66ile\x18\x01 \x03(\x0b\x32$.google.protobuf.FileDescriptorProto\"\xdb\x03\n\x13\x46ileDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07package\x18\x02 \x01(\t\x12\x12\n\ndependency\x18\x03 \x03(\t\x12\x19\n\x11public_dependency\x18\n \x03(\x05\x12\x17\n\x0fweak_dependency\x18\x0b \x03(\x05\x12\x36\n\x0cmessage_type\x18\x04 \x03(\x0b\x32 .google.protobuf.DescriptorProto\x12\x37\n\tenum_type\x18\x05 \x03(\x0b\x32$.google.protobuf.EnumDescriptorProto\x12\x38\n\x07service\x18\x06 \x03(\x0b\x32\'.google.protobuf.ServiceDescriptorProto\x12\x38\n\textension\x18\x07 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProto\x12-\n\x07options\x18\x08 \x01(\x0b\x32\x1c.google.protobuf.FileOptions\x12\x39\n\x10source_code_info\x18\t \x01(\x0b\x32\x1f.google.protobuf.SourceCodeInfo\x12\x0e\n\x06syntax\x18\x0c \x01(\t\"\xa9\x05\n\x0f\x44\x65scriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x34\n\x05\x66ield\x18\x02 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProto\x12\x38\n\textension\x18\x06 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProto\x12\x35\n\x0bnested_type\x18\x03 \x03(\x0b\x32 .google.protobuf.DescriptorProto\x12\x37\n\tenum_type\x18\x04 \x03(\x0b\x32$.google.protobuf.EnumDescriptorProto\x12H\n\x0f\x65xtension_range\x18\x05 \x03(\x0b\x32/.google.protobuf.DescriptorProto.ExtensionRange\x12\x39\n\noneof_decl\x18\x08 \x03(\x0b\x32%.google.protobuf.OneofDescriptorProto\x12\x30\n\x07options\x18\x07 \x01(\x0b\x32\x1f.google.protobuf.MessageOptions\x12\x46\n\x0ereserved_range\x18\t \x03(\x0b\x32..google.protobuf.DescriptorProto.ReservedRange\x12\x15\n\rreserved_name\x18\n \x03(\t\x1a\x65\n\x0e\x45xtensionRange\x12\r\n\x05start\x18\x01 \x01(\x05\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x05\x12\x37\n\x07options\x18\x03 \x01(\x0b\x32&.google.protobuf.ExtensionRangeOptions\x1a+\n\rReservedRange\x12\r\n\x05start\x18\x01 \x01(\x05\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x05\"g\n\x15\x45xtensionRangeOptions\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xd5\x05\n\x14\x46ieldDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06number\x18\x03 \x01(\x05\x12:\n\x05label\x18\x04 \x01(\x0e\x32+.google.protobuf.FieldDescriptorProto.Label\x12\x38\n\x04type\x18\x05 \x01(\x0e\x32*.google.protobuf.FieldDescriptorProto.Type\x12\x11\n\ttype_name\x18\x06 \x01(\t\x12\x10\n\x08\x65xtendee\x18\x02 \x01(\t\x12\x15\n\rdefault_value\x18\x07 \x01(\t\x12\x13\n\x0boneof_index\x18\t \x01(\x05\x12\x11\n\tjson_name\x18\n \x01(\t\x12.\n\x07options\x18\x08 \x01(\x0b\x32\x1d.google.protobuf.FieldOptions\x12\x17\n\x0fproto3_optional\x18\x11 \x01(\x08\"\xb6\x02\n\x04Type\x12\x0f\n\x0bTYPE_DOUBLE\x10\x01\x12\x0e\n\nTYPE_FLOAT\x10\x02\x12\x0e\n\nTYPE_INT64\x10\x03\x12\x0f\n\x0bTYPE_UINT64\x10\x04\x12\x0e\n\nTYPE_INT32\x10\x05\x12\x10\n\x0cTYPE_FIXED64\x10\x06\x12\x10\n\x0cTYPE_FIXED32\x10\x07\x12\r\n\tTYPE_BOOL\x10\x08\x12\x0f\n\x0bTYPE_STRING\x10\t\x12\x0e\n\nTYPE_GROUP\x10\n\x12\x10\n\x0cTYPE_MESSAGE\x10\x0b\x12\x0e\n\nTYPE_BYTES\x10\x0c\x12\x0f\n\x0bTYPE_UINT32\x10\r\x12\r\n\tTYPE_ENUM\x10\x0e\x12\x11\n\rTYPE_SFIXED32\x10\x0f\x12\x11\n\rTYPE_SFIXED64\x10\x10\x12\x0f\n\x0bTYPE_SINT32\x10\x11\x12\x0f\n\x0bTYPE_SINT64\x10\x12\"C\n\x05Label\x12\x12\n\x0eLABEL_OPTIONAL\x10\x01\x12\x12\n\x0eLABEL_REQUIRED\x10\x02\x12\x12\n\x0eLABEL_REPEATED\x10\x03\"T\n\x14OneofDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12.\n\x07options\x18\x02 \x01(\x0b\x32\x1d.google.protobuf.OneofOptions\"\xa4\x02\n\x13\x45numDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x38\n\x05value\x18\x02 \x03(\x0b\x32).google.protobuf.EnumValueDescriptorProto\x12-\n\x07options\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.EnumOptions\x12N\n\x0ereserved_range\x18\x04 \x03(\x0b\x32\x36.google.protobuf.EnumDescriptorProto.EnumReservedRange\x12\x15\n\rreserved_name\x18\x05 \x03(\t\x1a/\n\x11\x45numReservedRange\x12\r\n\x05start\x18\x01 \x01(\x05\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x05\"l\n\x18\x45numValueDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06number\x18\x02 \x01(\x05\x12\x32\n\x07options\x18\x03 \x01(\x0b\x32!.google.protobuf.EnumValueOptions\"\x90\x01\n\x16ServiceDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x36\n\x06method\x18\x02 \x03(\x0b\x32&.google.protobuf.MethodDescriptorProto\x12\x30\n\x07options\x18\x03 \x01(\x0b\x32\x1f.google.protobuf.ServiceOptions\"\xc1\x01\n\x15MethodDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x12\n\ninput_type\x18\x02 \x01(\t\x12\x13\n\x0boutput_type\x18\x03 \x01(\t\x12/\n\x07options\x18\x04 \x01(\x0b\x32\x1e.google.protobuf.MethodOptions\x12\x1f\n\x10\x63lient_streaming\x18\x05 \x01(\x08:\x05\x66\x61lse\x12\x1f\n\x10server_streaming\x18\x06 \x01(\x08:\x05\x66\x61lse\"\xa5\x06\n\x0b\x46ileOptions\x12\x14\n\x0cjava_package\x18\x01 \x01(\t\x12\x1c\n\x14java_outer_classname\x18\x08 \x01(\t\x12\"\n\x13java_multiple_files\x18\n \x01(\x08:\x05\x66\x61lse\x12)\n\x1djava_generate_equals_and_hash\x18\x14 \x01(\x08\x42\x02\x18\x01\x12%\n\x16java_string_check_utf8\x18\x1b \x01(\x08:\x05\x66\x61lse\x12\x46\n\x0coptimize_for\x18\t \x01(\x0e\x32).google.protobuf.FileOptions.OptimizeMode:\x05SPEED\x12\x12\n\ngo_package\x18\x0b \x01(\t\x12\"\n\x13\x63\x63_generic_services\x18\x10 \x01(\x08:\x05\x66\x61lse\x12$\n\x15java_generic_services\x18\x11 \x01(\x08:\x05\x66\x61lse\x12\"\n\x13py_generic_services\x18\x12 \x01(\x08:\x05\x66\x61lse\x12#\n\x14php_generic_services\x18* \x01(\x08:\x05\x66\x61lse\x12\x19\n\ndeprecated\x18\x17 \x01(\x08:\x05\x66\x61lse\x12\x1e\n\x10\x63\x63_enable_arenas\x18\x1f \x01(\x08:\x04true\x12\x19\n\x11objc_class_prefix\x18$ \x01(\t\x12\x18\n\x10\x63sharp_namespace\x18% \x01(\t\x12\x14\n\x0cswift_prefix\x18\' \x01(\t\x12\x18\n\x10php_class_prefix\x18( \x01(\t\x12\x15\n\rphp_namespace\x18) \x01(\t\x12\x1e\n\x16php_metadata_namespace\x18, \x01(\t\x12\x14\n\x0cruby_package\x18- \x01(\t\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption\":\n\x0cOptimizeMode\x12\t\n\x05SPEED\x10\x01\x12\r\n\tCODE_SIZE\x10\x02\x12\x10\n\x0cLITE_RUNTIME\x10\x03*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08&\x10\'\"\x84\x02\n\x0eMessageOptions\x12&\n\x17message_set_wire_format\x18\x01 \x01(\x08:\x05\x66\x61lse\x12.\n\x1fno_standard_descriptor_accessor\x18\x02 \x01(\x08:\x05\x66\x61lse\x12\x19\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lse\x12\x11\n\tmap_entry\x18\x07 \x01(\x08\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08\x04\x10\x05J\x04\x08\x05\x10\x06J\x04\x08\x06\x10\x07J\x04\x08\x08\x10\tJ\x04\x08\t\x10\n\"\xbe\x03\n\x0c\x46ieldOptions\x12:\n\x05\x63type\x18\x01 \x01(\x0e\x32#.google.protobuf.FieldOptions.CType:\x06STRING\x12\x0e\n\x06packed\x18\x02 \x01(\x08\x12?\n\x06jstype\x18\x06 \x01(\x0e\x32$.google.protobuf.FieldOptions.JSType:\tJS_NORMAL\x12\x13\n\x04lazy\x18\x05 \x01(\x08:\x05\x66\x61lse\x12\x1e\n\x0funverified_lazy\x18\x0f \x01(\x08:\x05\x66\x61lse\x12\x19\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lse\x12\x13\n\x04weak\x18\n \x01(\x08:\x05\x66\x61lse\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption\"/\n\x05\x43Type\x12\n\n\x06STRING\x10\x00\x12\x08\n\x04\x43ORD\x10\x01\x12\x10\n\x0cSTRING_PIECE\x10\x02\"5\n\x06JSType\x12\r\n\tJS_NORMAL\x10\x00\x12\r\n\tJS_STRING\x10\x01\x12\r\n\tJS_NUMBER\x10\x02*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08\x04\x10\x05\"^\n\x0cOneofOptions\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\x93\x01\n\x0b\x45numOptions\x12\x13\n\x0b\x61llow_alias\x18\x02 \x01(\x08\x12\x19\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lse\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08\x05\x10\x06\"}\n\x10\x45numValueOptions\x12\x19\n\ndeprecated\x18\x01 \x01(\x08:\x05\x66\x61lse\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"{\n\x0eServiceOptions\x12\x19\n\ndeprecated\x18! \x01(\x08:\x05\x66\x61lse\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xad\x02\n\rMethodOptions\x12\x19\n\ndeprecated\x18! \x01(\x08:\x05\x66\x61lse\x12_\n\x11idempotency_level\x18\" \x01(\x0e\x32/.google.protobuf.MethodOptions.IdempotencyLevel:\x13IDEMPOTENCY_UNKNOWN\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption\"P\n\x10IdempotencyLevel\x12\x17\n\x13IDEMPOTENCY_UNKNOWN\x10\x00\x12\x13\n\x0fNO_SIDE_EFFECTS\x10\x01\x12\x0e\n\nIDEMPOTENT\x10\x02*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\x9e\x02\n\x13UninterpretedOption\x12;\n\x04name\x18\x02 \x03(\x0b\x32-.google.protobuf.UninterpretedOption.NamePart\x12\x18\n\x10identifier_value\x18\x03 \x01(\t\x12\x1a\n\x12positive_int_value\x18\x04 \x01(\x04\x12\x1a\n\x12negative_int_value\x18\x05 \x01(\x03\x12\x14\n\x0c\x64ouble_value\x18\x06 \x01(\x01\x12\x14\n\x0cstring_value\x18\x07 \x01(\x0c\x12\x17\n\x0f\x61ggregate_value\x18\x08 \x01(\t\x1a\x33\n\x08NamePart\x12\x11\n\tname_part\x18\x01 \x02(\t\x12\x14\n\x0cis_extension\x18\x02 \x02(\x08\"\xd5\x01\n\x0eSourceCodeInfo\x12:\n\x08location\x18\x01 \x03(\x0b\x32(.google.protobuf.SourceCodeInfo.Location\x1a\x86\x01\n\x08Location\x12\x10\n\x04path\x18\x01 \x03(\x05\x42\x02\x10\x01\x12\x10\n\x04span\x18\x02 \x03(\x05\x42\x02\x10\x01\x12\x18\n\x10leading_comments\x18\x03 \x01(\t\x12\x19\n\x11trailing_comments\x18\x04 \x01(\t\x12!\n\x19leading_detached_comments\x18\x06 \x03(\t\"\xa7\x01\n\x11GeneratedCodeInfo\x12\x41\n\nannotation\x18\x01 \x03(\x0b\x32-.google.protobuf.GeneratedCodeInfo.Annotation\x1aO\n\nAnnotation\x12\x10\n\x04path\x18\x01 \x03(\x05\x42\x02\x10\x01\x12\x13\n\x0bsource_file\x18\x02 \x01(\t\x12\r\n\x05\x62\x65gin\x18\x03 \x01(\x05\x12\x0b\n\x03\x65nd\x18\x04 \x01(\x05\x42~\n\x13\x63om.google.protobufB\x10\x44\x65scriptorProtosH\x01Z-google.golang.org/protobuf/types/descriptorpb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1aGoogle.Protobuf.Reflection' - ) -else: - DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n google/protobuf/descriptor.proto\x12\x0fgoogle.protobuf\"G\n\x11\x46ileDescriptorSet\x12\x32\n\x04\x66ile\x18\x01 \x03(\x0b\x32$.google.protobuf.FileDescriptorProto\"\xdb\x03\n\x13\x46ileDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07package\x18\x02 \x01(\t\x12\x12\n\ndependency\x18\x03 \x03(\t\x12\x19\n\x11public_dependency\x18\n \x03(\x05\x12\x17\n\x0fweak_dependency\x18\x0b \x03(\x05\x12\x36\n\x0cmessage_type\x18\x04 \x03(\x0b\x32 .google.protobuf.DescriptorProto\x12\x37\n\tenum_type\x18\x05 \x03(\x0b\x32$.google.protobuf.EnumDescriptorProto\x12\x38\n\x07service\x18\x06 \x03(\x0b\x32\'.google.protobuf.ServiceDescriptorProto\x12\x38\n\textension\x18\x07 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProto\x12-\n\x07options\x18\x08 \x01(\x0b\x32\x1c.google.protobuf.FileOptions\x12\x39\n\x10source_code_info\x18\t \x01(\x0b\x32\x1f.google.protobuf.SourceCodeInfo\x12\x0e\n\x06syntax\x18\x0c \x01(\t\"\xa9\x05\n\x0f\x44\x65scriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x34\n\x05\x66ield\x18\x02 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProto\x12\x38\n\textension\x18\x06 \x03(\x0b\x32%.google.protobuf.FieldDescriptorProto\x12\x35\n\x0bnested_type\x18\x03 \x03(\x0b\x32 .google.protobuf.DescriptorProto\x12\x37\n\tenum_type\x18\x04 \x03(\x0b\x32$.google.protobuf.EnumDescriptorProto\x12H\n\x0f\x65xtension_range\x18\x05 \x03(\x0b\x32/.google.protobuf.DescriptorProto.ExtensionRange\x12\x39\n\noneof_decl\x18\x08 \x03(\x0b\x32%.google.protobuf.OneofDescriptorProto\x12\x30\n\x07options\x18\x07 \x01(\x0b\x32\x1f.google.protobuf.MessageOptions\x12\x46\n\x0ereserved_range\x18\t \x03(\x0b\x32..google.protobuf.DescriptorProto.ReservedRange\x12\x15\n\rreserved_name\x18\n \x03(\t\x1a\x65\n\x0e\x45xtensionRange\x12\r\n\x05start\x18\x01 \x01(\x05\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x05\x12\x37\n\x07options\x18\x03 \x01(\x0b\x32&.google.protobuf.ExtensionRangeOptions\x1a+\n\rReservedRange\x12\r\n\x05start\x18\x01 \x01(\x05\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x05\"g\n\x15\x45xtensionRangeOptions\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xd5\x05\n\x14\x46ieldDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06number\x18\x03 \x01(\x05\x12:\n\x05label\x18\x04 \x01(\x0e\x32+.google.protobuf.FieldDescriptorProto.Label\x12\x38\n\x04type\x18\x05 \x01(\x0e\x32*.google.protobuf.FieldDescriptorProto.Type\x12\x11\n\ttype_name\x18\x06 \x01(\t\x12\x10\n\x08\x65xtendee\x18\x02 \x01(\t\x12\x15\n\rdefault_value\x18\x07 \x01(\t\x12\x13\n\x0boneof_index\x18\t \x01(\x05\x12\x11\n\tjson_name\x18\n \x01(\t\x12.\n\x07options\x18\x08 \x01(\x0b\x32\x1d.google.protobuf.FieldOptions\x12\x17\n\x0fproto3_optional\x18\x11 \x01(\x08\"\xb6\x02\n\x04Type\x12\x0f\n\x0bTYPE_DOUBLE\x10\x01\x12\x0e\n\nTYPE_FLOAT\x10\x02\x12\x0e\n\nTYPE_INT64\x10\x03\x12\x0f\n\x0bTYPE_UINT64\x10\x04\x12\x0e\n\nTYPE_INT32\x10\x05\x12\x10\n\x0cTYPE_FIXED64\x10\x06\x12\x10\n\x0cTYPE_FIXED32\x10\x07\x12\r\n\tTYPE_BOOL\x10\x08\x12\x0f\n\x0bTYPE_STRING\x10\t\x12\x0e\n\nTYPE_GROUP\x10\n\x12\x10\n\x0cTYPE_MESSAGE\x10\x0b\x12\x0e\n\nTYPE_BYTES\x10\x0c\x12\x0f\n\x0bTYPE_UINT32\x10\r\x12\r\n\tTYPE_ENUM\x10\x0e\x12\x11\n\rTYPE_SFIXED32\x10\x0f\x12\x11\n\rTYPE_SFIXED64\x10\x10\x12\x0f\n\x0bTYPE_SINT32\x10\x11\x12\x0f\n\x0bTYPE_SINT64\x10\x12\"C\n\x05Label\x12\x12\n\x0eLABEL_OPTIONAL\x10\x01\x12\x12\n\x0eLABEL_REQUIRED\x10\x02\x12\x12\n\x0eLABEL_REPEATED\x10\x03\"T\n\x14OneofDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12.\n\x07options\x18\x02 \x01(\x0b\x32\x1d.google.protobuf.OneofOptions\"\xa4\x02\n\x13\x45numDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x38\n\x05value\x18\x02 \x03(\x0b\x32).google.protobuf.EnumValueDescriptorProto\x12-\n\x07options\x18\x03 \x01(\x0b\x32\x1c.google.protobuf.EnumOptions\x12N\n\x0ereserved_range\x18\x04 \x03(\x0b\x32\x36.google.protobuf.EnumDescriptorProto.EnumReservedRange\x12\x15\n\rreserved_name\x18\x05 \x03(\t\x1a/\n\x11\x45numReservedRange\x12\r\n\x05start\x18\x01 \x01(\x05\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x05\"l\n\x18\x45numValueDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06number\x18\x02 \x01(\x05\x12\x32\n\x07options\x18\x03 \x01(\x0b\x32!.google.protobuf.EnumValueOptions\"\x90\x01\n\x16ServiceDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x36\n\x06method\x18\x02 \x03(\x0b\x32&.google.protobuf.MethodDescriptorProto\x12\x30\n\x07options\x18\x03 \x01(\x0b\x32\x1f.google.protobuf.ServiceOptions\"\xc1\x01\n\x15MethodDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x12\n\ninput_type\x18\x02 \x01(\t\x12\x13\n\x0boutput_type\x18\x03 \x01(\t\x12/\n\x07options\x18\x04 \x01(\x0b\x32\x1e.google.protobuf.MethodOptions\x12\x1f\n\x10\x63lient_streaming\x18\x05 \x01(\x08:\x05\x66\x61lse\x12\x1f\n\x10server_streaming\x18\x06 \x01(\x08:\x05\x66\x61lse\"\xa5\x06\n\x0b\x46ileOptions\x12\x14\n\x0cjava_package\x18\x01 \x01(\t\x12\x1c\n\x14java_outer_classname\x18\x08 \x01(\t\x12\"\n\x13java_multiple_files\x18\n \x01(\x08:\x05\x66\x61lse\x12)\n\x1djava_generate_equals_and_hash\x18\x14 \x01(\x08\x42\x02\x18\x01\x12%\n\x16java_string_check_utf8\x18\x1b \x01(\x08:\x05\x66\x61lse\x12\x46\n\x0coptimize_for\x18\t \x01(\x0e\x32).google.protobuf.FileOptions.OptimizeMode:\x05SPEED\x12\x12\n\ngo_package\x18\x0b \x01(\t\x12\"\n\x13\x63\x63_generic_services\x18\x10 \x01(\x08:\x05\x66\x61lse\x12$\n\x15java_generic_services\x18\x11 \x01(\x08:\x05\x66\x61lse\x12\"\n\x13py_generic_services\x18\x12 \x01(\x08:\x05\x66\x61lse\x12#\n\x14php_generic_services\x18* \x01(\x08:\x05\x66\x61lse\x12\x19\n\ndeprecated\x18\x17 \x01(\x08:\x05\x66\x61lse\x12\x1e\n\x10\x63\x63_enable_arenas\x18\x1f \x01(\x08:\x04true\x12\x19\n\x11objc_class_prefix\x18$ \x01(\t\x12\x18\n\x10\x63sharp_namespace\x18% \x01(\t\x12\x14\n\x0cswift_prefix\x18\' \x01(\t\x12\x18\n\x10php_class_prefix\x18( \x01(\t\x12\x15\n\rphp_namespace\x18) \x01(\t\x12\x1e\n\x16php_metadata_namespace\x18, \x01(\t\x12\x14\n\x0cruby_package\x18- \x01(\t\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption\":\n\x0cOptimizeMode\x12\t\n\x05SPEED\x10\x01\x12\r\n\tCODE_SIZE\x10\x02\x12\x10\n\x0cLITE_RUNTIME\x10\x03*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08&\x10\'\"\x84\x02\n\x0eMessageOptions\x12&\n\x17message_set_wire_format\x18\x01 \x01(\x08:\x05\x66\x61lse\x12.\n\x1fno_standard_descriptor_accessor\x18\x02 \x01(\x08:\x05\x66\x61lse\x12\x19\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lse\x12\x11\n\tmap_entry\x18\x07 \x01(\x08\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08\x04\x10\x05J\x04\x08\x05\x10\x06J\x04\x08\x06\x10\x07J\x04\x08\x08\x10\tJ\x04\x08\t\x10\n\"\xbe\x03\n\x0c\x46ieldOptions\x12:\n\x05\x63type\x18\x01 \x01(\x0e\x32#.google.protobuf.FieldOptions.CType:\x06STRING\x12\x0e\n\x06packed\x18\x02 \x01(\x08\x12?\n\x06jstype\x18\x06 \x01(\x0e\x32$.google.protobuf.FieldOptions.JSType:\tJS_NORMAL\x12\x13\n\x04lazy\x18\x05 \x01(\x08:\x05\x66\x61lse\x12\x1e\n\x0funverified_lazy\x18\x0f \x01(\x08:\x05\x66\x61lse\x12\x19\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lse\x12\x13\n\x04weak\x18\n \x01(\x08:\x05\x66\x61lse\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption\"/\n\x05\x43Type\x12\n\n\x06STRING\x10\x00\x12\x08\n\x04\x43ORD\x10\x01\x12\x10\n\x0cSTRING_PIECE\x10\x02\"5\n\x06JSType\x12\r\n\tJS_NORMAL\x10\x00\x12\r\n\tJS_STRING\x10\x01\x12\r\n\tJS_NUMBER\x10\x02*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08\x04\x10\x05\"^\n\x0cOneofOptions\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\x93\x01\n\x0b\x45numOptions\x12\x13\n\x0b\x61llow_alias\x18\x02 \x01(\x08\x12\x19\n\ndeprecated\x18\x03 \x01(\x08:\x05\x66\x61lse\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x04\x08\x05\x10\x06\"}\n\x10\x45numValueOptions\x12\x19\n\ndeprecated\x18\x01 \x01(\x08:\x05\x66\x61lse\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"{\n\x0eServiceOptions\x12\x19\n\ndeprecated\x18! \x01(\x08:\x05\x66\x61lse\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\xad\x02\n\rMethodOptions\x12\x19\n\ndeprecated\x18! \x01(\x08:\x05\x66\x61lse\x12_\n\x11idempotency_level\x18\" \x01(\x0e\x32/.google.protobuf.MethodOptions.IdempotencyLevel:\x13IDEMPOTENCY_UNKNOWN\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.google.protobuf.UninterpretedOption\"P\n\x10IdempotencyLevel\x12\x17\n\x13IDEMPOTENCY_UNKNOWN\x10\x00\x12\x13\n\x0fNO_SIDE_EFFECTS\x10\x01\x12\x0e\n\nIDEMPOTENT\x10\x02*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02\"\x9e\x02\n\x13UninterpretedOption\x12;\n\x04name\x18\x02 \x03(\x0b\x32-.google.protobuf.UninterpretedOption.NamePart\x12\x18\n\x10identifier_value\x18\x03 \x01(\t\x12\x1a\n\x12positive_int_value\x18\x04 \x01(\x04\x12\x1a\n\x12negative_int_value\x18\x05 \x01(\x03\x12\x14\n\x0c\x64ouble_value\x18\x06 \x01(\x01\x12\x14\n\x0cstring_value\x18\x07 \x01(\x0c\x12\x17\n\x0f\x61ggregate_value\x18\x08 \x01(\t\x1a\x33\n\x08NamePart\x12\x11\n\tname_part\x18\x01 \x02(\t\x12\x14\n\x0cis_extension\x18\x02 \x02(\x08\"\xd5\x01\n\x0eSourceCodeInfo\x12:\n\x08location\x18\x01 \x03(\x0b\x32(.google.protobuf.SourceCodeInfo.Location\x1a\x86\x01\n\x08Location\x12\x10\n\x04path\x18\x01 \x03(\x05\x42\x02\x10\x01\x12\x10\n\x04span\x18\x02 \x03(\x05\x42\x02\x10\x01\x12\x18\n\x10leading_comments\x18\x03 \x01(\t\x12\x19\n\x11trailing_comments\x18\x04 \x01(\t\x12!\n\x19leading_detached_comments\x18\x06 \x03(\t\"\xa7\x01\n\x11GeneratedCodeInfo\x12\x41\n\nannotation\x18\x01 \x03(\x0b\x32-.google.protobuf.GeneratedCodeInfo.Annotation\x1aO\n\nAnnotation\x12\x10\n\x04path\x18\x01 \x03(\x05\x42\x02\x10\x01\x12\x13\n\x0bsource_file\x18\x02 \x01(\t\x12\r\n\x05\x62\x65gin\x18\x03 \x01(\x05\x12\x0b\n\x03\x65nd\x18\x04 \x01(\x05\x42~\n\x13\x63om.google.protobufB\x10\x44\x65scriptorProtosH\x01Z-google.golang.org/protobuf/types/descriptorpb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1aGoogle.Protobuf.Reflection') - -if _descriptor._USE_C_DESCRIPTORS == False: - _FIELDDESCRIPTORPROTO_TYPE = _descriptor.EnumDescriptor( - name='Type', - full_name='google.protobuf.FieldDescriptorProto.Type', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='TYPE_DOUBLE', index=0, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_FLOAT', index=1, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_INT64', index=2, number=3, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_UINT64', index=3, number=4, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_INT32', index=4, number=5, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_FIXED64', index=5, number=6, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_FIXED32', index=6, number=7, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_BOOL', index=7, number=8, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_STRING', index=8, number=9, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_GROUP', index=9, number=10, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_MESSAGE', index=10, number=11, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_BYTES', index=11, number=12, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_UINT32', index=12, number=13, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_ENUM', index=13, number=14, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_SFIXED32', index=14, number=15, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_SFIXED64', index=15, number=16, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_SINT32', index=16, number=17, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='TYPE_SINT64', index=17, number=18, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - ) - _sym_db.RegisterEnumDescriptor(_FIELDDESCRIPTORPROTO_TYPE) - - _FIELDDESCRIPTORPROTO_LABEL = _descriptor.EnumDescriptor( - name='Label', - full_name='google.protobuf.FieldDescriptorProto.Label', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='LABEL_OPTIONAL', index=0, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='LABEL_REQUIRED', index=1, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='LABEL_REPEATED', index=2, number=3, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - ) - _sym_db.RegisterEnumDescriptor(_FIELDDESCRIPTORPROTO_LABEL) - - _FILEOPTIONS_OPTIMIZEMODE = _descriptor.EnumDescriptor( - name='OptimizeMode', - full_name='google.protobuf.FileOptions.OptimizeMode', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='SPEED', index=0, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='CODE_SIZE', index=1, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='LITE_RUNTIME', index=2, number=3, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - ) - _sym_db.RegisterEnumDescriptor(_FILEOPTIONS_OPTIMIZEMODE) - - _FIELDOPTIONS_CTYPE = _descriptor.EnumDescriptor( - name='CType', - full_name='google.protobuf.FieldOptions.CType', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='STRING', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='CORD', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='STRING_PIECE', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - ) - _sym_db.RegisterEnumDescriptor(_FIELDOPTIONS_CTYPE) - - _FIELDOPTIONS_JSTYPE = _descriptor.EnumDescriptor( - name='JSType', - full_name='google.protobuf.FieldOptions.JSType', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='JS_NORMAL', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='JS_STRING', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='JS_NUMBER', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - ) - _sym_db.RegisterEnumDescriptor(_FIELDOPTIONS_JSTYPE) - - _METHODOPTIONS_IDEMPOTENCYLEVEL = _descriptor.EnumDescriptor( - name='IdempotencyLevel', - full_name='google.protobuf.MethodOptions.IdempotencyLevel', - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name='IDEMPOTENCY_UNKNOWN', index=0, number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='NO_SIDE_EFFECTS', index=1, number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - _descriptor.EnumValueDescriptor( - name='IDEMPOTENT', index=2, number=2, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key), - ], - containing_type=None, - serialized_options=None, - ) - _sym_db.RegisterEnumDescriptor(_METHODOPTIONS_IDEMPOTENCYLEVEL) - - - _FILEDESCRIPTORSET = _descriptor.Descriptor( - name='FileDescriptorSet', - full_name='google.protobuf.FileDescriptorSet', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='file', full_name='google.protobuf.FileDescriptorSet.file', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - ) - - - _FILEDESCRIPTORPROTO = _descriptor.Descriptor( - name='FileDescriptorProto', - full_name='google.protobuf.FileDescriptorProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='google.protobuf.FileDescriptorProto.name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='package', full_name='google.protobuf.FileDescriptorProto.package', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='dependency', full_name='google.protobuf.FileDescriptorProto.dependency', index=2, - number=3, type=9, cpp_type=9, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='public_dependency', full_name='google.protobuf.FileDescriptorProto.public_dependency', index=3, - number=10, type=5, cpp_type=1, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='weak_dependency', full_name='google.protobuf.FileDescriptorProto.weak_dependency', index=4, - number=11, type=5, cpp_type=1, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='message_type', full_name='google.protobuf.FileDescriptorProto.message_type', index=5, - number=4, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='enum_type', full_name='google.protobuf.FileDescriptorProto.enum_type', index=6, - number=5, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='service', full_name='google.protobuf.FileDescriptorProto.service', index=7, - number=6, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='extension', full_name='google.protobuf.FileDescriptorProto.extension', index=8, - number=7, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='options', full_name='google.protobuf.FileDescriptorProto.options', index=9, - number=8, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='source_code_info', full_name='google.protobuf.FileDescriptorProto.source_code_info', index=10, - number=9, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='syntax', full_name='google.protobuf.FileDescriptorProto.syntax', index=11, - number=12, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - ) - - - _DESCRIPTORPROTO_EXTENSIONRANGE = _descriptor.Descriptor( - name='ExtensionRange', - full_name='google.protobuf.DescriptorProto.ExtensionRange', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='start', full_name='google.protobuf.DescriptorProto.ExtensionRange.start', index=0, - number=1, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='end', full_name='google.protobuf.DescriptorProto.ExtensionRange.end', index=1, - number=2, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='options', full_name='google.protobuf.DescriptorProto.ExtensionRange.options', index=2, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - ) - - _DESCRIPTORPROTO_RESERVEDRANGE = _descriptor.Descriptor( - name='ReservedRange', - full_name='google.protobuf.DescriptorProto.ReservedRange', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='start', full_name='google.protobuf.DescriptorProto.ReservedRange.start', index=0, - number=1, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='end', full_name='google.protobuf.DescriptorProto.ReservedRange.end', index=1, - number=2, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - ) - - _DESCRIPTORPROTO = _descriptor.Descriptor( - name='DescriptorProto', - full_name='google.protobuf.DescriptorProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='google.protobuf.DescriptorProto.name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='field', full_name='google.protobuf.DescriptorProto.field', index=1, - number=2, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='extension', full_name='google.protobuf.DescriptorProto.extension', index=2, - number=6, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='nested_type', full_name='google.protobuf.DescriptorProto.nested_type', index=3, - number=3, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='enum_type', full_name='google.protobuf.DescriptorProto.enum_type', index=4, - number=4, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='extension_range', full_name='google.protobuf.DescriptorProto.extension_range', index=5, - number=5, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='oneof_decl', full_name='google.protobuf.DescriptorProto.oneof_decl', index=6, - number=8, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='options', full_name='google.protobuf.DescriptorProto.options', index=7, - number=7, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='reserved_range', full_name='google.protobuf.DescriptorProto.reserved_range', index=8, - number=9, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='reserved_name', full_name='google.protobuf.DescriptorProto.reserved_name', index=9, - number=10, type=9, cpp_type=9, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[_DESCRIPTORPROTO_EXTENSIONRANGE, _DESCRIPTORPROTO_RESERVEDRANGE, ], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - ) - - - _EXTENSIONRANGEOPTIONS = _descriptor.Descriptor( - name='ExtensionRangeOptions', - full_name='google.protobuf.ExtensionRangeOptions', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='uninterpreted_option', full_name='google.protobuf.ExtensionRangeOptions.uninterpreted_option', index=0, - number=999, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=True, - syntax='proto2', - extension_ranges=[(1000, 536870912), ], - oneofs=[ - ], - ) - - - _FIELDDESCRIPTORPROTO = _descriptor.Descriptor( - name='FieldDescriptorProto', - full_name='google.protobuf.FieldDescriptorProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='google.protobuf.FieldDescriptorProto.name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='number', full_name='google.protobuf.FieldDescriptorProto.number', index=1, - number=3, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='label', full_name='google.protobuf.FieldDescriptorProto.label', index=2, - number=4, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=1, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='type', full_name='google.protobuf.FieldDescriptorProto.type', index=3, - number=5, type=14, cpp_type=8, label=1, - has_default_value=False, default_value=1, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='type_name', full_name='google.protobuf.FieldDescriptorProto.type_name', index=4, - number=6, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='extendee', full_name='google.protobuf.FieldDescriptorProto.extendee', index=5, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='default_value', full_name='google.protobuf.FieldDescriptorProto.default_value', index=6, - number=7, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='oneof_index', full_name='google.protobuf.FieldDescriptorProto.oneof_index', index=7, - number=9, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='json_name', full_name='google.protobuf.FieldDescriptorProto.json_name', index=8, - number=10, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='options', full_name='google.protobuf.FieldDescriptorProto.options', index=9, - number=8, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='proto3_optional', full_name='google.protobuf.FieldDescriptorProto.proto3_optional', index=10, - number=17, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - _FIELDDESCRIPTORPROTO_TYPE, - _FIELDDESCRIPTORPROTO_LABEL, - ], - serialized_options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - ) - - - _ONEOFDESCRIPTORPROTO = _descriptor.Descriptor( - name='OneofDescriptorProto', - full_name='google.protobuf.OneofDescriptorProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='google.protobuf.OneofDescriptorProto.name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='options', full_name='google.protobuf.OneofDescriptorProto.options', index=1, - number=2, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - ) - - - _ENUMDESCRIPTORPROTO_ENUMRESERVEDRANGE = _descriptor.Descriptor( - name='EnumReservedRange', - full_name='google.protobuf.EnumDescriptorProto.EnumReservedRange', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='start', full_name='google.protobuf.EnumDescriptorProto.EnumReservedRange.start', index=0, - number=1, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='end', full_name='google.protobuf.EnumDescriptorProto.EnumReservedRange.end', index=1, - number=2, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - ) - - _ENUMDESCRIPTORPROTO = _descriptor.Descriptor( - name='EnumDescriptorProto', - full_name='google.protobuf.EnumDescriptorProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='google.protobuf.EnumDescriptorProto.name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='value', full_name='google.protobuf.EnumDescriptorProto.value', index=1, - number=2, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='options', full_name='google.protobuf.EnumDescriptorProto.options', index=2, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='reserved_range', full_name='google.protobuf.EnumDescriptorProto.reserved_range', index=3, - number=4, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='reserved_name', full_name='google.protobuf.EnumDescriptorProto.reserved_name', index=4, - number=5, type=9, cpp_type=9, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[_ENUMDESCRIPTORPROTO_ENUMRESERVEDRANGE, ], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - ) - - - _ENUMVALUEDESCRIPTORPROTO = _descriptor.Descriptor( - name='EnumValueDescriptorProto', - full_name='google.protobuf.EnumValueDescriptorProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='google.protobuf.EnumValueDescriptorProto.name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='number', full_name='google.protobuf.EnumValueDescriptorProto.number', index=1, - number=2, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='options', full_name='google.protobuf.EnumValueDescriptorProto.options', index=2, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - ) - - - _SERVICEDESCRIPTORPROTO = _descriptor.Descriptor( - name='ServiceDescriptorProto', - full_name='google.protobuf.ServiceDescriptorProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='google.protobuf.ServiceDescriptorProto.name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='method', full_name='google.protobuf.ServiceDescriptorProto.method', index=1, - number=2, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='options', full_name='google.protobuf.ServiceDescriptorProto.options', index=2, - number=3, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - ) - - - _METHODDESCRIPTORPROTO = _descriptor.Descriptor( - name='MethodDescriptorProto', - full_name='google.protobuf.MethodDescriptorProto', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='google.protobuf.MethodDescriptorProto.name', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='input_type', full_name='google.protobuf.MethodDescriptorProto.input_type', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='output_type', full_name='google.protobuf.MethodDescriptorProto.output_type', index=2, - number=3, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='options', full_name='google.protobuf.MethodDescriptorProto.options', index=3, - number=4, type=11, cpp_type=10, label=1, - has_default_value=False, default_value=None, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='client_streaming', full_name='google.protobuf.MethodDescriptorProto.client_streaming', index=4, - number=5, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='server_streaming', full_name='google.protobuf.MethodDescriptorProto.server_streaming', index=5, - number=6, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - ) - - - _FILEOPTIONS = _descriptor.Descriptor( - name='FileOptions', - full_name='google.protobuf.FileOptions', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='java_package', full_name='google.protobuf.FileOptions.java_package', index=0, - number=1, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='java_outer_classname', full_name='google.protobuf.FileOptions.java_outer_classname', index=1, - number=8, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='java_multiple_files', full_name='google.protobuf.FileOptions.java_multiple_files', index=2, - number=10, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='java_generate_equals_and_hash', full_name='google.protobuf.FileOptions.java_generate_equals_and_hash', index=3, - number=20, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='java_string_check_utf8', full_name='google.protobuf.FileOptions.java_string_check_utf8', index=4, - number=27, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='optimize_for', full_name='google.protobuf.FileOptions.optimize_for', index=5, - number=9, type=14, cpp_type=8, label=1, - has_default_value=True, default_value=1, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='go_package', full_name='google.protobuf.FileOptions.go_package', index=6, - number=11, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='cc_generic_services', full_name='google.protobuf.FileOptions.cc_generic_services', index=7, - number=16, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='java_generic_services', full_name='google.protobuf.FileOptions.java_generic_services', index=8, - number=17, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='py_generic_services', full_name='google.protobuf.FileOptions.py_generic_services', index=9, - number=18, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='php_generic_services', full_name='google.protobuf.FileOptions.php_generic_services', index=10, - number=42, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='deprecated', full_name='google.protobuf.FileOptions.deprecated', index=11, - number=23, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='cc_enable_arenas', full_name='google.protobuf.FileOptions.cc_enable_arenas', index=12, - number=31, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=True, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='objc_class_prefix', full_name='google.protobuf.FileOptions.objc_class_prefix', index=13, - number=36, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='csharp_namespace', full_name='google.protobuf.FileOptions.csharp_namespace', index=14, - number=37, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='swift_prefix', full_name='google.protobuf.FileOptions.swift_prefix', index=15, - number=39, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='php_class_prefix', full_name='google.protobuf.FileOptions.php_class_prefix', index=16, - number=40, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='php_namespace', full_name='google.protobuf.FileOptions.php_namespace', index=17, - number=41, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='php_metadata_namespace', full_name='google.protobuf.FileOptions.php_metadata_namespace', index=18, - number=44, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='ruby_package', full_name='google.protobuf.FileOptions.ruby_package', index=19, - number=45, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='uninterpreted_option', full_name='google.protobuf.FileOptions.uninterpreted_option', index=20, - number=999, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - _FILEOPTIONS_OPTIMIZEMODE, - ], - serialized_options=None, - is_extendable=True, - syntax='proto2', - extension_ranges=[(1000, 536870912), ], - oneofs=[ - ], - ) - - - _MESSAGEOPTIONS = _descriptor.Descriptor( - name='MessageOptions', - full_name='google.protobuf.MessageOptions', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='message_set_wire_format', full_name='google.protobuf.MessageOptions.message_set_wire_format', index=0, - number=1, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='no_standard_descriptor_accessor', full_name='google.protobuf.MessageOptions.no_standard_descriptor_accessor', index=1, - number=2, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='deprecated', full_name='google.protobuf.MessageOptions.deprecated', index=2, - number=3, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='map_entry', full_name='google.protobuf.MessageOptions.map_entry', index=3, - number=7, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='uninterpreted_option', full_name='google.protobuf.MessageOptions.uninterpreted_option', index=4, - number=999, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=True, - syntax='proto2', - extension_ranges=[(1000, 536870912), ], - oneofs=[ - ], - ) - - - _FIELDOPTIONS = _descriptor.Descriptor( - name='FieldOptions', - full_name='google.protobuf.FieldOptions', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='ctype', full_name='google.protobuf.FieldOptions.ctype', index=0, - number=1, type=14, cpp_type=8, label=1, - has_default_value=True, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='packed', full_name='google.protobuf.FieldOptions.packed', index=1, - number=2, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='jstype', full_name='google.protobuf.FieldOptions.jstype', index=2, - number=6, type=14, cpp_type=8, label=1, - has_default_value=True, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='lazy', full_name='google.protobuf.FieldOptions.lazy', index=3, - number=5, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='unverified_lazy', full_name='google.protobuf.FieldOptions.unverified_lazy', index=4, - number=15, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='deprecated', full_name='google.protobuf.FieldOptions.deprecated', index=5, - number=3, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='weak', full_name='google.protobuf.FieldOptions.weak', index=6, - number=10, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='uninterpreted_option', full_name='google.protobuf.FieldOptions.uninterpreted_option', index=7, - number=999, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - _FIELDOPTIONS_CTYPE, - _FIELDOPTIONS_JSTYPE, - ], - serialized_options=None, - is_extendable=True, - syntax='proto2', - extension_ranges=[(1000, 536870912), ], - oneofs=[ - ], - ) - - - _ONEOFOPTIONS = _descriptor.Descriptor( - name='OneofOptions', - full_name='google.protobuf.OneofOptions', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='uninterpreted_option', full_name='google.protobuf.OneofOptions.uninterpreted_option', index=0, - number=999, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=True, - syntax='proto2', - extension_ranges=[(1000, 536870912), ], - oneofs=[ - ], - ) - - - _ENUMOPTIONS = _descriptor.Descriptor( - name='EnumOptions', - full_name='google.protobuf.EnumOptions', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='allow_alias', full_name='google.protobuf.EnumOptions.allow_alias', index=0, - number=2, type=8, cpp_type=7, label=1, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='deprecated', full_name='google.protobuf.EnumOptions.deprecated', index=1, - number=3, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='uninterpreted_option', full_name='google.protobuf.EnumOptions.uninterpreted_option', index=2, - number=999, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=True, - syntax='proto2', - extension_ranges=[(1000, 536870912), ], - oneofs=[ - ], - ) - - - _ENUMVALUEOPTIONS = _descriptor.Descriptor( - name='EnumValueOptions', - full_name='google.protobuf.EnumValueOptions', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='deprecated', full_name='google.protobuf.EnumValueOptions.deprecated', index=0, - number=1, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='uninterpreted_option', full_name='google.protobuf.EnumValueOptions.uninterpreted_option', index=1, - number=999, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=True, - syntax='proto2', - extension_ranges=[(1000, 536870912), ], - oneofs=[ - ], - ) - - - _SERVICEOPTIONS = _descriptor.Descriptor( - name='ServiceOptions', - full_name='google.protobuf.ServiceOptions', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='deprecated', full_name='google.protobuf.ServiceOptions.deprecated', index=0, - number=33, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='uninterpreted_option', full_name='google.protobuf.ServiceOptions.uninterpreted_option', index=1, - number=999, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=True, - syntax='proto2', - extension_ranges=[(1000, 536870912), ], - oneofs=[ - ], - ) - - - _METHODOPTIONS = _descriptor.Descriptor( - name='MethodOptions', - full_name='google.protobuf.MethodOptions', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='deprecated', full_name='google.protobuf.MethodOptions.deprecated', index=0, - number=33, type=8, cpp_type=7, label=1, - has_default_value=True, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='idempotency_level', full_name='google.protobuf.MethodOptions.idempotency_level', index=1, - number=34, type=14, cpp_type=8, label=1, - has_default_value=True, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='uninterpreted_option', full_name='google.protobuf.MethodOptions.uninterpreted_option', index=2, - number=999, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - _METHODOPTIONS_IDEMPOTENCYLEVEL, - ], - serialized_options=None, - is_extendable=True, - syntax='proto2', - extension_ranges=[(1000, 536870912), ], - oneofs=[ - ], - ) - - - _UNINTERPRETEDOPTION_NAMEPART = _descriptor.Descriptor( - name='NamePart', - full_name='google.protobuf.UninterpretedOption.NamePart', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='name_part', full_name='google.protobuf.UninterpretedOption.NamePart.name_part', index=0, - number=1, type=9, cpp_type=9, label=2, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='is_extension', full_name='google.protobuf.UninterpretedOption.NamePart.is_extension', index=1, - number=2, type=8, cpp_type=7, label=2, - has_default_value=False, default_value=False, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - ) - - _UNINTERPRETEDOPTION = _descriptor.Descriptor( - name='UninterpretedOption', - full_name='google.protobuf.UninterpretedOption', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='name', full_name='google.protobuf.UninterpretedOption.name', index=0, - number=2, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='identifier_value', full_name='google.protobuf.UninterpretedOption.identifier_value', index=1, - number=3, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='positive_int_value', full_name='google.protobuf.UninterpretedOption.positive_int_value', index=2, - number=4, type=4, cpp_type=4, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='negative_int_value', full_name='google.protobuf.UninterpretedOption.negative_int_value', index=3, - number=5, type=3, cpp_type=2, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='double_value', full_name='google.protobuf.UninterpretedOption.double_value', index=4, - number=6, type=1, cpp_type=5, label=1, - has_default_value=False, default_value=float(0), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='string_value', full_name='google.protobuf.UninterpretedOption.string_value', index=5, - number=7, type=12, cpp_type=9, label=1, - has_default_value=False, default_value=b"", - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='aggregate_value', full_name='google.protobuf.UninterpretedOption.aggregate_value', index=6, - number=8, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[_UNINTERPRETEDOPTION_NAMEPART, ], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - ) - - - _SOURCECODEINFO_LOCATION = _descriptor.Descriptor( - name='Location', - full_name='google.protobuf.SourceCodeInfo.Location', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='path', full_name='google.protobuf.SourceCodeInfo.Location.path', index=0, - number=1, type=5, cpp_type=1, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='span', full_name='google.protobuf.SourceCodeInfo.Location.span', index=1, - number=2, type=5, cpp_type=1, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='leading_comments', full_name='google.protobuf.SourceCodeInfo.Location.leading_comments', index=2, - number=3, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='trailing_comments', full_name='google.protobuf.SourceCodeInfo.Location.trailing_comments', index=3, - number=4, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='leading_detached_comments', full_name='google.protobuf.SourceCodeInfo.Location.leading_detached_comments', index=4, - number=6, type=9, cpp_type=9, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - ) - - _SOURCECODEINFO = _descriptor.Descriptor( - name='SourceCodeInfo', - full_name='google.protobuf.SourceCodeInfo', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='location', full_name='google.protobuf.SourceCodeInfo.location', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[_SOURCECODEINFO_LOCATION, ], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - ) - - - _GENERATEDCODEINFO_ANNOTATION = _descriptor.Descriptor( - name='Annotation', - full_name='google.protobuf.GeneratedCodeInfo.Annotation', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='path', full_name='google.protobuf.GeneratedCodeInfo.Annotation.path', index=0, - number=1, type=5, cpp_type=1, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='source_file', full_name='google.protobuf.GeneratedCodeInfo.Annotation.source_file', index=1, - number=2, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=b"".decode('utf-8'), - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='begin', full_name='google.protobuf.GeneratedCodeInfo.Annotation.begin', index=2, - number=3, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - _descriptor.FieldDescriptor( - name='end', full_name='google.protobuf.GeneratedCodeInfo.Annotation.end', index=3, - number=4, type=5, cpp_type=1, label=1, - has_default_value=False, default_value=0, - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - ) - - _GENERATEDCODEINFO = _descriptor.Descriptor( - name='GeneratedCodeInfo', - full_name='google.protobuf.GeneratedCodeInfo', - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name='annotation', full_name='google.protobuf.GeneratedCodeInfo.annotation', index=0, - number=1, type=11, cpp_type=10, label=3, - has_default_value=False, default_value=[], - message_type=None, enum_type=None, containing_type=None, - is_extension=False, extension_scope=None, - serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), - ], - extensions=[ - ], - nested_types=[_GENERATEDCODEINFO_ANNOTATION, ], - enum_types=[ - ], - serialized_options=None, - is_extendable=False, - syntax='proto2', - extension_ranges=[], - oneofs=[ - ], - ) - - _FILEDESCRIPTORSET.fields_by_name['file'].message_type = _FILEDESCRIPTORPROTO - _FILEDESCRIPTORPROTO.fields_by_name['message_type'].message_type = _DESCRIPTORPROTO - _FILEDESCRIPTORPROTO.fields_by_name['enum_type'].message_type = _ENUMDESCRIPTORPROTO - _FILEDESCRIPTORPROTO.fields_by_name['service'].message_type = _SERVICEDESCRIPTORPROTO - _FILEDESCRIPTORPROTO.fields_by_name['extension'].message_type = _FIELDDESCRIPTORPROTO - _FILEDESCRIPTORPROTO.fields_by_name['options'].message_type = _FILEOPTIONS - _FILEDESCRIPTORPROTO.fields_by_name['source_code_info'].message_type = _SOURCECODEINFO - _DESCRIPTORPROTO_EXTENSIONRANGE.fields_by_name['options'].message_type = _EXTENSIONRANGEOPTIONS - _DESCRIPTORPROTO_EXTENSIONRANGE.containing_type = _DESCRIPTORPROTO - _DESCRIPTORPROTO_RESERVEDRANGE.containing_type = _DESCRIPTORPROTO - _DESCRIPTORPROTO.fields_by_name['field'].message_type = _FIELDDESCRIPTORPROTO - _DESCRIPTORPROTO.fields_by_name['extension'].message_type = _FIELDDESCRIPTORPROTO - _DESCRIPTORPROTO.fields_by_name['nested_type'].message_type = _DESCRIPTORPROTO - _DESCRIPTORPROTO.fields_by_name['enum_type'].message_type = _ENUMDESCRIPTORPROTO - _DESCRIPTORPROTO.fields_by_name['extension_range'].message_type = _DESCRIPTORPROTO_EXTENSIONRANGE - _DESCRIPTORPROTO.fields_by_name['oneof_decl'].message_type = _ONEOFDESCRIPTORPROTO - _DESCRIPTORPROTO.fields_by_name['options'].message_type = _MESSAGEOPTIONS - _DESCRIPTORPROTO.fields_by_name['reserved_range'].message_type = _DESCRIPTORPROTO_RESERVEDRANGE - _EXTENSIONRANGEOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION - _FIELDDESCRIPTORPROTO.fields_by_name['label'].enum_type = _FIELDDESCRIPTORPROTO_LABEL - _FIELDDESCRIPTORPROTO.fields_by_name['type'].enum_type = _FIELDDESCRIPTORPROTO_TYPE - _FIELDDESCRIPTORPROTO.fields_by_name['options'].message_type = _FIELDOPTIONS - _FIELDDESCRIPTORPROTO_TYPE.containing_type = _FIELDDESCRIPTORPROTO - _FIELDDESCRIPTORPROTO_LABEL.containing_type = _FIELDDESCRIPTORPROTO - _ONEOFDESCRIPTORPROTO.fields_by_name['options'].message_type = _ONEOFOPTIONS - _ENUMDESCRIPTORPROTO_ENUMRESERVEDRANGE.containing_type = _ENUMDESCRIPTORPROTO - _ENUMDESCRIPTORPROTO.fields_by_name['value'].message_type = _ENUMVALUEDESCRIPTORPROTO - _ENUMDESCRIPTORPROTO.fields_by_name['options'].message_type = _ENUMOPTIONS - _ENUMDESCRIPTORPROTO.fields_by_name['reserved_range'].message_type = _ENUMDESCRIPTORPROTO_ENUMRESERVEDRANGE - _ENUMVALUEDESCRIPTORPROTO.fields_by_name['options'].message_type = _ENUMVALUEOPTIONS - _SERVICEDESCRIPTORPROTO.fields_by_name['method'].message_type = _METHODDESCRIPTORPROTO - _SERVICEDESCRIPTORPROTO.fields_by_name['options'].message_type = _SERVICEOPTIONS - _METHODDESCRIPTORPROTO.fields_by_name['options'].message_type = _METHODOPTIONS - _FILEOPTIONS.fields_by_name['optimize_for'].enum_type = _FILEOPTIONS_OPTIMIZEMODE - _FILEOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION - _FILEOPTIONS_OPTIMIZEMODE.containing_type = _FILEOPTIONS - _MESSAGEOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION - _FIELDOPTIONS.fields_by_name['ctype'].enum_type = _FIELDOPTIONS_CTYPE - _FIELDOPTIONS.fields_by_name['jstype'].enum_type = _FIELDOPTIONS_JSTYPE - _FIELDOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION - _FIELDOPTIONS_CTYPE.containing_type = _FIELDOPTIONS - _FIELDOPTIONS_JSTYPE.containing_type = _FIELDOPTIONS - _ONEOFOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION - _ENUMOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION - _ENUMVALUEOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION - _SERVICEOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION - _METHODOPTIONS.fields_by_name['idempotency_level'].enum_type = _METHODOPTIONS_IDEMPOTENCYLEVEL - _METHODOPTIONS.fields_by_name['uninterpreted_option'].message_type = _UNINTERPRETEDOPTION - _METHODOPTIONS_IDEMPOTENCYLEVEL.containing_type = _METHODOPTIONS - _UNINTERPRETEDOPTION_NAMEPART.containing_type = _UNINTERPRETEDOPTION - _UNINTERPRETEDOPTION.fields_by_name['name'].message_type = _UNINTERPRETEDOPTION_NAMEPART - _SOURCECODEINFO_LOCATION.containing_type = _SOURCECODEINFO - _SOURCECODEINFO.fields_by_name['location'].message_type = _SOURCECODEINFO_LOCATION - _GENERATEDCODEINFO_ANNOTATION.containing_type = _GENERATEDCODEINFO - _GENERATEDCODEINFO.fields_by_name['annotation'].message_type = _GENERATEDCODEINFO_ANNOTATION - DESCRIPTOR.message_types_by_name['FileDescriptorSet'] = _FILEDESCRIPTORSET - DESCRIPTOR.message_types_by_name['FileDescriptorProto'] = _FILEDESCRIPTORPROTO - DESCRIPTOR.message_types_by_name['DescriptorProto'] = _DESCRIPTORPROTO - DESCRIPTOR.message_types_by_name['ExtensionRangeOptions'] = _EXTENSIONRANGEOPTIONS - DESCRIPTOR.message_types_by_name['FieldDescriptorProto'] = _FIELDDESCRIPTORPROTO - DESCRIPTOR.message_types_by_name['OneofDescriptorProto'] = _ONEOFDESCRIPTORPROTO - DESCRIPTOR.message_types_by_name['EnumDescriptorProto'] = _ENUMDESCRIPTORPROTO - DESCRIPTOR.message_types_by_name['EnumValueDescriptorProto'] = _ENUMVALUEDESCRIPTORPROTO - DESCRIPTOR.message_types_by_name['ServiceDescriptorProto'] = _SERVICEDESCRIPTORPROTO - DESCRIPTOR.message_types_by_name['MethodDescriptorProto'] = _METHODDESCRIPTORPROTO - DESCRIPTOR.message_types_by_name['FileOptions'] = _FILEOPTIONS - DESCRIPTOR.message_types_by_name['MessageOptions'] = _MESSAGEOPTIONS - DESCRIPTOR.message_types_by_name['FieldOptions'] = _FIELDOPTIONS - DESCRIPTOR.message_types_by_name['OneofOptions'] = _ONEOFOPTIONS - DESCRIPTOR.message_types_by_name['EnumOptions'] = _ENUMOPTIONS - DESCRIPTOR.message_types_by_name['EnumValueOptions'] = _ENUMVALUEOPTIONS - DESCRIPTOR.message_types_by_name['ServiceOptions'] = _SERVICEOPTIONS - DESCRIPTOR.message_types_by_name['MethodOptions'] = _METHODOPTIONS - DESCRIPTOR.message_types_by_name['UninterpretedOption'] = _UNINTERPRETEDOPTION - DESCRIPTOR.message_types_by_name['SourceCodeInfo'] = _SOURCECODEINFO - DESCRIPTOR.message_types_by_name['GeneratedCodeInfo'] = _GENERATEDCODEINFO - _sym_db.RegisterFileDescriptor(DESCRIPTOR) - -else: - _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.descriptor_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - _FILEDESCRIPTORSET._serialized_start=53 - _FILEDESCRIPTORSET._serialized_end=124 - _FILEDESCRIPTORPROTO._serialized_start=127 - _FILEDESCRIPTORPROTO._serialized_end=602 - _DESCRIPTORPROTO._serialized_start=605 - _DESCRIPTORPROTO._serialized_end=1286 - _DESCRIPTORPROTO_EXTENSIONRANGE._serialized_start=1140 - _DESCRIPTORPROTO_EXTENSIONRANGE._serialized_end=1241 - _DESCRIPTORPROTO_RESERVEDRANGE._serialized_start=1243 - _DESCRIPTORPROTO_RESERVEDRANGE._serialized_end=1286 - _EXTENSIONRANGEOPTIONS._serialized_start=1288 - _EXTENSIONRANGEOPTIONS._serialized_end=1391 - _FIELDDESCRIPTORPROTO._serialized_start=1394 - _FIELDDESCRIPTORPROTO._serialized_end=2119 - _FIELDDESCRIPTORPROTO_TYPE._serialized_start=1740 - _FIELDDESCRIPTORPROTO_TYPE._serialized_end=2050 - _FIELDDESCRIPTORPROTO_LABEL._serialized_start=2052 - _FIELDDESCRIPTORPROTO_LABEL._serialized_end=2119 - _ONEOFDESCRIPTORPROTO._serialized_start=2121 - _ONEOFDESCRIPTORPROTO._serialized_end=2205 - _ENUMDESCRIPTORPROTO._serialized_start=2208 - _ENUMDESCRIPTORPROTO._serialized_end=2500 - _ENUMDESCRIPTORPROTO_ENUMRESERVEDRANGE._serialized_start=2453 - _ENUMDESCRIPTORPROTO_ENUMRESERVEDRANGE._serialized_end=2500 - _ENUMVALUEDESCRIPTORPROTO._serialized_start=2502 - _ENUMVALUEDESCRIPTORPROTO._serialized_end=2610 - _SERVICEDESCRIPTORPROTO._serialized_start=2613 - _SERVICEDESCRIPTORPROTO._serialized_end=2757 - _METHODDESCRIPTORPROTO._serialized_start=2760 - _METHODDESCRIPTORPROTO._serialized_end=2953 - _FILEOPTIONS._serialized_start=2956 - _FILEOPTIONS._serialized_end=3761 - _FILEOPTIONS_OPTIMIZEMODE._serialized_start=3686 - _FILEOPTIONS_OPTIMIZEMODE._serialized_end=3744 - _MESSAGEOPTIONS._serialized_start=3764 - _MESSAGEOPTIONS._serialized_end=4024 - _FIELDOPTIONS._serialized_start=4027 - _FIELDOPTIONS._serialized_end=4473 - _FIELDOPTIONS_CTYPE._serialized_start=4354 - _FIELDOPTIONS_CTYPE._serialized_end=4401 - _FIELDOPTIONS_JSTYPE._serialized_start=4403 - _FIELDOPTIONS_JSTYPE._serialized_end=4456 - _ONEOFOPTIONS._serialized_start=4475 - _ONEOFOPTIONS._serialized_end=4569 - _ENUMOPTIONS._serialized_start=4572 - _ENUMOPTIONS._serialized_end=4719 - _ENUMVALUEOPTIONS._serialized_start=4721 - _ENUMVALUEOPTIONS._serialized_end=4846 - _SERVICEOPTIONS._serialized_start=4848 - _SERVICEOPTIONS._serialized_end=4971 - _METHODOPTIONS._serialized_start=4974 - _METHODOPTIONS._serialized_end=5275 - _METHODOPTIONS_IDEMPOTENCYLEVEL._serialized_start=5184 - _METHODOPTIONS_IDEMPOTENCYLEVEL._serialized_end=5264 - _UNINTERPRETEDOPTION._serialized_start=5278 - _UNINTERPRETEDOPTION._serialized_end=5564 - _UNINTERPRETEDOPTION_NAMEPART._serialized_start=5513 - _UNINTERPRETEDOPTION_NAMEPART._serialized_end=5564 - _SOURCECODEINFO._serialized_start=5567 - _SOURCECODEINFO._serialized_end=5780 - _SOURCECODEINFO_LOCATION._serialized_start=5646 - _SOURCECODEINFO_LOCATION._serialized_end=5780 - _GENERATEDCODEINFO._serialized_start=5783 - _GENERATEDCODEINFO._serialized_end=5950 - _GENERATEDCODEINFO_ANNOTATION._serialized_start=5871 - _GENERATEDCODEINFO_ANNOTATION._serialized_end=5950 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/descriptor_pool.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/descriptor_pool.py deleted file mode 100644 index 911372a8b0..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/descriptor_pool.py +++ /dev/null @@ -1,1295 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Provides DescriptorPool to use as a container for proto2 descriptors. - -The DescriptorPool is used in conjection with a DescriptorDatabase to maintain -a collection of protocol buffer descriptors for use when dynamically creating -message types at runtime. - -For most applications protocol buffers should be used via modules generated by -the protocol buffer compiler tool. This should only be used when the type of -protocol buffers used in an application or library cannot be predetermined. - -Below is a straightforward example on how to use this class:: - - pool = DescriptorPool() - file_descriptor_protos = [ ... ] - for file_descriptor_proto in file_descriptor_protos: - pool.Add(file_descriptor_proto) - my_message_descriptor = pool.FindMessageTypeByName('some.package.MessageType') - -The message descriptor can be used in conjunction with the message_factory -module in order to create a protocol buffer class that can be encoded and -decoded. - -If you want to get a Python class for the specified proto, use the -helper functions inside google.protobuf.message_factory -directly instead of this class. -""" - -__author__ = 'matthewtoia@google.com (Matt Toia)' - -import collections -import warnings - -from google.protobuf import descriptor -from google.protobuf import descriptor_database -from google.protobuf import text_encoding - - -_USE_C_DESCRIPTORS = descriptor._USE_C_DESCRIPTORS # pylint: disable=protected-access - - -def _Deprecated(func): - """Mark functions as deprecated.""" - - def NewFunc(*args, **kwargs): - warnings.warn( - 'Call to deprecated function %s(). Note: Do add unlinked descriptors ' - 'to descriptor_pool is wrong. Use Add() or AddSerializedFile() ' - 'instead.' % func.__name__, - category=DeprecationWarning) - return func(*args, **kwargs) - NewFunc.__name__ = func.__name__ - NewFunc.__doc__ = func.__doc__ - NewFunc.__dict__.update(func.__dict__) - return NewFunc - - -def _NormalizeFullyQualifiedName(name): - """Remove leading period from fully-qualified type name. - - Due to b/13860351 in descriptor_database.py, types in the root namespace are - generated with a leading period. This function removes that prefix. - - Args: - name (str): The fully-qualified symbol name. - - Returns: - str: The normalized fully-qualified symbol name. - """ - return name.lstrip('.') - - -def _OptionsOrNone(descriptor_proto): - """Returns the value of the field `options`, or None if it is not set.""" - if descriptor_proto.HasField('options'): - return descriptor_proto.options - else: - return None - - -def _IsMessageSetExtension(field): - return (field.is_extension and - field.containing_type.has_options and - field.containing_type.GetOptions().message_set_wire_format and - field.type == descriptor.FieldDescriptor.TYPE_MESSAGE and - field.label == descriptor.FieldDescriptor.LABEL_OPTIONAL) - - -class DescriptorPool(object): - """A collection of protobufs dynamically constructed by descriptor protos.""" - - if _USE_C_DESCRIPTORS: - - def __new__(cls, descriptor_db=None): - # pylint: disable=protected-access - return descriptor._message.DescriptorPool(descriptor_db) - - def __init__(self, descriptor_db=None): - """Initializes a Pool of proto buffs. - - The descriptor_db argument to the constructor is provided to allow - specialized file descriptor proto lookup code to be triggered on demand. An - example would be an implementation which will read and compile a file - specified in a call to FindFileByName() and not require the call to Add() - at all. Results from this database will be cached internally here as well. - - Args: - descriptor_db: A secondary source of file descriptors. - """ - - self._internal_db = descriptor_database.DescriptorDatabase() - self._descriptor_db = descriptor_db - self._descriptors = {} - self._enum_descriptors = {} - self._service_descriptors = {} - self._file_descriptors = {} - self._toplevel_extensions = {} - # TODO(jieluo): Remove _file_desc_by_toplevel_extension after - # maybe year 2020 for compatibility issue (with 3.4.1 only). - self._file_desc_by_toplevel_extension = {} - self._top_enum_values = {} - # We store extensions in two two-level mappings: The first key is the - # descriptor of the message being extended, the second key is the extension - # full name or its tag number. - self._extensions_by_name = collections.defaultdict(dict) - self._extensions_by_number = collections.defaultdict(dict) - - def _CheckConflictRegister(self, desc, desc_name, file_name): - """Check if the descriptor name conflicts with another of the same name. - - Args: - desc: Descriptor of a message, enum, service, extension or enum value. - desc_name (str): the full name of desc. - file_name (str): The file name of descriptor. - """ - for register, descriptor_type in [ - (self._descriptors, descriptor.Descriptor), - (self._enum_descriptors, descriptor.EnumDescriptor), - (self._service_descriptors, descriptor.ServiceDescriptor), - (self._toplevel_extensions, descriptor.FieldDescriptor), - (self._top_enum_values, descriptor.EnumValueDescriptor)]: - if desc_name in register: - old_desc = register[desc_name] - if isinstance(old_desc, descriptor.EnumValueDescriptor): - old_file = old_desc.type.file.name - else: - old_file = old_desc.file.name - - if not isinstance(desc, descriptor_type) or ( - old_file != file_name): - error_msg = ('Conflict register for file "' + file_name + - '": ' + desc_name + - ' is already defined in file "' + - old_file + '". Please fix the conflict by adding ' - 'package name on the proto file, or use different ' - 'name for the duplication.') - if isinstance(desc, descriptor.EnumValueDescriptor): - error_msg += ('\nNote: enum values appear as ' - 'siblings of the enum type instead of ' - 'children of it.') - - raise TypeError(error_msg) - - return - - def Add(self, file_desc_proto): - """Adds the FileDescriptorProto and its types to this pool. - - Args: - file_desc_proto (FileDescriptorProto): The file descriptor to add. - """ - - self._internal_db.Add(file_desc_proto) - - def AddSerializedFile(self, serialized_file_desc_proto): - """Adds the FileDescriptorProto and its types to this pool. - - Args: - serialized_file_desc_proto (bytes): A bytes string, serialization of the - :class:`FileDescriptorProto` to add. - - Returns: - FileDescriptor: Descriptor for the added file. - """ - - # pylint: disable=g-import-not-at-top - from google.protobuf import descriptor_pb2 - file_desc_proto = descriptor_pb2.FileDescriptorProto.FromString( - serialized_file_desc_proto) - file_desc = self._ConvertFileProtoToFileDescriptor(file_desc_proto) - file_desc.serialized_pb = serialized_file_desc_proto - return file_desc - - # Add Descriptor to descriptor pool is dreprecated. Please use Add() - # or AddSerializedFile() to add a FileDescriptorProto instead. - @_Deprecated - def AddDescriptor(self, desc): - self._AddDescriptor(desc) - - # Never call this method. It is for internal usage only. - def _AddDescriptor(self, desc): - """Adds a Descriptor to the pool, non-recursively. - - If the Descriptor contains nested messages or enums, the caller must - explicitly register them. This method also registers the FileDescriptor - associated with the message. - - Args: - desc: A Descriptor. - """ - if not isinstance(desc, descriptor.Descriptor): - raise TypeError('Expected instance of descriptor.Descriptor.') - - self._CheckConflictRegister(desc, desc.full_name, desc.file.name) - - self._descriptors[desc.full_name] = desc - self._AddFileDescriptor(desc.file) - - # Add EnumDescriptor to descriptor pool is dreprecated. Please use Add() - # or AddSerializedFile() to add a FileDescriptorProto instead. - @_Deprecated - def AddEnumDescriptor(self, enum_desc): - self._AddEnumDescriptor(enum_desc) - - # Never call this method. It is for internal usage only. - def _AddEnumDescriptor(self, enum_desc): - """Adds an EnumDescriptor to the pool. - - This method also registers the FileDescriptor associated with the enum. - - Args: - enum_desc: An EnumDescriptor. - """ - - if not isinstance(enum_desc, descriptor.EnumDescriptor): - raise TypeError('Expected instance of descriptor.EnumDescriptor.') - - file_name = enum_desc.file.name - self._CheckConflictRegister(enum_desc, enum_desc.full_name, file_name) - self._enum_descriptors[enum_desc.full_name] = enum_desc - - # Top enum values need to be indexed. - # Count the number of dots to see whether the enum is toplevel or nested - # in a message. We cannot use enum_desc.containing_type at this stage. - if enum_desc.file.package: - top_level = (enum_desc.full_name.count('.') - - enum_desc.file.package.count('.') == 1) - else: - top_level = enum_desc.full_name.count('.') == 0 - if top_level: - file_name = enum_desc.file.name - package = enum_desc.file.package - for enum_value in enum_desc.values: - full_name = _NormalizeFullyQualifiedName( - '.'.join((package, enum_value.name))) - self._CheckConflictRegister(enum_value, full_name, file_name) - self._top_enum_values[full_name] = enum_value - self._AddFileDescriptor(enum_desc.file) - - # Add ServiceDescriptor to descriptor pool is dreprecated. Please use Add() - # or AddSerializedFile() to add a FileDescriptorProto instead. - @_Deprecated - def AddServiceDescriptor(self, service_desc): - self._AddServiceDescriptor(service_desc) - - # Never call this method. It is for internal usage only. - def _AddServiceDescriptor(self, service_desc): - """Adds a ServiceDescriptor to the pool. - - Args: - service_desc: A ServiceDescriptor. - """ - - if not isinstance(service_desc, descriptor.ServiceDescriptor): - raise TypeError('Expected instance of descriptor.ServiceDescriptor.') - - self._CheckConflictRegister(service_desc, service_desc.full_name, - service_desc.file.name) - self._service_descriptors[service_desc.full_name] = service_desc - - # Add ExtensionDescriptor to descriptor pool is dreprecated. Please use Add() - # or AddSerializedFile() to add a FileDescriptorProto instead. - @_Deprecated - def AddExtensionDescriptor(self, extension): - self._AddExtensionDescriptor(extension) - - # Never call this method. It is for internal usage only. - def _AddExtensionDescriptor(self, extension): - """Adds a FieldDescriptor describing an extension to the pool. - - Args: - extension: A FieldDescriptor. - - Raises: - AssertionError: when another extension with the same number extends the - same message. - TypeError: when the specified extension is not a - descriptor.FieldDescriptor. - """ - if not (isinstance(extension, descriptor.FieldDescriptor) and - extension.is_extension): - raise TypeError('Expected an extension descriptor.') - - if extension.extension_scope is None: - self._toplevel_extensions[extension.full_name] = extension - - try: - existing_desc = self._extensions_by_number[ - extension.containing_type][extension.number] - except KeyError: - pass - else: - if extension is not existing_desc: - raise AssertionError( - 'Extensions "%s" and "%s" both try to extend message type "%s" ' - 'with field number %d.' % - (extension.full_name, existing_desc.full_name, - extension.containing_type.full_name, extension.number)) - - self._extensions_by_number[extension.containing_type][ - extension.number] = extension - self._extensions_by_name[extension.containing_type][ - extension.full_name] = extension - - # Also register MessageSet extensions with the type name. - if _IsMessageSetExtension(extension): - self._extensions_by_name[extension.containing_type][ - extension.message_type.full_name] = extension - - @_Deprecated - def AddFileDescriptor(self, file_desc): - self._InternalAddFileDescriptor(file_desc) - - # Never call this method. It is for internal usage only. - def _InternalAddFileDescriptor(self, file_desc): - """Adds a FileDescriptor to the pool, non-recursively. - - If the FileDescriptor contains messages or enums, the caller must explicitly - register them. - - Args: - file_desc: A FileDescriptor. - """ - - self._AddFileDescriptor(file_desc) - # TODO(jieluo): This is a temporary solution for FieldDescriptor.file. - # FieldDescriptor.file is added in code gen. Remove this solution after - # maybe 2020 for compatibility reason (with 3.4.1 only). - for extension in file_desc.extensions_by_name.values(): - self._file_desc_by_toplevel_extension[ - extension.full_name] = file_desc - - def _AddFileDescriptor(self, file_desc): - """Adds a FileDescriptor to the pool, non-recursively. - - If the FileDescriptor contains messages or enums, the caller must explicitly - register them. - - Args: - file_desc: A FileDescriptor. - """ - - if not isinstance(file_desc, descriptor.FileDescriptor): - raise TypeError('Expected instance of descriptor.FileDescriptor.') - self._file_descriptors[file_desc.name] = file_desc - - def FindFileByName(self, file_name): - """Gets a FileDescriptor by file name. - - Args: - file_name (str): The path to the file to get a descriptor for. - - Returns: - FileDescriptor: The descriptor for the named file. - - Raises: - KeyError: if the file cannot be found in the pool. - """ - - try: - return self._file_descriptors[file_name] - except KeyError: - pass - - try: - file_proto = self._internal_db.FindFileByName(file_name) - except KeyError as error: - if self._descriptor_db: - file_proto = self._descriptor_db.FindFileByName(file_name) - else: - raise error - if not file_proto: - raise KeyError('Cannot find a file named %s' % file_name) - return self._ConvertFileProtoToFileDescriptor(file_proto) - - def FindFileContainingSymbol(self, symbol): - """Gets the FileDescriptor for the file containing the specified symbol. - - Args: - symbol (str): The name of the symbol to search for. - - Returns: - FileDescriptor: Descriptor for the file that contains the specified - symbol. - - Raises: - KeyError: if the file cannot be found in the pool. - """ - - symbol = _NormalizeFullyQualifiedName(symbol) - try: - return self._InternalFindFileContainingSymbol(symbol) - except KeyError: - pass - - try: - # Try fallback database. Build and find again if possible. - self._FindFileContainingSymbolInDb(symbol) - return self._InternalFindFileContainingSymbol(symbol) - except KeyError: - raise KeyError('Cannot find a file containing %s' % symbol) - - def _InternalFindFileContainingSymbol(self, symbol): - """Gets the already built FileDescriptor containing the specified symbol. - - Args: - symbol (str): The name of the symbol to search for. - - Returns: - FileDescriptor: Descriptor for the file that contains the specified - symbol. - - Raises: - KeyError: if the file cannot be found in the pool. - """ - try: - return self._descriptors[symbol].file - except KeyError: - pass - - try: - return self._enum_descriptors[symbol].file - except KeyError: - pass - - try: - return self._service_descriptors[symbol].file - except KeyError: - pass - - try: - return self._top_enum_values[symbol].type.file - except KeyError: - pass - - try: - return self._file_desc_by_toplevel_extension[symbol] - except KeyError: - pass - - # Try fields, enum values and nested extensions inside a message. - top_name, _, sub_name = symbol.rpartition('.') - try: - message = self.FindMessageTypeByName(top_name) - assert (sub_name in message.extensions_by_name or - sub_name in message.fields_by_name or - sub_name in message.enum_values_by_name) - return message.file - except (KeyError, AssertionError): - raise KeyError('Cannot find a file containing %s' % symbol) - - def FindMessageTypeByName(self, full_name): - """Loads the named descriptor from the pool. - - Args: - full_name (str): The full name of the descriptor to load. - - Returns: - Descriptor: The descriptor for the named type. - - Raises: - KeyError: if the message cannot be found in the pool. - """ - - full_name = _NormalizeFullyQualifiedName(full_name) - if full_name not in self._descriptors: - self._FindFileContainingSymbolInDb(full_name) - return self._descriptors[full_name] - - def FindEnumTypeByName(self, full_name): - """Loads the named enum descriptor from the pool. - - Args: - full_name (str): The full name of the enum descriptor to load. - - Returns: - EnumDescriptor: The enum descriptor for the named type. - - Raises: - KeyError: if the enum cannot be found in the pool. - """ - - full_name = _NormalizeFullyQualifiedName(full_name) - if full_name not in self._enum_descriptors: - self._FindFileContainingSymbolInDb(full_name) - return self._enum_descriptors[full_name] - - def FindFieldByName(self, full_name): - """Loads the named field descriptor from the pool. - - Args: - full_name (str): The full name of the field descriptor to load. - - Returns: - FieldDescriptor: The field descriptor for the named field. - - Raises: - KeyError: if the field cannot be found in the pool. - """ - full_name = _NormalizeFullyQualifiedName(full_name) - message_name, _, field_name = full_name.rpartition('.') - message_descriptor = self.FindMessageTypeByName(message_name) - return message_descriptor.fields_by_name[field_name] - - def FindOneofByName(self, full_name): - """Loads the named oneof descriptor from the pool. - - Args: - full_name (str): The full name of the oneof descriptor to load. - - Returns: - OneofDescriptor: The oneof descriptor for the named oneof. - - Raises: - KeyError: if the oneof cannot be found in the pool. - """ - full_name = _NormalizeFullyQualifiedName(full_name) - message_name, _, oneof_name = full_name.rpartition('.') - message_descriptor = self.FindMessageTypeByName(message_name) - return message_descriptor.oneofs_by_name[oneof_name] - - def FindExtensionByName(self, full_name): - """Loads the named extension descriptor from the pool. - - Args: - full_name (str): The full name of the extension descriptor to load. - - Returns: - FieldDescriptor: The field descriptor for the named extension. - - Raises: - KeyError: if the extension cannot be found in the pool. - """ - full_name = _NormalizeFullyQualifiedName(full_name) - try: - # The proto compiler does not give any link between the FileDescriptor - # and top-level extensions unless the FileDescriptorProto is added to - # the DescriptorDatabase, but this can impact memory usage. - # So we registered these extensions by name explicitly. - return self._toplevel_extensions[full_name] - except KeyError: - pass - message_name, _, extension_name = full_name.rpartition('.') - try: - # Most extensions are nested inside a message. - scope = self.FindMessageTypeByName(message_name) - except KeyError: - # Some extensions are defined at file scope. - scope = self._FindFileContainingSymbolInDb(full_name) - return scope.extensions_by_name[extension_name] - - def FindExtensionByNumber(self, message_descriptor, number): - """Gets the extension of the specified message with the specified number. - - Extensions have to be registered to this pool by calling :func:`Add` or - :func:`AddExtensionDescriptor`. - - Args: - message_descriptor (Descriptor): descriptor of the extended message. - number (int): Number of the extension field. - - Returns: - FieldDescriptor: The descriptor for the extension. - - Raises: - KeyError: when no extension with the given number is known for the - specified message. - """ - try: - return self._extensions_by_number[message_descriptor][number] - except KeyError: - self._TryLoadExtensionFromDB(message_descriptor, number) - return self._extensions_by_number[message_descriptor][number] - - def FindAllExtensions(self, message_descriptor): - """Gets all the known extensions of a given message. - - Extensions have to be registered to this pool by build related - :func:`Add` or :func:`AddExtensionDescriptor`. - - Args: - message_descriptor (Descriptor): Descriptor of the extended message. - - Returns: - list[FieldDescriptor]: Field descriptors describing the extensions. - """ - # Fallback to descriptor db if FindAllExtensionNumbers is provided. - if self._descriptor_db and hasattr( - self._descriptor_db, 'FindAllExtensionNumbers'): - full_name = message_descriptor.full_name - all_numbers = self._descriptor_db.FindAllExtensionNumbers(full_name) - for number in all_numbers: - if number in self._extensions_by_number[message_descriptor]: - continue - self._TryLoadExtensionFromDB(message_descriptor, number) - - return list(self._extensions_by_number[message_descriptor].values()) - - def _TryLoadExtensionFromDB(self, message_descriptor, number): - """Try to Load extensions from descriptor db. - - Args: - message_descriptor: descriptor of the extended message. - number: the extension number that needs to be loaded. - """ - if not self._descriptor_db: - return - # Only supported when FindFileContainingExtension is provided. - if not hasattr( - self._descriptor_db, 'FindFileContainingExtension'): - return - - full_name = message_descriptor.full_name - file_proto = self._descriptor_db.FindFileContainingExtension( - full_name, number) - - if file_proto is None: - return - - try: - self._ConvertFileProtoToFileDescriptor(file_proto) - except: - warn_msg = ('Unable to load proto file %s for extension number %d.' % - (file_proto.name, number)) - warnings.warn(warn_msg, RuntimeWarning) - - def FindServiceByName(self, full_name): - """Loads the named service descriptor from the pool. - - Args: - full_name (str): The full name of the service descriptor to load. - - Returns: - ServiceDescriptor: The service descriptor for the named service. - - Raises: - KeyError: if the service cannot be found in the pool. - """ - full_name = _NormalizeFullyQualifiedName(full_name) - if full_name not in self._service_descriptors: - self._FindFileContainingSymbolInDb(full_name) - return self._service_descriptors[full_name] - - def FindMethodByName(self, full_name): - """Loads the named service method descriptor from the pool. - - Args: - full_name (str): The full name of the method descriptor to load. - - Returns: - MethodDescriptor: The method descriptor for the service method. - - Raises: - KeyError: if the method cannot be found in the pool. - """ - full_name = _NormalizeFullyQualifiedName(full_name) - service_name, _, method_name = full_name.rpartition('.') - service_descriptor = self.FindServiceByName(service_name) - return service_descriptor.methods_by_name[method_name] - - def _FindFileContainingSymbolInDb(self, symbol): - """Finds the file in descriptor DB containing the specified symbol. - - Args: - symbol (str): The name of the symbol to search for. - - Returns: - FileDescriptor: The file that contains the specified symbol. - - Raises: - KeyError: if the file cannot be found in the descriptor database. - """ - try: - file_proto = self._internal_db.FindFileContainingSymbol(symbol) - except KeyError as error: - if self._descriptor_db: - file_proto = self._descriptor_db.FindFileContainingSymbol(symbol) - else: - raise error - if not file_proto: - raise KeyError('Cannot find a file containing %s' % symbol) - return self._ConvertFileProtoToFileDescriptor(file_proto) - - def _ConvertFileProtoToFileDescriptor(self, file_proto): - """Creates a FileDescriptor from a proto or returns a cached copy. - - This method also has the side effect of loading all the symbols found in - the file into the appropriate dictionaries in the pool. - - Args: - file_proto: The proto to convert. - - Returns: - A FileDescriptor matching the passed in proto. - """ - if file_proto.name not in self._file_descriptors: - built_deps = list(self._GetDeps(file_proto.dependency)) - direct_deps = [self.FindFileByName(n) for n in file_proto.dependency] - public_deps = [direct_deps[i] for i in file_proto.public_dependency] - - file_descriptor = descriptor.FileDescriptor( - pool=self, - name=file_proto.name, - package=file_proto.package, - syntax=file_proto.syntax, - options=_OptionsOrNone(file_proto), - serialized_pb=file_proto.SerializeToString(), - dependencies=direct_deps, - public_dependencies=public_deps, - # pylint: disable=protected-access - create_key=descriptor._internal_create_key) - scope = {} - - # This loop extracts all the message and enum types from all the - # dependencies of the file_proto. This is necessary to create the - # scope of available message types when defining the passed in - # file proto. - for dependency in built_deps: - scope.update(self._ExtractSymbols( - dependency.message_types_by_name.values())) - scope.update((_PrefixWithDot(enum.full_name), enum) - for enum in dependency.enum_types_by_name.values()) - - for message_type in file_proto.message_type: - message_desc = self._ConvertMessageDescriptor( - message_type, file_proto.package, file_descriptor, scope, - file_proto.syntax) - file_descriptor.message_types_by_name[message_desc.name] = ( - message_desc) - - for enum_type in file_proto.enum_type: - file_descriptor.enum_types_by_name[enum_type.name] = ( - self._ConvertEnumDescriptor(enum_type, file_proto.package, - file_descriptor, None, scope, True)) - - for index, extension_proto in enumerate(file_proto.extension): - extension_desc = self._MakeFieldDescriptor( - extension_proto, file_proto.package, index, file_descriptor, - is_extension=True) - extension_desc.containing_type = self._GetTypeFromScope( - file_descriptor.package, extension_proto.extendee, scope) - self._SetFieldType(extension_proto, extension_desc, - file_descriptor.package, scope) - file_descriptor.extensions_by_name[extension_desc.name] = ( - extension_desc) - self._file_desc_by_toplevel_extension[extension_desc.full_name] = ( - file_descriptor) - - for desc_proto in file_proto.message_type: - self._SetAllFieldTypes(file_proto.package, desc_proto, scope) - - if file_proto.package: - desc_proto_prefix = _PrefixWithDot(file_proto.package) - else: - desc_proto_prefix = '' - - for desc_proto in file_proto.message_type: - desc = self._GetTypeFromScope( - desc_proto_prefix, desc_proto.name, scope) - file_descriptor.message_types_by_name[desc_proto.name] = desc - - for index, service_proto in enumerate(file_proto.service): - file_descriptor.services_by_name[service_proto.name] = ( - self._MakeServiceDescriptor(service_proto, index, scope, - file_proto.package, file_descriptor)) - - self._file_descriptors[file_proto.name] = file_descriptor - - # Add extensions to the pool - file_desc = self._file_descriptors[file_proto.name] - for extension in file_desc.extensions_by_name.values(): - self._AddExtensionDescriptor(extension) - for message_type in file_desc.message_types_by_name.values(): - for extension in message_type.extensions: - self._AddExtensionDescriptor(extension) - - return file_desc - - def _ConvertMessageDescriptor(self, desc_proto, package=None, file_desc=None, - scope=None, syntax=None): - """Adds the proto to the pool in the specified package. - - Args: - desc_proto: The descriptor_pb2.DescriptorProto protobuf message. - package: The package the proto should be located in. - file_desc: The file containing this message. - scope: Dict mapping short and full symbols to message and enum types. - syntax: string indicating syntax of the file ("proto2" or "proto3") - - Returns: - The added descriptor. - """ - - if package: - desc_name = '.'.join((package, desc_proto.name)) - else: - desc_name = desc_proto.name - - if file_desc is None: - file_name = None - else: - file_name = file_desc.name - - if scope is None: - scope = {} - - nested = [ - self._ConvertMessageDescriptor( - nested, desc_name, file_desc, scope, syntax) - for nested in desc_proto.nested_type] - enums = [ - self._ConvertEnumDescriptor(enum, desc_name, file_desc, None, - scope, False) - for enum in desc_proto.enum_type] - fields = [self._MakeFieldDescriptor(field, desc_name, index, file_desc) - for index, field in enumerate(desc_proto.field)] - extensions = [ - self._MakeFieldDescriptor(extension, desc_name, index, file_desc, - is_extension=True) - for index, extension in enumerate(desc_proto.extension)] - oneofs = [ - # pylint: disable=g-complex-comprehension - descriptor.OneofDescriptor( - desc.name, - '.'.join((desc_name, desc.name)), - index, - None, - [], - _OptionsOrNone(desc), - # pylint: disable=protected-access - create_key=descriptor._internal_create_key) - for index, desc in enumerate(desc_proto.oneof_decl) - ] - extension_ranges = [(r.start, r.end) for r in desc_proto.extension_range] - if extension_ranges: - is_extendable = True - else: - is_extendable = False - desc = descriptor.Descriptor( - name=desc_proto.name, - full_name=desc_name, - filename=file_name, - containing_type=None, - fields=fields, - oneofs=oneofs, - nested_types=nested, - enum_types=enums, - extensions=extensions, - options=_OptionsOrNone(desc_proto), - is_extendable=is_extendable, - extension_ranges=extension_ranges, - file=file_desc, - serialized_start=None, - serialized_end=None, - syntax=syntax, - # pylint: disable=protected-access - create_key=descriptor._internal_create_key) - for nested in desc.nested_types: - nested.containing_type = desc - for enum in desc.enum_types: - enum.containing_type = desc - for field_index, field_desc in enumerate(desc_proto.field): - if field_desc.HasField('oneof_index'): - oneof_index = field_desc.oneof_index - oneofs[oneof_index].fields.append(fields[field_index]) - fields[field_index].containing_oneof = oneofs[oneof_index] - - scope[_PrefixWithDot(desc_name)] = desc - self._CheckConflictRegister(desc, desc.full_name, desc.file.name) - self._descriptors[desc_name] = desc - return desc - - def _ConvertEnumDescriptor(self, enum_proto, package=None, file_desc=None, - containing_type=None, scope=None, top_level=False): - """Make a protobuf EnumDescriptor given an EnumDescriptorProto protobuf. - - Args: - enum_proto: The descriptor_pb2.EnumDescriptorProto protobuf message. - package: Optional package name for the new message EnumDescriptor. - file_desc: The file containing the enum descriptor. - containing_type: The type containing this enum. - scope: Scope containing available types. - top_level: If True, the enum is a top level symbol. If False, the enum - is defined inside a message. - - Returns: - The added descriptor - """ - - if package: - enum_name = '.'.join((package, enum_proto.name)) - else: - enum_name = enum_proto.name - - if file_desc is None: - file_name = None - else: - file_name = file_desc.name - - values = [self._MakeEnumValueDescriptor(value, index) - for index, value in enumerate(enum_proto.value)] - desc = descriptor.EnumDescriptor(name=enum_proto.name, - full_name=enum_name, - filename=file_name, - file=file_desc, - values=values, - containing_type=containing_type, - options=_OptionsOrNone(enum_proto), - # pylint: disable=protected-access - create_key=descriptor._internal_create_key) - scope['.%s' % enum_name] = desc - self._CheckConflictRegister(desc, desc.full_name, desc.file.name) - self._enum_descriptors[enum_name] = desc - - # Add top level enum values. - if top_level: - for value in values: - full_name = _NormalizeFullyQualifiedName( - '.'.join((package, value.name))) - self._CheckConflictRegister(value, full_name, file_name) - self._top_enum_values[full_name] = value - - return desc - - def _MakeFieldDescriptor(self, field_proto, message_name, index, - file_desc, is_extension=False): - """Creates a field descriptor from a FieldDescriptorProto. - - For message and enum type fields, this method will do a look up - in the pool for the appropriate descriptor for that type. If it - is unavailable, it will fall back to the _source function to - create it. If this type is still unavailable, construction will - fail. - - Args: - field_proto: The proto describing the field. - message_name: The name of the containing message. - index: Index of the field - file_desc: The file containing the field descriptor. - is_extension: Indication that this field is for an extension. - - Returns: - An initialized FieldDescriptor object - """ - - if message_name: - full_name = '.'.join((message_name, field_proto.name)) - else: - full_name = field_proto.name - - if field_proto.json_name: - json_name = field_proto.json_name - else: - json_name = None - - return descriptor.FieldDescriptor( - name=field_proto.name, - full_name=full_name, - index=index, - number=field_proto.number, - type=field_proto.type, - cpp_type=None, - message_type=None, - enum_type=None, - containing_type=None, - label=field_proto.label, - has_default_value=False, - default_value=None, - is_extension=is_extension, - extension_scope=None, - options=_OptionsOrNone(field_proto), - json_name=json_name, - file=file_desc, - # pylint: disable=protected-access - create_key=descriptor._internal_create_key) - - def _SetAllFieldTypes(self, package, desc_proto, scope): - """Sets all the descriptor's fields's types. - - This method also sets the containing types on any extensions. - - Args: - package: The current package of desc_proto. - desc_proto: The message descriptor to update. - scope: Enclosing scope of available types. - """ - - package = _PrefixWithDot(package) - - main_desc = self._GetTypeFromScope(package, desc_proto.name, scope) - - if package == '.': - nested_package = _PrefixWithDot(desc_proto.name) - else: - nested_package = '.'.join([package, desc_proto.name]) - - for field_proto, field_desc in zip(desc_proto.field, main_desc.fields): - self._SetFieldType(field_proto, field_desc, nested_package, scope) - - for extension_proto, extension_desc in ( - zip(desc_proto.extension, main_desc.extensions)): - extension_desc.containing_type = self._GetTypeFromScope( - nested_package, extension_proto.extendee, scope) - self._SetFieldType(extension_proto, extension_desc, nested_package, scope) - - for nested_type in desc_proto.nested_type: - self._SetAllFieldTypes(nested_package, nested_type, scope) - - def _SetFieldType(self, field_proto, field_desc, package, scope): - """Sets the field's type, cpp_type, message_type and enum_type. - - Args: - field_proto: Data about the field in proto format. - field_desc: The descriptor to modify. - package: The package the field's container is in. - scope: Enclosing scope of available types. - """ - if field_proto.type_name: - desc = self._GetTypeFromScope(package, field_proto.type_name, scope) - else: - desc = None - - if not field_proto.HasField('type'): - if isinstance(desc, descriptor.Descriptor): - field_proto.type = descriptor.FieldDescriptor.TYPE_MESSAGE - else: - field_proto.type = descriptor.FieldDescriptor.TYPE_ENUM - - field_desc.cpp_type = descriptor.FieldDescriptor.ProtoTypeToCppProtoType( - field_proto.type) - - if (field_proto.type == descriptor.FieldDescriptor.TYPE_MESSAGE - or field_proto.type == descriptor.FieldDescriptor.TYPE_GROUP): - field_desc.message_type = desc - - if field_proto.type == descriptor.FieldDescriptor.TYPE_ENUM: - field_desc.enum_type = desc - - if field_proto.label == descriptor.FieldDescriptor.LABEL_REPEATED: - field_desc.has_default_value = False - field_desc.default_value = [] - elif field_proto.HasField('default_value'): - field_desc.has_default_value = True - if (field_proto.type == descriptor.FieldDescriptor.TYPE_DOUBLE or - field_proto.type == descriptor.FieldDescriptor.TYPE_FLOAT): - field_desc.default_value = float(field_proto.default_value) - elif field_proto.type == descriptor.FieldDescriptor.TYPE_STRING: - field_desc.default_value = field_proto.default_value - elif field_proto.type == descriptor.FieldDescriptor.TYPE_BOOL: - field_desc.default_value = field_proto.default_value.lower() == 'true' - elif field_proto.type == descriptor.FieldDescriptor.TYPE_ENUM: - field_desc.default_value = field_desc.enum_type.values_by_name[ - field_proto.default_value].number - elif field_proto.type == descriptor.FieldDescriptor.TYPE_BYTES: - field_desc.default_value = text_encoding.CUnescape( - field_proto.default_value) - elif field_proto.type == descriptor.FieldDescriptor.TYPE_MESSAGE: - field_desc.default_value = None - else: - # All other types are of the "int" type. - field_desc.default_value = int(field_proto.default_value) - else: - field_desc.has_default_value = False - if (field_proto.type == descriptor.FieldDescriptor.TYPE_DOUBLE or - field_proto.type == descriptor.FieldDescriptor.TYPE_FLOAT): - field_desc.default_value = 0.0 - elif field_proto.type == descriptor.FieldDescriptor.TYPE_STRING: - field_desc.default_value = u'' - elif field_proto.type == descriptor.FieldDescriptor.TYPE_BOOL: - field_desc.default_value = False - elif field_proto.type == descriptor.FieldDescriptor.TYPE_ENUM: - field_desc.default_value = field_desc.enum_type.values[0].number - elif field_proto.type == descriptor.FieldDescriptor.TYPE_BYTES: - field_desc.default_value = b'' - elif field_proto.type == descriptor.FieldDescriptor.TYPE_MESSAGE: - field_desc.default_value = None - elif field_proto.type == descriptor.FieldDescriptor.TYPE_GROUP: - field_desc.default_value = None - else: - # All other types are of the "int" type. - field_desc.default_value = 0 - - field_desc.type = field_proto.type - - def _MakeEnumValueDescriptor(self, value_proto, index): - """Creates a enum value descriptor object from a enum value proto. - - Args: - value_proto: The proto describing the enum value. - index: The index of the enum value. - - Returns: - An initialized EnumValueDescriptor object. - """ - - return descriptor.EnumValueDescriptor( - name=value_proto.name, - index=index, - number=value_proto.number, - options=_OptionsOrNone(value_proto), - type=None, - # pylint: disable=protected-access - create_key=descriptor._internal_create_key) - - def _MakeServiceDescriptor(self, service_proto, service_index, scope, - package, file_desc): - """Make a protobuf ServiceDescriptor given a ServiceDescriptorProto. - - Args: - service_proto: The descriptor_pb2.ServiceDescriptorProto protobuf message. - service_index: The index of the service in the File. - scope: Dict mapping short and full symbols to message and enum types. - package: Optional package name for the new message EnumDescriptor. - file_desc: The file containing the service descriptor. - - Returns: - The added descriptor. - """ - - if package: - service_name = '.'.join((package, service_proto.name)) - else: - service_name = service_proto.name - - methods = [self._MakeMethodDescriptor(method_proto, service_name, package, - scope, index) - for index, method_proto in enumerate(service_proto.method)] - desc = descriptor.ServiceDescriptor( - name=service_proto.name, - full_name=service_name, - index=service_index, - methods=methods, - options=_OptionsOrNone(service_proto), - file=file_desc, - # pylint: disable=protected-access - create_key=descriptor._internal_create_key) - self._CheckConflictRegister(desc, desc.full_name, desc.file.name) - self._service_descriptors[service_name] = desc - return desc - - def _MakeMethodDescriptor(self, method_proto, service_name, package, scope, - index): - """Creates a method descriptor from a MethodDescriptorProto. - - Args: - method_proto: The proto describing the method. - service_name: The name of the containing service. - package: Optional package name to look up for types. - scope: Scope containing available types. - index: Index of the method in the service. - - Returns: - An initialized MethodDescriptor object. - """ - full_name = '.'.join((service_name, method_proto.name)) - input_type = self._GetTypeFromScope( - package, method_proto.input_type, scope) - output_type = self._GetTypeFromScope( - package, method_proto.output_type, scope) - return descriptor.MethodDescriptor( - name=method_proto.name, - full_name=full_name, - index=index, - containing_service=None, - input_type=input_type, - output_type=output_type, - client_streaming=method_proto.client_streaming, - server_streaming=method_proto.server_streaming, - options=_OptionsOrNone(method_proto), - # pylint: disable=protected-access - create_key=descriptor._internal_create_key) - - def _ExtractSymbols(self, descriptors): - """Pulls out all the symbols from descriptor protos. - - Args: - descriptors: The messages to extract descriptors from. - Yields: - A two element tuple of the type name and descriptor object. - """ - - for desc in descriptors: - yield (_PrefixWithDot(desc.full_name), desc) - for symbol in self._ExtractSymbols(desc.nested_types): - yield symbol - for enum in desc.enum_types: - yield (_PrefixWithDot(enum.full_name), enum) - - def _GetDeps(self, dependencies, visited=None): - """Recursively finds dependencies for file protos. - - Args: - dependencies: The names of the files being depended on. - visited: The names of files already found. - - Yields: - Each direct and indirect dependency. - """ - - visited = visited or set() - for dependency in dependencies: - if dependency not in visited: - visited.add(dependency) - dep_desc = self.FindFileByName(dependency) - yield dep_desc - public_files = [d.name for d in dep_desc.public_dependencies] - yield from self._GetDeps(public_files, visited) - - def _GetTypeFromScope(self, package, type_name, scope): - """Finds a given type name in the current scope. - - Args: - package: The package the proto should be located in. - type_name: The name of the type to be found in the scope. - scope: Dict mapping short and full symbols to message and enum types. - - Returns: - The descriptor for the requested type. - """ - if type_name not in scope: - components = _PrefixWithDot(package).split('.') - while components: - possible_match = '.'.join(components + [type_name]) - if possible_match in scope: - type_name = possible_match - break - else: - components.pop(-1) - return scope[type_name] - - -def _PrefixWithDot(name): - return name if name.startswith('.') else '.%s' % name - - -if _USE_C_DESCRIPTORS: - # TODO(amauryfa): This pool could be constructed from Python code, when we - # support a flag like 'use_cpp_generated_pool=True'. - # pylint: disable=protected-access - _DEFAULT = descriptor._message.default_pool -else: - _DEFAULT = DescriptorPool() - - -def Default(): - return _DEFAULT diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/duration_pb2.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/duration_pb2.py deleted file mode 100644 index a8ecc07bdf..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/duration_pb2.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/duration.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1egoogle/protobuf/duration.proto\x12\x0fgoogle.protobuf\"*\n\x08\x44uration\x12\x0f\n\x07seconds\x18\x01 \x01(\x03\x12\r\n\x05nanos\x18\x02 \x01(\x05\x42\x83\x01\n\x13\x63om.google.protobufB\rDurationProtoP\x01Z1google.golang.org/protobuf/types/known/durationpb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.duration_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.google.protobufB\rDurationProtoP\001Z1google.golang.org/protobuf/types/known/durationpb\370\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' - _DURATION._serialized_start=51 - _DURATION._serialized_end=93 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/empty_pb2.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/empty_pb2.py deleted file mode 100644 index 0b4d554db3..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/empty_pb2.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/empty.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1bgoogle/protobuf/empty.proto\x12\x0fgoogle.protobuf\"\x07\n\x05\x45mptyB}\n\x13\x63om.google.protobufB\nEmptyProtoP\x01Z.google.golang.org/protobuf/types/known/emptypb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.empty_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.google.protobufB\nEmptyProtoP\001Z.google.golang.org/protobuf/types/known/emptypb\370\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' - _EMPTY._serialized_start=48 - _EMPTY._serialized_end=55 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/field_mask_pb2.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/field_mask_pb2.py deleted file mode 100644 index 80a4e96e59..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/field_mask_pb2.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/field_mask.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n google/protobuf/field_mask.proto\x12\x0fgoogle.protobuf\"\x1a\n\tFieldMask\x12\r\n\x05paths\x18\x01 \x03(\tB\x85\x01\n\x13\x63om.google.protobufB\x0e\x46ieldMaskProtoP\x01Z2google.golang.org/protobuf/types/known/fieldmaskpb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.field_mask_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.google.protobufB\016FieldMaskProtoP\001Z2google.golang.org/protobuf/types/known/fieldmaskpb\370\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' - _FIELDMASK._serialized_start=53 - _FIELDMASK._serialized_end=79 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/__init__.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/_parameterized.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/_parameterized.py deleted file mode 100644 index afdbb78c36..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/_parameterized.py +++ /dev/null @@ -1,443 +0,0 @@ -#! /usr/bin/env python -# -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Adds support for parameterized tests to Python's unittest TestCase class. - -A parameterized test is a method in a test case that is invoked with different -argument tuples. - -A simple example: - - class AdditionExample(parameterized.TestCase): - @parameterized.parameters( - (1, 2, 3), - (4, 5, 9), - (1, 1, 3)) - def testAddition(self, op1, op2, result): - self.assertEqual(result, op1 + op2) - - -Each invocation is a separate test case and properly isolated just -like a normal test method, with its own setUp/tearDown cycle. In the -example above, there are three separate testcases, one of which will -fail due to an assertion error (1 + 1 != 3). - -Parameters for individual test cases can be tuples (with positional parameters) -or dictionaries (with named parameters): - - class AdditionExample(parameterized.TestCase): - @parameterized.parameters( - {'op1': 1, 'op2': 2, 'result': 3}, - {'op1': 4, 'op2': 5, 'result': 9}, - ) - def testAddition(self, op1, op2, result): - self.assertEqual(result, op1 + op2) - -If a parameterized test fails, the error message will show the -original test name (which is modified internally) and the arguments -for the specific invocation, which are part of the string returned by -the shortDescription() method on test cases. - -The id method of the test, used internally by the unittest framework, -is also modified to show the arguments. To make sure that test names -stay the same across several invocations, object representations like - - >>> class Foo(object): - ... pass - >>> repr(Foo()) - '<__main__.Foo object at 0x23d8610>' - -are turned into '<__main__.Foo>'. For even more descriptive names, -especially in test logs, you can use the named_parameters decorator. In -this case, only tuples are supported, and the first parameters has to -be a string (or an object that returns an apt name when converted via -str()): - - class NamedExample(parameterized.TestCase): - @parameterized.named_parameters( - ('Normal', 'aa', 'aaa', True), - ('EmptyPrefix', '', 'abc', True), - ('BothEmpty', '', '', True)) - def testStartsWith(self, prefix, string, result): - self.assertEqual(result, strings.startswith(prefix)) - -Named tests also have the benefit that they can be run individually -from the command line: - - $ testmodule.py NamedExample.testStartsWithNormal - . - -------------------------------------------------------------------- - Ran 1 test in 0.000s - - OK - -Parameterized Classes -===================== -If invocation arguments are shared across test methods in a single -TestCase class, instead of decorating all test methods -individually, the class itself can be decorated: - - @parameterized.parameters( - (1, 2, 3) - (4, 5, 9)) - class ArithmeticTest(parameterized.TestCase): - def testAdd(self, arg1, arg2, result): - self.assertEqual(arg1 + arg2, result) - - def testSubtract(self, arg2, arg2, result): - self.assertEqual(result - arg1, arg2) - -Inputs from Iterables -===================== -If parameters should be shared across several test cases, or are dynamically -created from other sources, a single non-tuple iterable can be passed into -the decorator. This iterable will be used to obtain the test cases: - - class AdditionExample(parameterized.TestCase): - @parameterized.parameters( - c.op1, c.op2, c.result for c in testcases - ) - def testAddition(self, op1, op2, result): - self.assertEqual(result, op1 + op2) - - -Single-Argument Test Methods -============================ -If a test method takes only one argument, the single argument does not need to -be wrapped into a tuple: - - class NegativeNumberExample(parameterized.TestCase): - @parameterized.parameters( - -1, -3, -4, -5 - ) - def testIsNegative(self, arg): - self.assertTrue(IsNegative(arg)) -""" - -__author__ = 'tmarek@google.com (Torsten Marek)' - -import functools -import re -import types -import unittest -import uuid - -try: - # Since python 3 - import collections.abc as collections_abc -except ImportError: - # Won't work after python 3.8 - import collections as collections_abc - -ADDR_RE = re.compile(r'\<([a-zA-Z0-9_\-\.]+) object at 0x[a-fA-F0-9]+\>') -_SEPARATOR = uuid.uuid1().hex -_FIRST_ARG = object() -_ARGUMENT_REPR = object() - - -def _CleanRepr(obj): - return ADDR_RE.sub(r'<\1>', repr(obj)) - - -# Helper function formerly from the unittest module, removed from it in -# Python 2.7. -def _StrClass(cls): - return '%s.%s' % (cls.__module__, cls.__name__) - - -def _NonStringIterable(obj): - return (isinstance(obj, collections_abc.Iterable) and - not isinstance(obj, str)) - - -def _FormatParameterList(testcase_params): - if isinstance(testcase_params, collections_abc.Mapping): - return ', '.join('%s=%s' % (argname, _CleanRepr(value)) - for argname, value in testcase_params.items()) - elif _NonStringIterable(testcase_params): - return ', '.join(map(_CleanRepr, testcase_params)) - else: - return _FormatParameterList((testcase_params,)) - - -class _ParameterizedTestIter(object): - """Callable and iterable class for producing new test cases.""" - - def __init__(self, test_method, testcases, naming_type): - """Returns concrete test functions for a test and a list of parameters. - - The naming_type is used to determine the name of the concrete - functions as reported by the unittest framework. If naming_type is - _FIRST_ARG, the testcases must be tuples, and the first element must - have a string representation that is a valid Python identifier. - - Args: - test_method: The decorated test method. - testcases: (list of tuple/dict) A list of parameter - tuples/dicts for individual test invocations. - naming_type: The test naming type, either _NAMED or _ARGUMENT_REPR. - """ - self._test_method = test_method - self.testcases = testcases - self._naming_type = naming_type - - def __call__(self, *args, **kwargs): - raise RuntimeError('You appear to be running a parameterized test case ' - 'without having inherited from parameterized.' - 'TestCase. This is bad because none of ' - 'your test cases are actually being run.') - - def __iter__(self): - test_method = self._test_method - naming_type = self._naming_type - - def MakeBoundParamTest(testcase_params): - @functools.wraps(test_method) - def BoundParamTest(self): - if isinstance(testcase_params, collections_abc.Mapping): - test_method(self, **testcase_params) - elif _NonStringIterable(testcase_params): - test_method(self, *testcase_params) - else: - test_method(self, testcase_params) - - if naming_type is _FIRST_ARG: - # Signal the metaclass that the name of the test function is unique - # and descriptive. - BoundParamTest.__x_use_name__ = True - BoundParamTest.__name__ += str(testcase_params[0]) - testcase_params = testcase_params[1:] - elif naming_type is _ARGUMENT_REPR: - # __x_extra_id__ is used to pass naming information to the __new__ - # method of TestGeneratorMetaclass. - # The metaclass will make sure to create a unique, but nondescriptive - # name for this test. - BoundParamTest.__x_extra_id__ = '(%s)' % ( - _FormatParameterList(testcase_params),) - else: - raise RuntimeError('%s is not a valid naming type.' % (naming_type,)) - - BoundParamTest.__doc__ = '%s(%s)' % ( - BoundParamTest.__name__, _FormatParameterList(testcase_params)) - if test_method.__doc__: - BoundParamTest.__doc__ += '\n%s' % (test_method.__doc__,) - return BoundParamTest - return (MakeBoundParamTest(c) for c in self.testcases) - - -def _IsSingletonList(testcases): - """True iff testcases contains only a single non-tuple element.""" - return len(testcases) == 1 and not isinstance(testcases[0], tuple) - - -def _ModifyClass(class_object, testcases, naming_type): - assert not getattr(class_object, '_id_suffix', None), ( - 'Cannot add parameters to %s,' - ' which already has parameterized methods.' % (class_object,)) - class_object._id_suffix = id_suffix = {} - # We change the size of __dict__ while we iterate over it, - # which Python 3.x will complain about, so use copy(). - for name, obj in class_object.__dict__.copy().items(): - if (name.startswith(unittest.TestLoader.testMethodPrefix) - and isinstance(obj, types.FunctionType)): - delattr(class_object, name) - methods = {} - _UpdateClassDictForParamTestCase( - methods, id_suffix, name, - _ParameterizedTestIter(obj, testcases, naming_type)) - for name, meth in methods.items(): - setattr(class_object, name, meth) - - -def _ParameterDecorator(naming_type, testcases): - """Implementation of the parameterization decorators. - - Args: - naming_type: The naming type. - testcases: Testcase parameters. - - Returns: - A function for modifying the decorated object. - """ - def _Apply(obj): - if isinstance(obj, type): - _ModifyClass( - obj, - list(testcases) if not isinstance(testcases, collections_abc.Sequence) - else testcases, - naming_type) - return obj - else: - return _ParameterizedTestIter(obj, testcases, naming_type) - - if _IsSingletonList(testcases): - assert _NonStringIterable(testcases[0]), ( - 'Single parameter argument must be a non-string iterable') - testcases = testcases[0] - - return _Apply - - -def parameters(*testcases): # pylint: disable=invalid-name - """A decorator for creating parameterized tests. - - See the module docstring for a usage example. - Args: - *testcases: Parameters for the decorated method, either a single - iterable, or a list of tuples/dicts/objects (for tests - with only one argument). - - Returns: - A test generator to be handled by TestGeneratorMetaclass. - """ - return _ParameterDecorator(_ARGUMENT_REPR, testcases) - - -def named_parameters(*testcases): # pylint: disable=invalid-name - """A decorator for creating parameterized tests. - - See the module docstring for a usage example. The first element of - each parameter tuple should be a string and will be appended to the - name of the test method. - - Args: - *testcases: Parameters for the decorated method, either a single - iterable, or a list of tuples. - - Returns: - A test generator to be handled by TestGeneratorMetaclass. - """ - return _ParameterDecorator(_FIRST_ARG, testcases) - - -class TestGeneratorMetaclass(type): - """Metaclass for test cases with test generators. - - A test generator is an iterable in a testcase that produces callables. These - callables must be single-argument methods. These methods are injected into - the class namespace and the original iterable is removed. If the name of the - iterable conforms to the test pattern, the injected methods will be picked - up as tests by the unittest framework. - - In general, it is supposed to be used in conjunction with the - parameters decorator. - """ - - def __new__(mcs, class_name, bases, dct): - dct['_id_suffix'] = id_suffix = {} - for name, obj in dct.copy().items(): - if (name.startswith(unittest.TestLoader.testMethodPrefix) and - _NonStringIterable(obj)): - iterator = iter(obj) - dct.pop(name) - _UpdateClassDictForParamTestCase(dct, id_suffix, name, iterator) - - return type.__new__(mcs, class_name, bases, dct) - - -def _UpdateClassDictForParamTestCase(dct, id_suffix, name, iterator): - """Adds individual test cases to a dictionary. - - Args: - dct: The target dictionary. - id_suffix: The dictionary for mapping names to test IDs. - name: The original name of the test case. - iterator: The iterator generating the individual test cases. - """ - for idx, func in enumerate(iterator): - assert callable(func), 'Test generators must yield callables, got %r' % ( - func,) - if getattr(func, '__x_use_name__', False): - new_name = func.__name__ - else: - new_name = '%s%s%d' % (name, _SEPARATOR, idx) - assert new_name not in dct, ( - 'Name of parameterized test case "%s" not unique' % (new_name,)) - dct[new_name] = func - id_suffix[new_name] = getattr(func, '__x_extra_id__', '') - - -class TestCase(unittest.TestCase, metaclass=TestGeneratorMetaclass): - """Base class for test cases using the parameters decorator.""" - - def _OriginalName(self): - return self._testMethodName.split(_SEPARATOR)[0] - - def __str__(self): - return '%s (%s)' % (self._OriginalName(), _StrClass(self.__class__)) - - def id(self): # pylint: disable=invalid-name - """Returns the descriptive ID of the test. - - This is used internally by the unittesting framework to get a name - for the test to be used in reports. - - Returns: - The test id. - """ - return '%s.%s%s' % (_StrClass(self.__class__), - self._OriginalName(), - self._id_suffix.get(self._testMethodName, '')) - - -def CoopTestCase(other_base_class): - """Returns a new base class with a cooperative metaclass base. - - This enables the TestCase to be used in combination - with other base classes that have custom metaclasses, such as - mox.MoxTestBase. - - Only works with metaclasses that do not override type.__new__. - - Example: - - import google3 - import mox - - from google3.testing.pybase import parameterized - - class ExampleTest(parameterized.CoopTestCase(mox.MoxTestBase)): - ... - - Args: - other_base_class: (class) A test case base class. - - Returns: - A new class object. - """ - metaclass = type( - 'CoopMetaclass', - (other_base_class.__metaclass__, - TestGeneratorMetaclass), {}) - return metaclass( - 'CoopTestCase', - (other_base_class, TestCase), {}) diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/api_implementation.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/api_implementation.py deleted file mode 100644 index 7fef237670..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/api_implementation.py +++ /dev/null @@ -1,112 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Determine which implementation of the protobuf API is used in this process. -""" - -import os -import sys -import warnings - -try: - # pylint: disable=g-import-not-at-top - from google.protobuf.internal import _api_implementation - # The compile-time constants in the _api_implementation module can be used to - # switch to a certain implementation of the Python API at build time. - _api_version = _api_implementation.api_version -except ImportError: - _api_version = -1 # Unspecified by compiler flags. - -if _api_version == 1: - raise ValueError('api_version=1 is no longer supported.') - - -_default_implementation_type = ('cpp' if _api_version > 0 else 'python') - - -# This environment variable can be used to switch to a certain implementation -# of the Python API, overriding the compile-time constants in the -# _api_implementation module. Right now only 'python' and 'cpp' are valid -# values. Any other value will be ignored. -_implementation_type = os.getenv('PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION', - _default_implementation_type) - -if _implementation_type != 'python': - _implementation_type = 'cpp' - -if 'PyPy' in sys.version and _implementation_type == 'cpp': - warnings.warn('PyPy does not work yet with cpp protocol buffers. ' - 'Falling back to the python implementation.') - _implementation_type = 'python' - - -# Detect if serialization should be deterministic by default -try: - # The presence of this module in a build allows the proto implementation to - # be upgraded merely via build deps. - # - # NOTE: Merely importing this automatically enables deterministic proto - # serialization for C++ code, but we still need to export it as a boolean so - # that we can do the same for `_implementation_type == 'python'`. - # - # NOTE2: It is possible for C++ code to enable deterministic serialization by - # default _without_ affecting Python code, if the C++ implementation is not in - # use by this module. That is intended behavior, so we don't actually expose - # this boolean outside of this module. - # - # pylint: disable=g-import-not-at-top,unused-import - from google.protobuf import enable_deterministic_proto_serialization - _python_deterministic_proto_serialization = True -except ImportError: - _python_deterministic_proto_serialization = False - - -# Usage of this function is discouraged. Clients shouldn't care which -# implementation of the API is in use. Note that there is no guarantee -# that differences between APIs will be maintained. -# Please don't use this function if possible. -def Type(): - return _implementation_type - - -def _SetType(implementation_type): - """Never use! Only for protobuf benchmark.""" - global _implementation_type - _implementation_type = implementation_type - - -# See comment on 'Type' above. -def Version(): - return 2 - - -# For internal use only -def IsPythonDefaultSerializationDeterministic(): - return _python_deterministic_proto_serialization diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/builder.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/builder.py deleted file mode 100644 index 64353ee4af..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/builder.py +++ /dev/null @@ -1,130 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Builds descriptors, message classes and services for generated _pb2.py. - -This file is only called in python generated _pb2.py files. It builds -descriptors, message classes and services that users can directly use -in generated code. -""" - -__author__ = 'jieluo@google.com (Jie Luo)' - -from google.protobuf.internal import enum_type_wrapper -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database - -_sym_db = _symbol_database.Default() - - -def BuildMessageAndEnumDescriptors(file_des, module): - """Builds message and enum descriptors. - - Args: - file_des: FileDescriptor of the .proto file - module: Generated _pb2 module - """ - - def BuildNestedDescriptors(msg_des, prefix): - for (name, nested_msg) in msg_des.nested_types_by_name.items(): - module_name = prefix + name.upper() - module[module_name] = nested_msg - BuildNestedDescriptors(nested_msg, module_name + '_') - for enum_des in msg_des.enum_types: - module[prefix + enum_des.name.upper()] = enum_des - - for (name, msg_des) in file_des.message_types_by_name.items(): - module_name = '_' + name.upper() - module[module_name] = msg_des - BuildNestedDescriptors(msg_des, module_name + '_') - - -def BuildTopDescriptorsAndMessages(file_des, module_name, module): - """Builds top level descriptors and message classes. - - Args: - file_des: FileDescriptor of the .proto file - module_name: str, the name of generated _pb2 module - module: Generated _pb2 module - """ - - def BuildMessage(msg_des): - create_dict = {} - for (name, nested_msg) in msg_des.nested_types_by_name.items(): - create_dict[name] = BuildMessage(nested_msg) - create_dict['DESCRIPTOR'] = msg_des - create_dict['__module__'] = module_name - message_class = _reflection.GeneratedProtocolMessageType( - msg_des.name, (_message.Message,), create_dict) - _sym_db.RegisterMessage(message_class) - return message_class - - # top level enums - for (name, enum_des) in file_des.enum_types_by_name.items(): - module['_' + name.upper()] = enum_des - module[name] = enum_type_wrapper.EnumTypeWrapper(enum_des) - for enum_value in enum_des.values: - module[enum_value.name] = enum_value.number - - # top level extensions - for (name, extension_des) in file_des.extensions_by_name.items(): - module[name.upper() + '_FIELD_NUMBER'] = extension_des.number - module[name] = extension_des - - # services - for (name, service) in file_des.services_by_name.items(): - module['_' + name.upper()] = service - - # Build messages. - for (name, msg_des) in file_des.message_types_by_name.items(): - module[name] = BuildMessage(msg_des) - - -def BuildServices(file_des, module_name, module): - """Builds services classes and services stub class. - - Args: - file_des: FileDescriptor of the .proto file - module_name: str, the name of generated _pb2 module - module: Generated _pb2 module - """ - # pylint: disable=g-import-not-at-top - from google.protobuf import service as _service - from google.protobuf import service_reflection - # pylint: enable=g-import-not-at-top - for (name, service) in file_des.services_by_name.items(): - module[name] = service_reflection.GeneratedServiceType( - name, (_service.Service,), - dict(DESCRIPTOR=service, __module__=module_name)) - stub_name = name + '_Stub' - module[stub_name] = service_reflection.GeneratedServiceStubType( - stub_name, (module[name],), - dict(DESCRIPTOR=service, __module__=module_name)) diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/containers.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/containers.py deleted file mode 100644 index 29fbb53d2f..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/containers.py +++ /dev/null @@ -1,710 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Contains container classes to represent different protocol buffer types. - -This file defines container classes which represent categories of protocol -buffer field types which need extra maintenance. Currently these categories -are: - -- Repeated scalar fields - These are all repeated fields which aren't - composite (e.g. they are of simple types like int32, string, etc). -- Repeated composite fields - Repeated fields which are composite. This - includes groups and nested messages. -""" - -import collections.abc -import copy -import pickle -from typing import ( - Any, - Iterable, - Iterator, - List, - MutableMapping, - MutableSequence, - NoReturn, - Optional, - Sequence, - TypeVar, - Union, - overload, -) - - -_T = TypeVar('_T') -_K = TypeVar('_K') -_V = TypeVar('_V') - - -class BaseContainer(Sequence[_T]): - """Base container class.""" - - # Minimizes memory usage and disallows assignment to other attributes. - __slots__ = ['_message_listener', '_values'] - - def __init__(self, message_listener: Any) -> None: - """ - Args: - message_listener: A MessageListener implementation. - The RepeatedScalarFieldContainer will call this object's - Modified() method when it is modified. - """ - self._message_listener = message_listener - self._values = [] - - @overload - def __getitem__(self, key: int) -> _T: - ... - - @overload - def __getitem__(self, key: slice) -> List[_T]: - ... - - def __getitem__(self, key): - """Retrieves item by the specified key.""" - return self._values[key] - - def __len__(self) -> int: - """Returns the number of elements in the container.""" - return len(self._values) - - def __ne__(self, other: Any) -> bool: - """Checks if another instance isn't equal to this one.""" - # The concrete classes should define __eq__. - return not self == other - - __hash__ = None - - def __repr__(self) -> str: - return repr(self._values) - - def sort(self, *args, **kwargs) -> None: - # Continue to support the old sort_function keyword argument. - # This is expected to be a rare occurrence, so use LBYL to avoid - # the overhead of actually catching KeyError. - if 'sort_function' in kwargs: - kwargs['cmp'] = kwargs.pop('sort_function') - self._values.sort(*args, **kwargs) - - def reverse(self) -> None: - self._values.reverse() - - -# TODO(slebedev): Remove this. BaseContainer does *not* conform to -# MutableSequence, only its subclasses do. -collections.abc.MutableSequence.register(BaseContainer) - - -class RepeatedScalarFieldContainer(BaseContainer[_T], MutableSequence[_T]): - """Simple, type-checked, list-like container for holding repeated scalars.""" - - # Disallows assignment to other attributes. - __slots__ = ['_type_checker'] - - def __init__( - self, - message_listener: Any, - type_checker: Any, - ) -> None: - """Args: - - message_listener: A MessageListener implementation. The - RepeatedScalarFieldContainer will call this object's Modified() method - when it is modified. - type_checker: A type_checkers.ValueChecker instance to run on elements - inserted into this container. - """ - super().__init__(message_listener) - self._type_checker = type_checker - - def append(self, value: _T) -> None: - """Appends an item to the list. Similar to list.append().""" - self._values.append(self._type_checker.CheckValue(value)) - if not self._message_listener.dirty: - self._message_listener.Modified() - - def insert(self, key: int, value: _T) -> None: - """Inserts the item at the specified position. Similar to list.insert().""" - self._values.insert(key, self._type_checker.CheckValue(value)) - if not self._message_listener.dirty: - self._message_listener.Modified() - - def extend(self, elem_seq: Iterable[_T]) -> None: - """Extends by appending the given iterable. Similar to list.extend().""" - if elem_seq is None: - return - try: - elem_seq_iter = iter(elem_seq) - except TypeError: - if not elem_seq: - # silently ignore falsy inputs :-/. - # TODO(ptucker): Deprecate this behavior. b/18413862 - return - raise - - new_values = [self._type_checker.CheckValue(elem) for elem in elem_seq_iter] - if new_values: - self._values.extend(new_values) - self._message_listener.Modified() - - def MergeFrom( - self, - other: Union['RepeatedScalarFieldContainer[_T]', Iterable[_T]], - ) -> None: - """Appends the contents of another repeated field of the same type to this - one. We do not check the types of the individual fields. - """ - self._values.extend(other) - self._message_listener.Modified() - - def remove(self, elem: _T): - """Removes an item from the list. Similar to list.remove().""" - self._values.remove(elem) - self._message_listener.Modified() - - def pop(self, key: Optional[int] = -1) -> _T: - """Removes and returns an item at a given index. Similar to list.pop().""" - value = self._values[key] - self.__delitem__(key) - return value - - @overload - def __setitem__(self, key: int, value: _T) -> None: - ... - - @overload - def __setitem__(self, key: slice, value: Iterable[_T]) -> None: - ... - - def __setitem__(self, key, value) -> None: - """Sets the item on the specified position.""" - if isinstance(key, slice): - if key.step is not None: - raise ValueError('Extended slices not supported') - self._values[key] = map(self._type_checker.CheckValue, value) - self._message_listener.Modified() - else: - self._values[key] = self._type_checker.CheckValue(value) - self._message_listener.Modified() - - def __delitem__(self, key: Union[int, slice]) -> None: - """Deletes the item at the specified position.""" - del self._values[key] - self._message_listener.Modified() - - def __eq__(self, other: Any) -> bool: - """Compares the current instance with another one.""" - if self is other: - return True - # Special case for the same type which should be common and fast. - if isinstance(other, self.__class__): - return other._values == self._values - # We are presumably comparing against some other sequence type. - return other == self._values - - def __deepcopy__( - self, - unused_memo: Any = None, - ) -> 'RepeatedScalarFieldContainer[_T]': - clone = RepeatedScalarFieldContainer( - copy.deepcopy(self._message_listener), self._type_checker) - clone.MergeFrom(self) - return clone - - def __reduce__(self, **kwargs) -> NoReturn: - raise pickle.PickleError( - "Can't pickle repeated scalar fields, convert to list first") - - -# TODO(slebedev): Constrain T to be a subtype of Message. -class RepeatedCompositeFieldContainer(BaseContainer[_T], MutableSequence[_T]): - """Simple, list-like container for holding repeated composite fields.""" - - # Disallows assignment to other attributes. - __slots__ = ['_message_descriptor'] - - def __init__(self, message_listener: Any, message_descriptor: Any) -> None: - """ - Note that we pass in a descriptor instead of the generated directly, - since at the time we construct a _RepeatedCompositeFieldContainer we - haven't yet necessarily initialized the type that will be contained in the - container. - - Args: - message_listener: A MessageListener implementation. - The RepeatedCompositeFieldContainer will call this object's - Modified() method when it is modified. - message_descriptor: A Descriptor instance describing the protocol type - that should be present in this container. We'll use the - _concrete_class field of this descriptor when the client calls add(). - """ - super().__init__(message_listener) - self._message_descriptor = message_descriptor - - def add(self, **kwargs: Any) -> _T: - """Adds a new element at the end of the list and returns it. Keyword - arguments may be used to initialize the element. - """ - new_element = self._message_descriptor._concrete_class(**kwargs) - new_element._SetListener(self._message_listener) - self._values.append(new_element) - if not self._message_listener.dirty: - self._message_listener.Modified() - return new_element - - def append(self, value: _T) -> None: - """Appends one element by copying the message.""" - new_element = self._message_descriptor._concrete_class() - new_element._SetListener(self._message_listener) - new_element.CopyFrom(value) - self._values.append(new_element) - if not self._message_listener.dirty: - self._message_listener.Modified() - - def insert(self, key: int, value: _T) -> None: - """Inserts the item at the specified position by copying.""" - new_element = self._message_descriptor._concrete_class() - new_element._SetListener(self._message_listener) - new_element.CopyFrom(value) - self._values.insert(key, new_element) - if not self._message_listener.dirty: - self._message_listener.Modified() - - def extend(self, elem_seq: Iterable[_T]) -> None: - """Extends by appending the given sequence of elements of the same type - - as this one, copying each individual message. - """ - message_class = self._message_descriptor._concrete_class - listener = self._message_listener - values = self._values - for message in elem_seq: - new_element = message_class() - new_element._SetListener(listener) - new_element.MergeFrom(message) - values.append(new_element) - listener.Modified() - - def MergeFrom( - self, - other: Union['RepeatedCompositeFieldContainer[_T]', Iterable[_T]], - ) -> None: - """Appends the contents of another repeated field of the same type to this - one, copying each individual message. - """ - self.extend(other) - - def remove(self, elem: _T) -> None: - """Removes an item from the list. Similar to list.remove().""" - self._values.remove(elem) - self._message_listener.Modified() - - def pop(self, key: Optional[int] = -1) -> _T: - """Removes and returns an item at a given index. Similar to list.pop().""" - value = self._values[key] - self.__delitem__(key) - return value - - @overload - def __setitem__(self, key: int, value: _T) -> None: - ... - - @overload - def __setitem__(self, key: slice, value: Iterable[_T]) -> None: - ... - - def __setitem__(self, key, value): - # This method is implemented to make RepeatedCompositeFieldContainer - # structurally compatible with typing.MutableSequence. It is - # otherwise unsupported and will always raise an error. - raise TypeError( - f'{self.__class__.__name__} object does not support item assignment') - - def __delitem__(self, key: Union[int, slice]) -> None: - """Deletes the item at the specified position.""" - del self._values[key] - self._message_listener.Modified() - - def __eq__(self, other: Any) -> bool: - """Compares the current instance with another one.""" - if self is other: - return True - if not isinstance(other, self.__class__): - raise TypeError('Can only compare repeated composite fields against ' - 'other repeated composite fields.') - return self._values == other._values - - -class ScalarMap(MutableMapping[_K, _V]): - """Simple, type-checked, dict-like container for holding repeated scalars.""" - - # Disallows assignment to other attributes. - __slots__ = ['_key_checker', '_value_checker', '_values', '_message_listener', - '_entry_descriptor'] - - def __init__( - self, - message_listener: Any, - key_checker: Any, - value_checker: Any, - entry_descriptor: Any, - ) -> None: - """ - Args: - message_listener: A MessageListener implementation. - The ScalarMap will call this object's Modified() method when it - is modified. - key_checker: A type_checkers.ValueChecker instance to run on keys - inserted into this container. - value_checker: A type_checkers.ValueChecker instance to run on values - inserted into this container. - entry_descriptor: The MessageDescriptor of a map entry: key and value. - """ - self._message_listener = message_listener - self._key_checker = key_checker - self._value_checker = value_checker - self._entry_descriptor = entry_descriptor - self._values = {} - - def __getitem__(self, key: _K) -> _V: - try: - return self._values[key] - except KeyError: - key = self._key_checker.CheckValue(key) - val = self._value_checker.DefaultValue() - self._values[key] = val - return val - - def __contains__(self, item: _K) -> bool: - # We check the key's type to match the strong-typing flavor of the API. - # Also this makes it easier to match the behavior of the C++ implementation. - self._key_checker.CheckValue(item) - return item in self._values - - @overload - def get(self, key: _K) -> Optional[_V]: - ... - - @overload - def get(self, key: _K, default: _T) -> Union[_V, _T]: - ... - - # We need to override this explicitly, because our defaultdict-like behavior - # will make the default implementation (from our base class) always insert - # the key. - def get(self, key, default=None): - if key in self: - return self[key] - else: - return default - - def __setitem__(self, key: _K, value: _V) -> _T: - checked_key = self._key_checker.CheckValue(key) - checked_value = self._value_checker.CheckValue(value) - self._values[checked_key] = checked_value - self._message_listener.Modified() - - def __delitem__(self, key: _K) -> None: - del self._values[key] - self._message_listener.Modified() - - def __len__(self) -> int: - return len(self._values) - - def __iter__(self) -> Iterator[_K]: - return iter(self._values) - - def __repr__(self) -> str: - return repr(self._values) - - def MergeFrom(self, other: 'ScalarMap[_K, _V]') -> None: - self._values.update(other._values) - self._message_listener.Modified() - - def InvalidateIterators(self) -> None: - # It appears that the only way to reliably invalidate iterators to - # self._values is to ensure that its size changes. - original = self._values - self._values = original.copy() - original[None] = None - - # This is defined in the abstract base, but we can do it much more cheaply. - def clear(self) -> None: - self._values.clear() - self._message_listener.Modified() - - def GetEntryClass(self) -> Any: - return self._entry_descriptor._concrete_class - - -class MessageMap(MutableMapping[_K, _V]): - """Simple, type-checked, dict-like container for with submessage values.""" - - # Disallows assignment to other attributes. - __slots__ = ['_key_checker', '_values', '_message_listener', - '_message_descriptor', '_entry_descriptor'] - - def __init__( - self, - message_listener: Any, - message_descriptor: Any, - key_checker: Any, - entry_descriptor: Any, - ) -> None: - """ - Args: - message_listener: A MessageListener implementation. - The ScalarMap will call this object's Modified() method when it - is modified. - key_checker: A type_checkers.ValueChecker instance to run on keys - inserted into this container. - value_checker: A type_checkers.ValueChecker instance to run on values - inserted into this container. - entry_descriptor: The MessageDescriptor of a map entry: key and value. - """ - self._message_listener = message_listener - self._message_descriptor = message_descriptor - self._key_checker = key_checker - self._entry_descriptor = entry_descriptor - self._values = {} - - def __getitem__(self, key: _K) -> _V: - key = self._key_checker.CheckValue(key) - try: - return self._values[key] - except KeyError: - new_element = self._message_descriptor._concrete_class() - new_element._SetListener(self._message_listener) - self._values[key] = new_element - self._message_listener.Modified() - return new_element - - def get_or_create(self, key: _K) -> _V: - """get_or_create() is an alias for getitem (ie. map[key]). - - Args: - key: The key to get or create in the map. - - This is useful in cases where you want to be explicit that the call is - mutating the map. This can avoid lint errors for statements like this - that otherwise would appear to be pointless statements: - - msg.my_map[key] - """ - return self[key] - - @overload - def get(self, key: _K) -> Optional[_V]: - ... - - @overload - def get(self, key: _K, default: _T) -> Union[_V, _T]: - ... - - # We need to override this explicitly, because our defaultdict-like behavior - # will make the default implementation (from our base class) always insert - # the key. - def get(self, key, default=None): - if key in self: - return self[key] - else: - return default - - def __contains__(self, item: _K) -> bool: - item = self._key_checker.CheckValue(item) - return item in self._values - - def __setitem__(self, key: _K, value: _V) -> NoReturn: - raise ValueError('May not set values directly, call my_map[key].foo = 5') - - def __delitem__(self, key: _K) -> None: - key = self._key_checker.CheckValue(key) - del self._values[key] - self._message_listener.Modified() - - def __len__(self) -> int: - return len(self._values) - - def __iter__(self) -> Iterator[_K]: - return iter(self._values) - - def __repr__(self) -> str: - return repr(self._values) - - def MergeFrom(self, other: 'MessageMap[_K, _V]') -> None: - # pylint: disable=protected-access - for key in other._values: - # According to documentation: "When parsing from the wire or when merging, - # if there are duplicate map keys the last key seen is used". - if key in self: - del self[key] - self[key].CopyFrom(other[key]) - # self._message_listener.Modified() not required here, because - # mutations to submessages already propagate. - - def InvalidateIterators(self) -> None: - # It appears that the only way to reliably invalidate iterators to - # self._values is to ensure that its size changes. - original = self._values - self._values = original.copy() - original[None] = None - - # This is defined in the abstract base, but we can do it much more cheaply. - def clear(self) -> None: - self._values.clear() - self._message_listener.Modified() - - def GetEntryClass(self) -> Any: - return self._entry_descriptor._concrete_class - - -class _UnknownField: - """A parsed unknown field.""" - - # Disallows assignment to other attributes. - __slots__ = ['_field_number', '_wire_type', '_data'] - - def __init__(self, field_number, wire_type, data): - self._field_number = field_number - self._wire_type = wire_type - self._data = data - return - - def __lt__(self, other): - # pylint: disable=protected-access - return self._field_number < other._field_number - - def __eq__(self, other): - if self is other: - return True - # pylint: disable=protected-access - return (self._field_number == other._field_number and - self._wire_type == other._wire_type and - self._data == other._data) - - -class UnknownFieldRef: # pylint: disable=missing-class-docstring - - def __init__(self, parent, index): - self._parent = parent - self._index = index - - def _check_valid(self): - if not self._parent: - raise ValueError('UnknownField does not exist. ' - 'The parent message might be cleared.') - if self._index >= len(self._parent): - raise ValueError('UnknownField does not exist. ' - 'The parent message might be cleared.') - - @property - def field_number(self): - self._check_valid() - # pylint: disable=protected-access - return self._parent._internal_get(self._index)._field_number - - @property - def wire_type(self): - self._check_valid() - # pylint: disable=protected-access - return self._parent._internal_get(self._index)._wire_type - - @property - def data(self): - self._check_valid() - # pylint: disable=protected-access - return self._parent._internal_get(self._index)._data - - -class UnknownFieldSet: - """UnknownField container""" - - # Disallows assignment to other attributes. - __slots__ = ['_values'] - - def __init__(self): - self._values = [] - - def __getitem__(self, index): - if self._values is None: - raise ValueError('UnknownFields does not exist. ' - 'The parent message might be cleared.') - size = len(self._values) - if index < 0: - index += size - if index < 0 or index >= size: - raise IndexError('index %d out of range'.index) - - return UnknownFieldRef(self, index) - - def _internal_get(self, index): - return self._values[index] - - def __len__(self): - if self._values is None: - raise ValueError('UnknownFields does not exist. ' - 'The parent message might be cleared.') - return len(self._values) - - def _add(self, field_number, wire_type, data): - unknown_field = _UnknownField(field_number, wire_type, data) - self._values.append(unknown_field) - return unknown_field - - def __iter__(self): - for i in range(len(self)): - yield UnknownFieldRef(self, i) - - def _extend(self, other): - if other is None: - return - # pylint: disable=protected-access - self._values.extend(other._values) - - def __eq__(self, other): - if self is other: - return True - # Sort unknown fields because their order shouldn't - # affect equality test. - values = list(self._values) - if other is None: - return not values - values.sort() - # pylint: disable=protected-access - other_values = sorted(other._values) - return values == other_values - - def _clear(self): - for value in self._values: - # pylint: disable=protected-access - if isinstance(value._data, UnknownFieldSet): - value._data._clear() # pylint: disable=protected-access - self._values = None diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/decoder.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/decoder.py deleted file mode 100644 index bc1b7b785c..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/decoder.py +++ /dev/null @@ -1,1029 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Code for decoding protocol buffer primitives. - -This code is very similar to encoder.py -- read the docs for that module first. - -A "decoder" is a function with the signature: - Decode(buffer, pos, end, message, field_dict) -The arguments are: - buffer: The string containing the encoded message. - pos: The current position in the string. - end: The position in the string where the current message ends. May be - less than len(buffer) if we're reading a sub-message. - message: The message object into which we're parsing. - field_dict: message._fields (avoids a hashtable lookup). -The decoder reads the field and stores it into field_dict, returning the new -buffer position. A decoder for a repeated field may proactively decode all of -the elements of that field, if they appear consecutively. - -Note that decoders may throw any of the following: - IndexError: Indicates a truncated message. - struct.error: Unpacking of a fixed-width field failed. - message.DecodeError: Other errors. - -Decoders are expected to raise an exception if they are called with pos > end. -This allows callers to be lax about bounds checking: it's fineto read past -"end" as long as you are sure that someone else will notice and throw an -exception later on. - -Something up the call stack is expected to catch IndexError and struct.error -and convert them to message.DecodeError. - -Decoders are constructed using decoder constructors with the signature: - MakeDecoder(field_number, is_repeated, is_packed, key, new_default) -The arguments are: - field_number: The field number of the field we want to decode. - is_repeated: Is the field a repeated field? (bool) - is_packed: Is the field a packed field? (bool) - key: The key to use when looking up the field within field_dict. - (This is actually the FieldDescriptor but nothing in this - file should depend on that.) - new_default: A function which takes a message object as a parameter and - returns a new instance of the default value for this field. - (This is called for repeated fields and sub-messages, when an - instance does not already exist.) - -As with encoders, we define a decoder constructor for every type of field. -Then, for every field of every message class we construct an actual decoder. -That decoder goes into a dict indexed by tag, so when we decode a message -we repeatedly read a tag, look up the corresponding decoder, and invoke it. -""" - -__author__ = 'kenton@google.com (Kenton Varda)' - -import math -import struct - -from google.protobuf.internal import containers -from google.protobuf.internal import encoder -from google.protobuf.internal import wire_format -from google.protobuf import message - - -# This is not for optimization, but rather to avoid conflicts with local -# variables named "message". -_DecodeError = message.DecodeError - - -def _VarintDecoder(mask, result_type): - """Return an encoder for a basic varint value (does not include tag). - - Decoded values will be bitwise-anded with the given mask before being - returned, e.g. to limit them to 32 bits. The returned decoder does not - take the usual "end" parameter -- the caller is expected to do bounds checking - after the fact (often the caller can defer such checking until later). The - decoder returns a (value, new_pos) pair. - """ - - def DecodeVarint(buffer, pos): - result = 0 - shift = 0 - while 1: - b = buffer[pos] - result |= ((b & 0x7f) << shift) - pos += 1 - if not (b & 0x80): - result &= mask - result = result_type(result) - return (result, pos) - shift += 7 - if shift >= 64: - raise _DecodeError('Too many bytes when decoding varint.') - return DecodeVarint - - -def _SignedVarintDecoder(bits, result_type): - """Like _VarintDecoder() but decodes signed values.""" - - signbit = 1 << (bits - 1) - mask = (1 << bits) - 1 - - def DecodeVarint(buffer, pos): - result = 0 - shift = 0 - while 1: - b = buffer[pos] - result |= ((b & 0x7f) << shift) - pos += 1 - if not (b & 0x80): - result &= mask - result = (result ^ signbit) - signbit - result = result_type(result) - return (result, pos) - shift += 7 - if shift >= 64: - raise _DecodeError('Too many bytes when decoding varint.') - return DecodeVarint - -# All 32-bit and 64-bit values are represented as int. -_DecodeVarint = _VarintDecoder((1 << 64) - 1, int) -_DecodeSignedVarint = _SignedVarintDecoder(64, int) - -# Use these versions for values which must be limited to 32 bits. -_DecodeVarint32 = _VarintDecoder((1 << 32) - 1, int) -_DecodeSignedVarint32 = _SignedVarintDecoder(32, int) - - -def ReadTag(buffer, pos): - """Read a tag from the memoryview, and return a (tag_bytes, new_pos) tuple. - - We return the raw bytes of the tag rather than decoding them. The raw - bytes can then be used to look up the proper decoder. This effectively allows - us to trade some work that would be done in pure-python (decoding a varint) - for work that is done in C (searching for a byte string in a hash table). - In a low-level language it would be much cheaper to decode the varint and - use that, but not in Python. - - Args: - buffer: memoryview object of the encoded bytes - pos: int of the current position to start from - - Returns: - Tuple[bytes, int] of the tag data and new position. - """ - start = pos - while buffer[pos] & 0x80: - pos += 1 - pos += 1 - - tag_bytes = buffer[start:pos].tobytes() - return tag_bytes, pos - - -# -------------------------------------------------------------------- - - -def _SimpleDecoder(wire_type, decode_value): - """Return a constructor for a decoder for fields of a particular type. - - Args: - wire_type: The field's wire type. - decode_value: A function which decodes an individual value, e.g. - _DecodeVarint() - """ - - def SpecificDecoder(field_number, is_repeated, is_packed, key, new_default, - clear_if_default=False): - if is_packed: - local_DecodeVarint = _DecodeVarint - def DecodePackedField(buffer, pos, end, message, field_dict): - value = field_dict.get(key) - if value is None: - value = field_dict.setdefault(key, new_default(message)) - (endpoint, pos) = local_DecodeVarint(buffer, pos) - endpoint += pos - if endpoint > end: - raise _DecodeError('Truncated message.') - while pos < endpoint: - (element, pos) = decode_value(buffer, pos) - value.append(element) - if pos > endpoint: - del value[-1] # Discard corrupt value. - raise _DecodeError('Packed element was truncated.') - return pos - return DecodePackedField - elif is_repeated: - tag_bytes = encoder.TagBytes(field_number, wire_type) - tag_len = len(tag_bytes) - def DecodeRepeatedField(buffer, pos, end, message, field_dict): - value = field_dict.get(key) - if value is None: - value = field_dict.setdefault(key, new_default(message)) - while 1: - (element, new_pos) = decode_value(buffer, pos) - value.append(element) - # Predict that the next tag is another copy of the same repeated - # field. - pos = new_pos + tag_len - if buffer[new_pos:pos] != tag_bytes or new_pos >= end: - # Prediction failed. Return. - if new_pos > end: - raise _DecodeError('Truncated message.') - return new_pos - return DecodeRepeatedField - else: - def DecodeField(buffer, pos, end, message, field_dict): - (new_value, pos) = decode_value(buffer, pos) - if pos > end: - raise _DecodeError('Truncated message.') - if clear_if_default and not new_value: - field_dict.pop(key, None) - else: - field_dict[key] = new_value - return pos - return DecodeField - - return SpecificDecoder - - -def _ModifiedDecoder(wire_type, decode_value, modify_value): - """Like SimpleDecoder but additionally invokes modify_value on every value - before storing it. Usually modify_value is ZigZagDecode. - """ - - # Reusing _SimpleDecoder is slightly slower than copying a bunch of code, but - # not enough to make a significant difference. - - def InnerDecode(buffer, pos): - (result, new_pos) = decode_value(buffer, pos) - return (modify_value(result), new_pos) - return _SimpleDecoder(wire_type, InnerDecode) - - -def _StructPackDecoder(wire_type, format): - """Return a constructor for a decoder for a fixed-width field. - - Args: - wire_type: The field's wire type. - format: The format string to pass to struct.unpack(). - """ - - value_size = struct.calcsize(format) - local_unpack = struct.unpack - - # Reusing _SimpleDecoder is slightly slower than copying a bunch of code, but - # not enough to make a significant difference. - - # Note that we expect someone up-stack to catch struct.error and convert - # it to _DecodeError -- this way we don't have to set up exception- - # handling blocks every time we parse one value. - - def InnerDecode(buffer, pos): - new_pos = pos + value_size - result = local_unpack(format, buffer[pos:new_pos])[0] - return (result, new_pos) - return _SimpleDecoder(wire_type, InnerDecode) - - -def _FloatDecoder(): - """Returns a decoder for a float field. - - This code works around a bug in struct.unpack for non-finite 32-bit - floating-point values. - """ - - local_unpack = struct.unpack - - def InnerDecode(buffer, pos): - """Decode serialized float to a float and new position. - - Args: - buffer: memoryview of the serialized bytes - pos: int, position in the memory view to start at. - - Returns: - Tuple[float, int] of the deserialized float value and new position - in the serialized data. - """ - # We expect a 32-bit value in little-endian byte order. Bit 1 is the sign - # bit, bits 2-9 represent the exponent, and bits 10-32 are the significand. - new_pos = pos + 4 - float_bytes = buffer[pos:new_pos].tobytes() - - # If this value has all its exponent bits set, then it's non-finite. - # In Python 2.4, struct.unpack will convert it to a finite 64-bit value. - # To avoid that, we parse it specially. - if (float_bytes[3:4] in b'\x7F\xFF' and float_bytes[2:3] >= b'\x80'): - # If at least one significand bit is set... - if float_bytes[0:3] != b'\x00\x00\x80': - return (math.nan, new_pos) - # If sign bit is set... - if float_bytes[3:4] == b'\xFF': - return (-math.inf, new_pos) - return (math.inf, new_pos) - - # Note that we expect someone up-stack to catch struct.error and convert - # it to _DecodeError -- this way we don't have to set up exception- - # handling blocks every time we parse one value. - result = local_unpack('= b'\xF0') - and (double_bytes[0:7] != b'\x00\x00\x00\x00\x00\x00\xF0')): - return (math.nan, new_pos) - - # Note that we expect someone up-stack to catch struct.error and convert - # it to _DecodeError -- this way we don't have to set up exception- - # handling blocks every time we parse one value. - result = local_unpack(' end: - raise _DecodeError('Truncated message.') - while pos < endpoint: - value_start_pos = pos - (element, pos) = _DecodeSignedVarint32(buffer, pos) - # pylint: disable=protected-access - if element in enum_type.values_by_number: - value.append(element) - else: - if not message._unknown_fields: - message._unknown_fields = [] - tag_bytes = encoder.TagBytes(field_number, - wire_format.WIRETYPE_VARINT) - - message._unknown_fields.append( - (tag_bytes, buffer[value_start_pos:pos].tobytes())) - if message._unknown_field_set is None: - message._unknown_field_set = containers.UnknownFieldSet() - message._unknown_field_set._add( - field_number, wire_format.WIRETYPE_VARINT, element) - # pylint: enable=protected-access - if pos > endpoint: - if element in enum_type.values_by_number: - del value[-1] # Discard corrupt value. - else: - del message._unknown_fields[-1] - # pylint: disable=protected-access - del message._unknown_field_set._values[-1] - # pylint: enable=protected-access - raise _DecodeError('Packed element was truncated.') - return pos - return DecodePackedField - elif is_repeated: - tag_bytes = encoder.TagBytes(field_number, wire_format.WIRETYPE_VARINT) - tag_len = len(tag_bytes) - def DecodeRepeatedField(buffer, pos, end, message, field_dict): - """Decode serialized repeated enum to its value and a new position. - - Args: - buffer: memoryview of the serialized bytes. - pos: int, position in the memory view to start at. - end: int, end position of serialized data - message: Message object to store unknown fields in - field_dict: Map[Descriptor, Any] to store decoded values in. - - Returns: - int, new position in serialized data. - """ - value = field_dict.get(key) - if value is None: - value = field_dict.setdefault(key, new_default(message)) - while 1: - (element, new_pos) = _DecodeSignedVarint32(buffer, pos) - # pylint: disable=protected-access - if element in enum_type.values_by_number: - value.append(element) - else: - if not message._unknown_fields: - message._unknown_fields = [] - message._unknown_fields.append( - (tag_bytes, buffer[pos:new_pos].tobytes())) - if message._unknown_field_set is None: - message._unknown_field_set = containers.UnknownFieldSet() - message._unknown_field_set._add( - field_number, wire_format.WIRETYPE_VARINT, element) - # pylint: enable=protected-access - # Predict that the next tag is another copy of the same repeated - # field. - pos = new_pos + tag_len - if buffer[new_pos:pos] != tag_bytes or new_pos >= end: - # Prediction failed. Return. - if new_pos > end: - raise _DecodeError('Truncated message.') - return new_pos - return DecodeRepeatedField - else: - def DecodeField(buffer, pos, end, message, field_dict): - """Decode serialized repeated enum to its value and a new position. - - Args: - buffer: memoryview of the serialized bytes. - pos: int, position in the memory view to start at. - end: int, end position of serialized data - message: Message object to store unknown fields in - field_dict: Map[Descriptor, Any] to store decoded values in. - - Returns: - int, new position in serialized data. - """ - value_start_pos = pos - (enum_value, pos) = _DecodeSignedVarint32(buffer, pos) - if pos > end: - raise _DecodeError('Truncated message.') - if clear_if_default and not enum_value: - field_dict.pop(key, None) - return pos - # pylint: disable=protected-access - if enum_value in enum_type.values_by_number: - field_dict[key] = enum_value - else: - if not message._unknown_fields: - message._unknown_fields = [] - tag_bytes = encoder.TagBytes(field_number, - wire_format.WIRETYPE_VARINT) - message._unknown_fields.append( - (tag_bytes, buffer[value_start_pos:pos].tobytes())) - if message._unknown_field_set is None: - message._unknown_field_set = containers.UnknownFieldSet() - message._unknown_field_set._add( - field_number, wire_format.WIRETYPE_VARINT, enum_value) - # pylint: enable=protected-access - return pos - return DecodeField - - -# -------------------------------------------------------------------- - - -Int32Decoder = _SimpleDecoder( - wire_format.WIRETYPE_VARINT, _DecodeSignedVarint32) - -Int64Decoder = _SimpleDecoder( - wire_format.WIRETYPE_VARINT, _DecodeSignedVarint) - -UInt32Decoder = _SimpleDecoder(wire_format.WIRETYPE_VARINT, _DecodeVarint32) -UInt64Decoder = _SimpleDecoder(wire_format.WIRETYPE_VARINT, _DecodeVarint) - -SInt32Decoder = _ModifiedDecoder( - wire_format.WIRETYPE_VARINT, _DecodeVarint32, wire_format.ZigZagDecode) -SInt64Decoder = _ModifiedDecoder( - wire_format.WIRETYPE_VARINT, _DecodeVarint, wire_format.ZigZagDecode) - -# Note that Python conveniently guarantees that when using the '<' prefix on -# formats, they will also have the same size across all platforms (as opposed -# to without the prefix, where their sizes depend on the C compiler's basic -# type sizes). -Fixed32Decoder = _StructPackDecoder(wire_format.WIRETYPE_FIXED32, ' end: - raise _DecodeError('Truncated string.') - value.append(_ConvertToUnicode(buffer[pos:new_pos])) - # Predict that the next tag is another copy of the same repeated field. - pos = new_pos + tag_len - if buffer[new_pos:pos] != tag_bytes or new_pos == end: - # Prediction failed. Return. - return new_pos - return DecodeRepeatedField - else: - def DecodeField(buffer, pos, end, message, field_dict): - (size, pos) = local_DecodeVarint(buffer, pos) - new_pos = pos + size - if new_pos > end: - raise _DecodeError('Truncated string.') - if clear_if_default and not size: - field_dict.pop(key, None) - else: - field_dict[key] = _ConvertToUnicode(buffer[pos:new_pos]) - return new_pos - return DecodeField - - -def BytesDecoder(field_number, is_repeated, is_packed, key, new_default, - clear_if_default=False): - """Returns a decoder for a bytes field.""" - - local_DecodeVarint = _DecodeVarint - - assert not is_packed - if is_repeated: - tag_bytes = encoder.TagBytes(field_number, - wire_format.WIRETYPE_LENGTH_DELIMITED) - tag_len = len(tag_bytes) - def DecodeRepeatedField(buffer, pos, end, message, field_dict): - value = field_dict.get(key) - if value is None: - value = field_dict.setdefault(key, new_default(message)) - while 1: - (size, pos) = local_DecodeVarint(buffer, pos) - new_pos = pos + size - if new_pos > end: - raise _DecodeError('Truncated string.') - value.append(buffer[pos:new_pos].tobytes()) - # Predict that the next tag is another copy of the same repeated field. - pos = new_pos + tag_len - if buffer[new_pos:pos] != tag_bytes or new_pos == end: - # Prediction failed. Return. - return new_pos - return DecodeRepeatedField - else: - def DecodeField(buffer, pos, end, message, field_dict): - (size, pos) = local_DecodeVarint(buffer, pos) - new_pos = pos + size - if new_pos > end: - raise _DecodeError('Truncated string.') - if clear_if_default and not size: - field_dict.pop(key, None) - else: - field_dict[key] = buffer[pos:new_pos].tobytes() - return new_pos - return DecodeField - - -def GroupDecoder(field_number, is_repeated, is_packed, key, new_default): - """Returns a decoder for a group field.""" - - end_tag_bytes = encoder.TagBytes(field_number, - wire_format.WIRETYPE_END_GROUP) - end_tag_len = len(end_tag_bytes) - - assert not is_packed - if is_repeated: - tag_bytes = encoder.TagBytes(field_number, - wire_format.WIRETYPE_START_GROUP) - tag_len = len(tag_bytes) - def DecodeRepeatedField(buffer, pos, end, message, field_dict): - value = field_dict.get(key) - if value is None: - value = field_dict.setdefault(key, new_default(message)) - while 1: - value = field_dict.get(key) - if value is None: - value = field_dict.setdefault(key, new_default(message)) - # Read sub-message. - pos = value.add()._InternalParse(buffer, pos, end) - # Read end tag. - new_pos = pos+end_tag_len - if buffer[pos:new_pos] != end_tag_bytes or new_pos > end: - raise _DecodeError('Missing group end tag.') - # Predict that the next tag is another copy of the same repeated field. - pos = new_pos + tag_len - if buffer[new_pos:pos] != tag_bytes or new_pos == end: - # Prediction failed. Return. - return new_pos - return DecodeRepeatedField - else: - def DecodeField(buffer, pos, end, message, field_dict): - value = field_dict.get(key) - if value is None: - value = field_dict.setdefault(key, new_default(message)) - # Read sub-message. - pos = value._InternalParse(buffer, pos, end) - # Read end tag. - new_pos = pos+end_tag_len - if buffer[pos:new_pos] != end_tag_bytes or new_pos > end: - raise _DecodeError('Missing group end tag.') - return new_pos - return DecodeField - - -def MessageDecoder(field_number, is_repeated, is_packed, key, new_default): - """Returns a decoder for a message field.""" - - local_DecodeVarint = _DecodeVarint - - assert not is_packed - if is_repeated: - tag_bytes = encoder.TagBytes(field_number, - wire_format.WIRETYPE_LENGTH_DELIMITED) - tag_len = len(tag_bytes) - def DecodeRepeatedField(buffer, pos, end, message, field_dict): - value = field_dict.get(key) - if value is None: - value = field_dict.setdefault(key, new_default(message)) - while 1: - # Read length. - (size, pos) = local_DecodeVarint(buffer, pos) - new_pos = pos + size - if new_pos > end: - raise _DecodeError('Truncated message.') - # Read sub-message. - if value.add()._InternalParse(buffer, pos, new_pos) != new_pos: - # The only reason _InternalParse would return early is if it - # encountered an end-group tag. - raise _DecodeError('Unexpected end-group tag.') - # Predict that the next tag is another copy of the same repeated field. - pos = new_pos + tag_len - if buffer[new_pos:pos] != tag_bytes or new_pos == end: - # Prediction failed. Return. - return new_pos - return DecodeRepeatedField - else: - def DecodeField(buffer, pos, end, message, field_dict): - value = field_dict.get(key) - if value is None: - value = field_dict.setdefault(key, new_default(message)) - # Read length. - (size, pos) = local_DecodeVarint(buffer, pos) - new_pos = pos + size - if new_pos > end: - raise _DecodeError('Truncated message.') - # Read sub-message. - if value._InternalParse(buffer, pos, new_pos) != new_pos: - # The only reason _InternalParse would return early is if it encountered - # an end-group tag. - raise _DecodeError('Unexpected end-group tag.') - return new_pos - return DecodeField - - -# -------------------------------------------------------------------- - -MESSAGE_SET_ITEM_TAG = encoder.TagBytes(1, wire_format.WIRETYPE_START_GROUP) - -def MessageSetItemDecoder(descriptor): - """Returns a decoder for a MessageSet item. - - The parameter is the message Descriptor. - - The message set message looks like this: - message MessageSet { - repeated group Item = 1 { - required int32 type_id = 2; - required string message = 3; - } - } - """ - - type_id_tag_bytes = encoder.TagBytes(2, wire_format.WIRETYPE_VARINT) - message_tag_bytes = encoder.TagBytes(3, wire_format.WIRETYPE_LENGTH_DELIMITED) - item_end_tag_bytes = encoder.TagBytes(1, wire_format.WIRETYPE_END_GROUP) - - local_ReadTag = ReadTag - local_DecodeVarint = _DecodeVarint - local_SkipField = SkipField - - def DecodeItem(buffer, pos, end, message, field_dict): - """Decode serialized message set to its value and new position. - - Args: - buffer: memoryview of the serialized bytes. - pos: int, position in the memory view to start at. - end: int, end position of serialized data - message: Message object to store unknown fields in - field_dict: Map[Descriptor, Any] to store decoded values in. - - Returns: - int, new position in serialized data. - """ - message_set_item_start = pos - type_id = -1 - message_start = -1 - message_end = -1 - - # Technically, type_id and message can appear in any order, so we need - # a little loop here. - while 1: - (tag_bytes, pos) = local_ReadTag(buffer, pos) - if tag_bytes == type_id_tag_bytes: - (type_id, pos) = local_DecodeVarint(buffer, pos) - elif tag_bytes == message_tag_bytes: - (size, message_start) = local_DecodeVarint(buffer, pos) - pos = message_end = message_start + size - elif tag_bytes == item_end_tag_bytes: - break - else: - pos = SkipField(buffer, pos, end, tag_bytes) - if pos == -1: - raise _DecodeError('Missing group end tag.') - - if pos > end: - raise _DecodeError('Truncated message.') - - if type_id == -1: - raise _DecodeError('MessageSet item missing type_id.') - if message_start == -1: - raise _DecodeError('MessageSet item missing message.') - - extension = message.Extensions._FindExtensionByNumber(type_id) - # pylint: disable=protected-access - if extension is not None: - value = field_dict.get(extension) - if value is None: - message_type = extension.message_type - if not hasattr(message_type, '_concrete_class'): - # pylint: disable=protected-access - message._FACTORY.GetPrototype(message_type) - value = field_dict.setdefault( - extension, message_type._concrete_class()) - if value._InternalParse(buffer, message_start,message_end) != message_end: - # The only reason _InternalParse would return early is if it encountered - # an end-group tag. - raise _DecodeError('Unexpected end-group tag.') - else: - if not message._unknown_fields: - message._unknown_fields = [] - message._unknown_fields.append( - (MESSAGE_SET_ITEM_TAG, buffer[message_set_item_start:pos].tobytes())) - if message._unknown_field_set is None: - message._unknown_field_set = containers.UnknownFieldSet() - message._unknown_field_set._add( - type_id, - wire_format.WIRETYPE_LENGTH_DELIMITED, - buffer[message_start:message_end].tobytes()) - # pylint: enable=protected-access - - return pos - - return DecodeItem - -# -------------------------------------------------------------------- - -def MapDecoder(field_descriptor, new_default, is_message_map): - """Returns a decoder for a map field.""" - - key = field_descriptor - tag_bytes = encoder.TagBytes(field_descriptor.number, - wire_format.WIRETYPE_LENGTH_DELIMITED) - tag_len = len(tag_bytes) - local_DecodeVarint = _DecodeVarint - # Can't read _concrete_class yet; might not be initialized. - message_type = field_descriptor.message_type - - def DecodeMap(buffer, pos, end, message, field_dict): - submsg = message_type._concrete_class() - value = field_dict.get(key) - if value is None: - value = field_dict.setdefault(key, new_default(message)) - while 1: - # Read length. - (size, pos) = local_DecodeVarint(buffer, pos) - new_pos = pos + size - if new_pos > end: - raise _DecodeError('Truncated message.') - # Read sub-message. - submsg.Clear() - if submsg._InternalParse(buffer, pos, new_pos) != new_pos: - # The only reason _InternalParse would return early is if it - # encountered an end-group tag. - raise _DecodeError('Unexpected end-group tag.') - - if is_message_map: - value[submsg.key].CopyFrom(submsg.value) - else: - value[submsg.key] = submsg.value - - # Predict that the next tag is another copy of the same repeated field. - pos = new_pos + tag_len - if buffer[new_pos:pos] != tag_bytes or new_pos == end: - # Prediction failed. Return. - return new_pos - - return DecodeMap - -# -------------------------------------------------------------------- -# Optimization is not as heavy here because calls to SkipField() are rare, -# except for handling end-group tags. - -def _SkipVarint(buffer, pos, end): - """Skip a varint value. Returns the new position.""" - # Previously ord(buffer[pos]) raised IndexError when pos is out of range. - # With this code, ord(b'') raises TypeError. Both are handled in - # python_message.py to generate a 'Truncated message' error. - while ord(buffer[pos:pos+1].tobytes()) & 0x80: - pos += 1 - pos += 1 - if pos > end: - raise _DecodeError('Truncated message.') - return pos - -def _SkipFixed64(buffer, pos, end): - """Skip a fixed64 value. Returns the new position.""" - - pos += 8 - if pos > end: - raise _DecodeError('Truncated message.') - return pos - - -def _DecodeFixed64(buffer, pos): - """Decode a fixed64.""" - new_pos = pos + 8 - return (struct.unpack(' end: - raise _DecodeError('Truncated message.') - return pos - - -def _SkipGroup(buffer, pos, end): - """Skip sub-group. Returns the new position.""" - - while 1: - (tag_bytes, pos) = ReadTag(buffer, pos) - new_pos = SkipField(buffer, pos, end, tag_bytes) - if new_pos == -1: - return pos - pos = new_pos - - -def _DecodeUnknownFieldSet(buffer, pos, end_pos=None): - """Decode UnknownFieldSet. Returns the UnknownFieldSet and new position.""" - - unknown_field_set = containers.UnknownFieldSet() - while end_pos is None or pos < end_pos: - (tag_bytes, pos) = ReadTag(buffer, pos) - (tag, _) = _DecodeVarint(tag_bytes, 0) - field_number, wire_type = wire_format.UnpackTag(tag) - if wire_type == wire_format.WIRETYPE_END_GROUP: - break - (data, pos) = _DecodeUnknownField(buffer, pos, wire_type) - # pylint: disable=protected-access - unknown_field_set._add(field_number, wire_type, data) - - return (unknown_field_set, pos) - - -def _DecodeUnknownField(buffer, pos, wire_type): - """Decode a unknown field. Returns the UnknownField and new position.""" - - if wire_type == wire_format.WIRETYPE_VARINT: - (data, pos) = _DecodeVarint(buffer, pos) - elif wire_type == wire_format.WIRETYPE_FIXED64: - (data, pos) = _DecodeFixed64(buffer, pos) - elif wire_type == wire_format.WIRETYPE_FIXED32: - (data, pos) = _DecodeFixed32(buffer, pos) - elif wire_type == wire_format.WIRETYPE_LENGTH_DELIMITED: - (size, pos) = _DecodeVarint(buffer, pos) - data = buffer[pos:pos+size].tobytes() - pos += size - elif wire_type == wire_format.WIRETYPE_START_GROUP: - (data, pos) = _DecodeUnknownFieldSet(buffer, pos) - elif wire_type == wire_format.WIRETYPE_END_GROUP: - return (0, -1) - else: - raise _DecodeError('Wrong wire type in tag.') - - return (data, pos) - - -def _EndGroup(buffer, pos, end): - """Skipping an END_GROUP tag returns -1 to tell the parent loop to break.""" - - return -1 - - -def _SkipFixed32(buffer, pos, end): - """Skip a fixed32 value. Returns the new position.""" - - pos += 4 - if pos > end: - raise _DecodeError('Truncated message.') - return pos - - -def _DecodeFixed32(buffer, pos): - """Decode a fixed32.""" - - new_pos = pos + 4 - return (struct.unpack('B').pack - - def EncodeVarint(write, value, unused_deterministic=None): - bits = value & 0x7f - value >>= 7 - while value: - write(local_int2byte(0x80|bits)) - bits = value & 0x7f - value >>= 7 - return write(local_int2byte(bits)) - - return EncodeVarint - - -def _SignedVarintEncoder(): - """Return an encoder for a basic signed varint value (does not include - tag).""" - - local_int2byte = struct.Struct('>B').pack - - def EncodeSignedVarint(write, value, unused_deterministic=None): - if value < 0: - value += (1 << 64) - bits = value & 0x7f - value >>= 7 - while value: - write(local_int2byte(0x80|bits)) - bits = value & 0x7f - value >>= 7 - return write(local_int2byte(bits)) - - return EncodeSignedVarint - - -_EncodeVarint = _VarintEncoder() -_EncodeSignedVarint = _SignedVarintEncoder() - - -def _VarintBytes(value): - """Encode the given integer as a varint and return the bytes. This is only - called at startup time so it doesn't need to be fast.""" - - pieces = [] - _EncodeVarint(pieces.append, value, True) - return b"".join(pieces) - - -def TagBytes(field_number, wire_type): - """Encode the given tag and return the bytes. Only called at startup.""" - - return bytes(_VarintBytes(wire_format.PackTag(field_number, wire_type))) - -# -------------------------------------------------------------------- -# As with sizers (see above), we have a number of common encoder -# implementations. - - -def _SimpleEncoder(wire_type, encode_value, compute_value_size): - """Return a constructor for an encoder for fields of a particular type. - - Args: - wire_type: The field's wire type, for encoding tags. - encode_value: A function which encodes an individual value, e.g. - _EncodeVarint(). - compute_value_size: A function which computes the size of an individual - value, e.g. _VarintSize(). - """ - - def SpecificEncoder(field_number, is_repeated, is_packed): - if is_packed: - tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) - local_EncodeVarint = _EncodeVarint - def EncodePackedField(write, value, deterministic): - write(tag_bytes) - size = 0 - for element in value: - size += compute_value_size(element) - local_EncodeVarint(write, size, deterministic) - for element in value: - encode_value(write, element, deterministic) - return EncodePackedField - elif is_repeated: - tag_bytes = TagBytes(field_number, wire_type) - def EncodeRepeatedField(write, value, deterministic): - for element in value: - write(tag_bytes) - encode_value(write, element, deterministic) - return EncodeRepeatedField - else: - tag_bytes = TagBytes(field_number, wire_type) - def EncodeField(write, value, deterministic): - write(tag_bytes) - return encode_value(write, value, deterministic) - return EncodeField - - return SpecificEncoder - - -def _ModifiedEncoder(wire_type, encode_value, compute_value_size, modify_value): - """Like SimpleEncoder but additionally invokes modify_value on every value - before passing it to encode_value. Usually modify_value is ZigZagEncode.""" - - def SpecificEncoder(field_number, is_repeated, is_packed): - if is_packed: - tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) - local_EncodeVarint = _EncodeVarint - def EncodePackedField(write, value, deterministic): - write(tag_bytes) - size = 0 - for element in value: - size += compute_value_size(modify_value(element)) - local_EncodeVarint(write, size, deterministic) - for element in value: - encode_value(write, modify_value(element), deterministic) - return EncodePackedField - elif is_repeated: - tag_bytes = TagBytes(field_number, wire_type) - def EncodeRepeatedField(write, value, deterministic): - for element in value: - write(tag_bytes) - encode_value(write, modify_value(element), deterministic) - return EncodeRepeatedField - else: - tag_bytes = TagBytes(field_number, wire_type) - def EncodeField(write, value, deterministic): - write(tag_bytes) - return encode_value(write, modify_value(value), deterministic) - return EncodeField - - return SpecificEncoder - - -def _StructPackEncoder(wire_type, format): - """Return a constructor for an encoder for a fixed-width field. - - Args: - wire_type: The field's wire type, for encoding tags. - format: The format string to pass to struct.pack(). - """ - - value_size = struct.calcsize(format) - - def SpecificEncoder(field_number, is_repeated, is_packed): - local_struct_pack = struct.pack - if is_packed: - tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) - local_EncodeVarint = _EncodeVarint - def EncodePackedField(write, value, deterministic): - write(tag_bytes) - local_EncodeVarint(write, len(value) * value_size, deterministic) - for element in value: - write(local_struct_pack(format, element)) - return EncodePackedField - elif is_repeated: - tag_bytes = TagBytes(field_number, wire_type) - def EncodeRepeatedField(write, value, unused_deterministic=None): - for element in value: - write(tag_bytes) - write(local_struct_pack(format, element)) - return EncodeRepeatedField - else: - tag_bytes = TagBytes(field_number, wire_type) - def EncodeField(write, value, unused_deterministic=None): - write(tag_bytes) - return write(local_struct_pack(format, value)) - return EncodeField - - return SpecificEncoder - - -def _FloatingPointEncoder(wire_type, format): - """Return a constructor for an encoder for float fields. - - This is like StructPackEncoder, but catches errors that may be due to - passing non-finite floating-point values to struct.pack, and makes a - second attempt to encode those values. - - Args: - wire_type: The field's wire type, for encoding tags. - format: The format string to pass to struct.pack(). - """ - - value_size = struct.calcsize(format) - if value_size == 4: - def EncodeNonFiniteOrRaise(write, value): - # Remember that the serialized form uses little-endian byte order. - if value == _POS_INF: - write(b'\x00\x00\x80\x7F') - elif value == _NEG_INF: - write(b'\x00\x00\x80\xFF') - elif value != value: # NaN - write(b'\x00\x00\xC0\x7F') - else: - raise - elif value_size == 8: - def EncodeNonFiniteOrRaise(write, value): - if value == _POS_INF: - write(b'\x00\x00\x00\x00\x00\x00\xF0\x7F') - elif value == _NEG_INF: - write(b'\x00\x00\x00\x00\x00\x00\xF0\xFF') - elif value != value: # NaN - write(b'\x00\x00\x00\x00\x00\x00\xF8\x7F') - else: - raise - else: - raise ValueError('Can\'t encode floating-point values that are ' - '%d bytes long (only 4 or 8)' % value_size) - - def SpecificEncoder(field_number, is_repeated, is_packed): - local_struct_pack = struct.pack - if is_packed: - tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) - local_EncodeVarint = _EncodeVarint - def EncodePackedField(write, value, deterministic): - write(tag_bytes) - local_EncodeVarint(write, len(value) * value_size, deterministic) - for element in value: - # This try/except block is going to be faster than any code that - # we could write to check whether element is finite. - try: - write(local_struct_pack(format, element)) - except SystemError: - EncodeNonFiniteOrRaise(write, element) - return EncodePackedField - elif is_repeated: - tag_bytes = TagBytes(field_number, wire_type) - def EncodeRepeatedField(write, value, unused_deterministic=None): - for element in value: - write(tag_bytes) - try: - write(local_struct_pack(format, element)) - except SystemError: - EncodeNonFiniteOrRaise(write, element) - return EncodeRepeatedField - else: - tag_bytes = TagBytes(field_number, wire_type) - def EncodeField(write, value, unused_deterministic=None): - write(tag_bytes) - try: - write(local_struct_pack(format, value)) - except SystemError: - EncodeNonFiniteOrRaise(write, value) - return EncodeField - - return SpecificEncoder - - -# ==================================================================== -# Here we declare an encoder constructor for each field type. These work -# very similarly to sizer constructors, described earlier. - - -Int32Encoder = Int64Encoder = EnumEncoder = _SimpleEncoder( - wire_format.WIRETYPE_VARINT, _EncodeSignedVarint, _SignedVarintSize) - -UInt32Encoder = UInt64Encoder = _SimpleEncoder( - wire_format.WIRETYPE_VARINT, _EncodeVarint, _VarintSize) - -SInt32Encoder = SInt64Encoder = _ModifiedEncoder( - wire_format.WIRETYPE_VARINT, _EncodeVarint, _VarintSize, - wire_format.ZigZagEncode) - -# Note that Python conveniently guarantees that when using the '<' prefix on -# formats, they will also have the same size across all platforms (as opposed -# to without the prefix, where their sizes depend on the C compiler's basic -# type sizes). -Fixed32Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, ' str - ValueType = int - - def __init__(self, enum_type): - """Inits EnumTypeWrapper with an EnumDescriptor.""" - self._enum_type = enum_type - self.DESCRIPTOR = enum_type # pylint: disable=invalid-name - - def Name(self, number): # pylint: disable=invalid-name - """Returns a string containing the name of an enum value.""" - try: - return self._enum_type.values_by_number[number].name - except KeyError: - pass # fall out to break exception chaining - - if not isinstance(number, int): - raise TypeError( - 'Enum value for {} must be an int, but got {} {!r}.'.format( - self._enum_type.name, type(number), number)) - else: - # repr here to handle the odd case when you pass in a boolean. - raise ValueError('Enum {} has no name defined for value {!r}'.format( - self._enum_type.name, number)) - - def Value(self, name): # pylint: disable=invalid-name - """Returns the value corresponding to the given enum name.""" - try: - return self._enum_type.values_by_name[name].number - except KeyError: - pass # fall out to break exception chaining - raise ValueError('Enum {} has no value defined for name {!r}'.format( - self._enum_type.name, name)) - - def keys(self): - """Return a list of the string names in the enum. - - Returns: - A list of strs, in the order they were defined in the .proto file. - """ - - return [value_descriptor.name - for value_descriptor in self._enum_type.values] - - def values(self): - """Return a list of the integer values in the enum. - - Returns: - A list of ints, in the order they were defined in the .proto file. - """ - - return [value_descriptor.number - for value_descriptor in self._enum_type.values] - - def items(self): - """Return a list of the (name, value) pairs of the enum. - - Returns: - A list of (str, int) pairs, in the order they were defined - in the .proto file. - """ - return [(value_descriptor.name, value_descriptor.number) - for value_descriptor in self._enum_type.values] - - def __getattr__(self, name): - """Returns the value corresponding to the given enum name.""" - try: - return super( - EnumTypeWrapper, - self).__getattribute__('_enum_type').values_by_name[name].number - except KeyError: - pass # fall out to break exception chaining - raise AttributeError('Enum {} has no value defined for name {!r}'.format( - self._enum_type.name, name)) diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/extension_dict.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/extension_dict.py deleted file mode 100644 index b346cf283e..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/extension_dict.py +++ /dev/null @@ -1,213 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Contains _ExtensionDict class to represent extensions. -""" - -from google.protobuf.internal import type_checkers -from google.protobuf.descriptor import FieldDescriptor - - -def _VerifyExtensionHandle(message, extension_handle): - """Verify that the given extension handle is valid.""" - - if not isinstance(extension_handle, FieldDescriptor): - raise KeyError('HasExtension() expects an extension handle, got: %s' % - extension_handle) - - if not extension_handle.is_extension: - raise KeyError('"%s" is not an extension.' % extension_handle.full_name) - - if not extension_handle.containing_type: - raise KeyError('"%s" is missing a containing_type.' - % extension_handle.full_name) - - if extension_handle.containing_type is not message.DESCRIPTOR: - raise KeyError('Extension "%s" extends message type "%s", but this ' - 'message is of type "%s".' % - (extension_handle.full_name, - extension_handle.containing_type.full_name, - message.DESCRIPTOR.full_name)) - - -# TODO(robinson): Unify error handling of "unknown extension" crap. -# TODO(robinson): Support iteritems()-style iteration over all -# extensions with the "has" bits turned on? -class _ExtensionDict(object): - - """Dict-like container for Extension fields on proto instances. - - Note that in all cases we expect extension handles to be - FieldDescriptors. - """ - - def __init__(self, extended_message): - """ - Args: - extended_message: Message instance for which we are the Extensions dict. - """ - self._extended_message = extended_message - - def __getitem__(self, extension_handle): - """Returns the current value of the given extension handle.""" - - _VerifyExtensionHandle(self._extended_message, extension_handle) - - result = self._extended_message._fields.get(extension_handle) - if result is not None: - return result - - if extension_handle.label == FieldDescriptor.LABEL_REPEATED: - result = extension_handle._default_constructor(self._extended_message) - elif extension_handle.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE: - message_type = extension_handle.message_type - if not hasattr(message_type, '_concrete_class'): - # pylint: disable=protected-access - self._extended_message._FACTORY.GetPrototype(message_type) - assert getattr(extension_handle.message_type, '_concrete_class', None), ( - 'Uninitialized concrete class found for field %r (message type %r)' - % (extension_handle.full_name, - extension_handle.message_type.full_name)) - result = extension_handle.message_type._concrete_class() - try: - result._SetListener(self._extended_message._listener_for_children) - except ReferenceError: - pass - else: - # Singular scalar -- just return the default without inserting into the - # dict. - return extension_handle.default_value - - # Atomically check if another thread has preempted us and, if not, swap - # in the new object we just created. If someone has preempted us, we - # take that object and discard ours. - # WARNING: We are relying on setdefault() being atomic. This is true - # in CPython but we haven't investigated others. This warning appears - # in several other locations in this file. - result = self._extended_message._fields.setdefault( - extension_handle, result) - - return result - - def __eq__(self, other): - if not isinstance(other, self.__class__): - return False - - my_fields = self._extended_message.ListFields() - other_fields = other._extended_message.ListFields() - - # Get rid of non-extension fields. - my_fields = [field for field in my_fields if field.is_extension] - other_fields = [field for field in other_fields if field.is_extension] - - return my_fields == other_fields - - def __ne__(self, other): - return not self == other - - def __len__(self): - fields = self._extended_message.ListFields() - # Get rid of non-extension fields. - extension_fields = [field for field in fields if field[0].is_extension] - return len(extension_fields) - - def __hash__(self): - raise TypeError('unhashable object') - - # Note that this is only meaningful for non-repeated, scalar extension - # fields. Note also that we may have to call _Modified() when we do - # successfully set a field this way, to set any necessary "has" bits in the - # ancestors of the extended message. - def __setitem__(self, extension_handle, value): - """If extension_handle specifies a non-repeated, scalar extension - field, sets the value of that field. - """ - - _VerifyExtensionHandle(self._extended_message, extension_handle) - - if (extension_handle.label == FieldDescriptor.LABEL_REPEATED or - extension_handle.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE): - raise TypeError( - 'Cannot assign to extension "%s" because it is a repeated or ' - 'composite type.' % extension_handle.full_name) - - # It's slightly wasteful to lookup the type checker each time, - # but we expect this to be a vanishingly uncommon case anyway. - type_checker = type_checkers.GetTypeChecker(extension_handle) - # pylint: disable=protected-access - self._extended_message._fields[extension_handle] = ( - type_checker.CheckValue(value)) - self._extended_message._Modified() - - def __delitem__(self, extension_handle): - self._extended_message.ClearExtension(extension_handle) - - def _FindExtensionByName(self, name): - """Tries to find a known extension with the specified name. - - Args: - name: Extension full name. - - Returns: - Extension field descriptor. - """ - return self._extended_message._extensions_by_name.get(name, None) - - def _FindExtensionByNumber(self, number): - """Tries to find a known extension with the field number. - - Args: - number: Extension field number. - - Returns: - Extension field descriptor. - """ - return self._extended_message._extensions_by_number.get(number, None) - - def __iter__(self): - # Return a generator over the populated extension fields - return (f[0] for f in self._extended_message.ListFields() - if f[0].is_extension) - - def __contains__(self, extension_handle): - _VerifyExtensionHandle(self._extended_message, extension_handle) - - if extension_handle not in self._extended_message._fields: - return False - - if extension_handle.label == FieldDescriptor.LABEL_REPEATED: - return bool(self._extended_message._fields.get(extension_handle)) - - if extension_handle.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE: - value = self._extended_message._fields.get(extension_handle) - # pylint: disable=protected-access - return value is not None and value._is_present_in_parent - - return True diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/message_listener.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/message_listener.py deleted file mode 100644 index 0fc255a774..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/message_listener.py +++ /dev/null @@ -1,78 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Defines a listener interface for observing certain -state transitions on Message objects. - -Also defines a null implementation of this interface. -""" - -__author__ = 'robinson@google.com (Will Robinson)' - - -class MessageListener(object): - - """Listens for modifications made to a message. Meant to be registered via - Message._SetListener(). - - Attributes: - dirty: If True, then calling Modified() would be a no-op. This can be - used to avoid these calls entirely in the common case. - """ - - def Modified(self): - """Called every time the message is modified in such a way that the parent - message may need to be updated. This currently means either: - (a) The message was modified for the first time, so the parent message - should henceforth mark the message as present. - (b) The message's cached byte size became dirty -- i.e. the message was - modified for the first time after a previous call to ByteSize(). - Therefore the parent should also mark its byte size as dirty. - Note that (a) implies (b), since new objects start out with a client cached - size (zero). However, we document (a) explicitly because it is important. - - Modified() will *only* be called in response to one of these two events -- - not every time the sub-message is modified. - - Note that if the listener's |dirty| attribute is true, then calling - Modified at the moment would be a no-op, so it can be skipped. Performance- - sensitive callers should check this attribute directly before calling since - it will be true most of the time. - """ - - raise NotImplementedError - - -class NullMessageListener(object): - - """No-op MessageListener implementation.""" - - def Modified(self): - pass diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/message_set_extensions_pb2.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/message_set_extensions_pb2.py deleted file mode 100644 index 63651a3f19..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/message_set_extensions_pb2.py +++ /dev/null @@ -1,36 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/internal/message_set_extensions.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n5google/protobuf/internal/message_set_extensions.proto\x12\x18google.protobuf.internal\"\x1e\n\x0eTestMessageSet*\x08\x08\x04\x10\xff\xff\xff\xff\x07:\x02\x08\x01\"\xa5\x01\n\x18TestMessageSetExtension1\x12\t\n\x01i\x18\x0f \x01(\x05\x32~\n\x15message_set_extension\x12(.google.protobuf.internal.TestMessageSet\x18\xab\xff\xf6. \x01(\x0b\x32\x32.google.protobuf.internal.TestMessageSetExtension1\"\xa7\x01\n\x18TestMessageSetExtension2\x12\x0b\n\x03str\x18\x19 \x01(\t2~\n\x15message_set_extension\x12(.google.protobuf.internal.TestMessageSet\x18\xca\xff\xf6. \x01(\x0b\x32\x32.google.protobuf.internal.TestMessageSetExtension2\"(\n\x18TestMessageSetExtension3\x12\x0c\n\x04text\x18# \x01(\t:\x7f\n\x16message_set_extension3\x12(.google.protobuf.internal.TestMessageSet\x18\xdf\xff\xf6. \x01(\x0b\x32\x32.google.protobuf.internal.TestMessageSetExtension3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.internal.message_set_extensions_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - TestMessageSet.RegisterExtension(message_set_extension3) - TestMessageSet.RegisterExtension(_TESTMESSAGESETEXTENSION1.extensions_by_name['message_set_extension']) - TestMessageSet.RegisterExtension(_TESTMESSAGESETEXTENSION2.extensions_by_name['message_set_extension']) - - DESCRIPTOR._options = None - _TESTMESSAGESET._options = None - _TESTMESSAGESET._serialized_options = b'\010\001' - _TESTMESSAGESET._serialized_start=83 - _TESTMESSAGESET._serialized_end=113 - _TESTMESSAGESETEXTENSION1._serialized_start=116 - _TESTMESSAGESETEXTENSION1._serialized_end=281 - _TESTMESSAGESETEXTENSION2._serialized_start=284 - _TESTMESSAGESETEXTENSION2._serialized_end=451 - _TESTMESSAGESETEXTENSION3._serialized_start=453 - _TESTMESSAGESETEXTENSION3._serialized_end=493 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/missing_enum_values_pb2.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/missing_enum_values_pb2.py deleted file mode 100644 index 5497083197..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/missing_enum_values_pb2.py +++ /dev/null @@ -1,37 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/internal/missing_enum_values.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n2google/protobuf/internal/missing_enum_values.proto\x12\x1fgoogle.protobuf.python.internal\"\xc1\x02\n\x0eTestEnumValues\x12X\n\x14optional_nested_enum\x18\x01 \x01(\x0e\x32:.google.protobuf.python.internal.TestEnumValues.NestedEnum\x12X\n\x14repeated_nested_enum\x18\x02 \x03(\x0e\x32:.google.protobuf.python.internal.TestEnumValues.NestedEnum\x12Z\n\x12packed_nested_enum\x18\x03 \x03(\x0e\x32:.google.protobuf.python.internal.TestEnumValues.NestedEnumB\x02\x10\x01\"\x1f\n\nNestedEnum\x12\x08\n\x04ZERO\x10\x00\x12\x07\n\x03ONE\x10\x01\"\xd3\x02\n\x15TestMissingEnumValues\x12_\n\x14optional_nested_enum\x18\x01 \x01(\x0e\x32\x41.google.protobuf.python.internal.TestMissingEnumValues.NestedEnum\x12_\n\x14repeated_nested_enum\x18\x02 \x03(\x0e\x32\x41.google.protobuf.python.internal.TestMissingEnumValues.NestedEnum\x12\x61\n\x12packed_nested_enum\x18\x03 \x03(\x0e\x32\x41.google.protobuf.python.internal.TestMissingEnumValues.NestedEnumB\x02\x10\x01\"\x15\n\nNestedEnum\x12\x07\n\x03TWO\x10\x02\"\x1b\n\nJustString\x12\r\n\x05\x64ummy\x18\x01 \x02(\t') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.internal.missing_enum_values_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - _TESTENUMVALUES.fields_by_name['packed_nested_enum']._options = None - _TESTENUMVALUES.fields_by_name['packed_nested_enum']._serialized_options = b'\020\001' - _TESTMISSINGENUMVALUES.fields_by_name['packed_nested_enum']._options = None - _TESTMISSINGENUMVALUES.fields_by_name['packed_nested_enum']._serialized_options = b'\020\001' - _TESTENUMVALUES._serialized_start=88 - _TESTENUMVALUES._serialized_end=409 - _TESTENUMVALUES_NESTEDENUM._serialized_start=378 - _TESTENUMVALUES_NESTEDENUM._serialized_end=409 - _TESTMISSINGENUMVALUES._serialized_start=412 - _TESTMISSINGENUMVALUES._serialized_end=751 - _TESTMISSINGENUMVALUES_NESTEDENUM._serialized_start=730 - _TESTMISSINGENUMVALUES_NESTEDENUM._serialized_end=751 - _JUSTSTRING._serialized_start=753 - _JUSTSTRING._serialized_end=780 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/more_extensions_dynamic_pb2.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/more_extensions_dynamic_pb2.py deleted file mode 100644 index 0953706bac..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/more_extensions_dynamic_pb2.py +++ /dev/null @@ -1,29 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/internal/more_extensions_dynamic.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.protobuf.internal import more_extensions_pb2 as google_dot_protobuf_dot_internal_dot_more__extensions__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n6google/protobuf/internal/more_extensions_dynamic.proto\x12\x18google.protobuf.internal\x1a.google/protobuf/internal/more_extensions.proto\"\x1f\n\x12\x44ynamicMessageType\x12\t\n\x01\x61\x18\x01 \x01(\x05:J\n\x17\x64ynamic_int32_extension\x12).google.protobuf.internal.ExtendedMessage\x18\x64 \x01(\x05:z\n\x19\x64ynamic_message_extension\x12).google.protobuf.internal.ExtendedMessage\x18\x65 \x01(\x0b\x32,.google.protobuf.internal.DynamicMessageType:\x83\x01\n\"repeated_dynamic_message_extension\x12).google.protobuf.internal.ExtendedMessage\x18\x66 \x03(\x0b\x32,.google.protobuf.internal.DynamicMessageType') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.internal.more_extensions_dynamic_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - google_dot_protobuf_dot_internal_dot_more__extensions__pb2.ExtendedMessage.RegisterExtension(dynamic_int32_extension) - google_dot_protobuf_dot_internal_dot_more__extensions__pb2.ExtendedMessage.RegisterExtension(dynamic_message_extension) - google_dot_protobuf_dot_internal_dot_more__extensions__pb2.ExtendedMessage.RegisterExtension(repeated_dynamic_message_extension) - - DESCRIPTOR._options = None - _DYNAMICMESSAGETYPE._serialized_start=132 - _DYNAMICMESSAGETYPE._serialized_end=163 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/more_extensions_pb2.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/more_extensions_pb2.py deleted file mode 100644 index 1cfa1b7c8b..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/more_extensions_pb2.py +++ /dev/null @@ -1,41 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/internal/more_extensions.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n.google/protobuf/internal/more_extensions.proto\x12\x18google.protobuf.internal\"\x99\x01\n\x0fTopLevelMessage\x12\x41\n\nsubmessage\x18\x01 \x01(\x0b\x32).google.protobuf.internal.ExtendedMessageB\x02(\x01\x12\x43\n\x0enested_message\x18\x02 \x01(\x0b\x32\'.google.protobuf.internal.NestedMessageB\x02(\x01\"R\n\rNestedMessage\x12\x41\n\nsubmessage\x18\x01 \x01(\x0b\x32).google.protobuf.internal.ExtendedMessageB\x02(\x01\"K\n\x0f\x45xtendedMessage\x12\x17\n\x0eoptional_int32\x18\xe9\x07 \x01(\x05\x12\x18\n\x0frepeated_string\x18\xea\x07 \x03(\t*\x05\x08\x01\x10\xe8\x07\"-\n\x0e\x46oreignMessage\x12\x1b\n\x13\x66oreign_message_int\x18\x01 \x01(\x05:I\n\x16optional_int_extension\x12).google.protobuf.internal.ExtendedMessage\x18\x01 \x01(\x05:w\n\x1aoptional_message_extension\x12).google.protobuf.internal.ExtendedMessage\x18\x02 \x01(\x0b\x32(.google.protobuf.internal.ForeignMessage:I\n\x16repeated_int_extension\x12).google.protobuf.internal.ExtendedMessage\x18\x03 \x03(\x05:w\n\x1arepeated_message_extension\x12).google.protobuf.internal.ExtendedMessage\x18\x04 \x03(\x0b\x32(.google.protobuf.internal.ForeignMessage') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.internal.more_extensions_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - ExtendedMessage.RegisterExtension(optional_int_extension) - ExtendedMessage.RegisterExtension(optional_message_extension) - ExtendedMessage.RegisterExtension(repeated_int_extension) - ExtendedMessage.RegisterExtension(repeated_message_extension) - - DESCRIPTOR._options = None - _TOPLEVELMESSAGE.fields_by_name['submessage']._options = None - _TOPLEVELMESSAGE.fields_by_name['submessage']._serialized_options = b'(\001' - _TOPLEVELMESSAGE.fields_by_name['nested_message']._options = None - _TOPLEVELMESSAGE.fields_by_name['nested_message']._serialized_options = b'(\001' - _NESTEDMESSAGE.fields_by_name['submessage']._options = None - _NESTEDMESSAGE.fields_by_name['submessage']._serialized_options = b'(\001' - _TOPLEVELMESSAGE._serialized_start=77 - _TOPLEVELMESSAGE._serialized_end=230 - _NESTEDMESSAGE._serialized_start=232 - _NESTEDMESSAGE._serialized_end=314 - _EXTENDEDMESSAGE._serialized_start=316 - _EXTENDEDMESSAGE._serialized_end=391 - _FOREIGNMESSAGE._serialized_start=393 - _FOREIGNMESSAGE._serialized_end=438 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/more_messages_pb2.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/more_messages_pb2.py deleted file mode 100644 index d7f7115609..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/more_messages_pb2.py +++ /dev/null @@ -1,556 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/internal/more_messages.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n,google/protobuf/internal/more_messages.proto\x12\x18google.protobuf.internal\"h\n\x10OutOfOrderFields\x12\x17\n\x0foptional_sint32\x18\x05 \x01(\x11\x12\x17\n\x0foptional_uint32\x18\x03 \x01(\r\x12\x16\n\x0eoptional_int32\x18\x01 \x01(\x05*\x04\x08\x04\x10\x05*\x04\x08\x02\x10\x03\"\xcd\x02\n\x05\x63lass\x12\x1b\n\tint_field\x18\x01 \x01(\x05R\x08json_int\x12\n\n\x02if\x18\x02 \x01(\x05\x12(\n\x02\x61s\x18\x03 \x01(\x0e\x32\x1c.google.protobuf.internal.is\x12\x30\n\nenum_field\x18\x04 \x01(\x0e\x32\x1c.google.protobuf.internal.is\x12>\n\x11nested_enum_field\x18\x05 \x01(\x0e\x32#.google.protobuf.internal.class.for\x12;\n\x0enested_message\x18\x06 \x01(\x0b\x32#.google.protobuf.internal.class.try\x1a\x1c\n\x03try\x12\r\n\x05\x66ield\x18\x01 \x01(\x05*\x06\x08\xe7\x07\x10\x90N\"\x1c\n\x03\x66or\x12\x0b\n\x07\x64\x65\x66\x61ult\x10\x00\x12\x08\n\x04True\x10\x01*\x06\x08\xe7\x07\x10\x90N\"?\n\x0b\x45xtendClass20\n\x06return\x12\x1f.google.protobuf.internal.class\x18\xea\x07 \x01(\x05\"~\n\x0fTestFullKeyword\x12:\n\x06\x66ield1\x18\x01 \x01(\x0b\x32*.google.protobuf.internal.OutOfOrderFields\x12/\n\x06\x66ield2\x18\x02 \x01(\x0b\x32\x1f.google.protobuf.internal.class\"\xa5\x0f\n\x11LotsNestedMessage\x1a\x04\n\x02\x42\x30\x1a\x04\n\x02\x42\x31\x1a\x04\n\x02\x42\x32\x1a\x04\n\x02\x42\x33\x1a\x04\n\x02\x42\x34\x1a\x04\n\x02\x42\x35\x1a\x04\n\x02\x42\x36\x1a\x04\n\x02\x42\x37\x1a\x04\n\x02\x42\x38\x1a\x04\n\x02\x42\x39\x1a\x05\n\x03\x42\x31\x30\x1a\x05\n\x03\x42\x31\x31\x1a\x05\n\x03\x42\x31\x32\x1a\x05\n\x03\x42\x31\x33\x1a\x05\n\x03\x42\x31\x34\x1a\x05\n\x03\x42\x31\x35\x1a\x05\n\x03\x42\x31\x36\x1a\x05\n\x03\x42\x31\x37\x1a\x05\n\x03\x42\x31\x38\x1a\x05\n\x03\x42\x31\x39\x1a\x05\n\x03\x42\x32\x30\x1a\x05\n\x03\x42\x32\x31\x1a\x05\n\x03\x42\x32\x32\x1a\x05\n\x03\x42\x32\x33\x1a\x05\n\x03\x42\x32\x34\x1a\x05\n\x03\x42\x32\x35\x1a\x05\n\x03\x42\x32\x36\x1a\x05\n\x03\x42\x32\x37\x1a\x05\n\x03\x42\x32\x38\x1a\x05\n\x03\x42\x32\x39\x1a\x05\n\x03\x42\x33\x30\x1a\x05\n\x03\x42\x33\x31\x1a\x05\n\x03\x42\x33\x32\x1a\x05\n\x03\x42\x33\x33\x1a\x05\n\x03\x42\x33\x34\x1a\x05\n\x03\x42\x33\x35\x1a\x05\n\x03\x42\x33\x36\x1a\x05\n\x03\x42\x33\x37\x1a\x05\n\x03\x42\x33\x38\x1a\x05\n\x03\x42\x33\x39\x1a\x05\n\x03\x42\x34\x30\x1a\x05\n\x03\x42\x34\x31\x1a\x05\n\x03\x42\x34\x32\x1a\x05\n\x03\x42\x34\x33\x1a\x05\n\x03\x42\x34\x34\x1a\x05\n\x03\x42\x34\x35\x1a\x05\n\x03\x42\x34\x36\x1a\x05\n\x03\x42\x34\x37\x1a\x05\n\x03\x42\x34\x38\x1a\x05\n\x03\x42\x34\x39\x1a\x05\n\x03\x42\x35\x30\x1a\x05\n\x03\x42\x35\x31\x1a\x05\n\x03\x42\x35\x32\x1a\x05\n\x03\x42\x35\x33\x1a\x05\n\x03\x42\x35\x34\x1a\x05\n\x03\x42\x35\x35\x1a\x05\n\x03\x42\x35\x36\x1a\x05\n\x03\x42\x35\x37\x1a\x05\n\x03\x42\x35\x38\x1a\x05\n\x03\x42\x35\x39\x1a\x05\n\x03\x42\x36\x30\x1a\x05\n\x03\x42\x36\x31\x1a\x05\n\x03\x42\x36\x32\x1a\x05\n\x03\x42\x36\x33\x1a\x05\n\x03\x42\x36\x34\x1a\x05\n\x03\x42\x36\x35\x1a\x05\n\x03\x42\x36\x36\x1a\x05\n\x03\x42\x36\x37\x1a\x05\n\x03\x42\x36\x38\x1a\x05\n\x03\x42\x36\x39\x1a\x05\n\x03\x42\x37\x30\x1a\x05\n\x03\x42\x37\x31\x1a\x05\n\x03\x42\x37\x32\x1a\x05\n\x03\x42\x37\x33\x1a\x05\n\x03\x42\x37\x34\x1a\x05\n\x03\x42\x37\x35\x1a\x05\n\x03\x42\x37\x36\x1a\x05\n\x03\x42\x37\x37\x1a\x05\n\x03\x42\x37\x38\x1a\x05\n\x03\x42\x37\x39\x1a\x05\n\x03\x42\x38\x30\x1a\x05\n\x03\x42\x38\x31\x1a\x05\n\x03\x42\x38\x32\x1a\x05\n\x03\x42\x38\x33\x1a\x05\n\x03\x42\x38\x34\x1a\x05\n\x03\x42\x38\x35\x1a\x05\n\x03\x42\x38\x36\x1a\x05\n\x03\x42\x38\x37\x1a\x05\n\x03\x42\x38\x38\x1a\x05\n\x03\x42\x38\x39\x1a\x05\n\x03\x42\x39\x30\x1a\x05\n\x03\x42\x39\x31\x1a\x05\n\x03\x42\x39\x32\x1a\x05\n\x03\x42\x39\x33\x1a\x05\n\x03\x42\x39\x34\x1a\x05\n\x03\x42\x39\x35\x1a\x05\n\x03\x42\x39\x36\x1a\x05\n\x03\x42\x39\x37\x1a\x05\n\x03\x42\x39\x38\x1a\x05\n\x03\x42\x39\x39\x1a\x06\n\x04\x42\x31\x30\x30\x1a\x06\n\x04\x42\x31\x30\x31\x1a\x06\n\x04\x42\x31\x30\x32\x1a\x06\n\x04\x42\x31\x30\x33\x1a\x06\n\x04\x42\x31\x30\x34\x1a\x06\n\x04\x42\x31\x30\x35\x1a\x06\n\x04\x42\x31\x30\x36\x1a\x06\n\x04\x42\x31\x30\x37\x1a\x06\n\x04\x42\x31\x30\x38\x1a\x06\n\x04\x42\x31\x30\x39\x1a\x06\n\x04\x42\x31\x31\x30\x1a\x06\n\x04\x42\x31\x31\x31\x1a\x06\n\x04\x42\x31\x31\x32\x1a\x06\n\x04\x42\x31\x31\x33\x1a\x06\n\x04\x42\x31\x31\x34\x1a\x06\n\x04\x42\x31\x31\x35\x1a\x06\n\x04\x42\x31\x31\x36\x1a\x06\n\x04\x42\x31\x31\x37\x1a\x06\n\x04\x42\x31\x31\x38\x1a\x06\n\x04\x42\x31\x31\x39\x1a\x06\n\x04\x42\x31\x32\x30\x1a\x06\n\x04\x42\x31\x32\x31\x1a\x06\n\x04\x42\x31\x32\x32\x1a\x06\n\x04\x42\x31\x32\x33\x1a\x06\n\x04\x42\x31\x32\x34\x1a\x06\n\x04\x42\x31\x32\x35\x1a\x06\n\x04\x42\x31\x32\x36\x1a\x06\n\x04\x42\x31\x32\x37\x1a\x06\n\x04\x42\x31\x32\x38\x1a\x06\n\x04\x42\x31\x32\x39\x1a\x06\n\x04\x42\x31\x33\x30\x1a\x06\n\x04\x42\x31\x33\x31\x1a\x06\n\x04\x42\x31\x33\x32\x1a\x06\n\x04\x42\x31\x33\x33\x1a\x06\n\x04\x42\x31\x33\x34\x1a\x06\n\x04\x42\x31\x33\x35\x1a\x06\n\x04\x42\x31\x33\x36\x1a\x06\n\x04\x42\x31\x33\x37\x1a\x06\n\x04\x42\x31\x33\x38\x1a\x06\n\x04\x42\x31\x33\x39\x1a\x06\n\x04\x42\x31\x34\x30\x1a\x06\n\x04\x42\x31\x34\x31\x1a\x06\n\x04\x42\x31\x34\x32\x1a\x06\n\x04\x42\x31\x34\x33\x1a\x06\n\x04\x42\x31\x34\x34\x1a\x06\n\x04\x42\x31\x34\x35\x1a\x06\n\x04\x42\x31\x34\x36\x1a\x06\n\x04\x42\x31\x34\x37\x1a\x06\n\x04\x42\x31\x34\x38\x1a\x06\n\x04\x42\x31\x34\x39\x1a\x06\n\x04\x42\x31\x35\x30\x1a\x06\n\x04\x42\x31\x35\x31\x1a\x06\n\x04\x42\x31\x35\x32\x1a\x06\n\x04\x42\x31\x35\x33\x1a\x06\n\x04\x42\x31\x35\x34\x1a\x06\n\x04\x42\x31\x35\x35\x1a\x06\n\x04\x42\x31\x35\x36\x1a\x06\n\x04\x42\x31\x35\x37\x1a\x06\n\x04\x42\x31\x35\x38\x1a\x06\n\x04\x42\x31\x35\x39\x1a\x06\n\x04\x42\x31\x36\x30\x1a\x06\n\x04\x42\x31\x36\x31\x1a\x06\n\x04\x42\x31\x36\x32\x1a\x06\n\x04\x42\x31\x36\x33\x1a\x06\n\x04\x42\x31\x36\x34\x1a\x06\n\x04\x42\x31\x36\x35\x1a\x06\n\x04\x42\x31\x36\x36\x1a\x06\n\x04\x42\x31\x36\x37\x1a\x06\n\x04\x42\x31\x36\x38\x1a\x06\n\x04\x42\x31\x36\x39\x1a\x06\n\x04\x42\x31\x37\x30\x1a\x06\n\x04\x42\x31\x37\x31\x1a\x06\n\x04\x42\x31\x37\x32\x1a\x06\n\x04\x42\x31\x37\x33\x1a\x06\n\x04\x42\x31\x37\x34\x1a\x06\n\x04\x42\x31\x37\x35\x1a\x06\n\x04\x42\x31\x37\x36\x1a\x06\n\x04\x42\x31\x37\x37\x1a\x06\n\x04\x42\x31\x37\x38\x1a\x06\n\x04\x42\x31\x37\x39\x1a\x06\n\x04\x42\x31\x38\x30\x1a\x06\n\x04\x42\x31\x38\x31\x1a\x06\n\x04\x42\x31\x38\x32\x1a\x06\n\x04\x42\x31\x38\x33\x1a\x06\n\x04\x42\x31\x38\x34\x1a\x06\n\x04\x42\x31\x38\x35\x1a\x06\n\x04\x42\x31\x38\x36\x1a\x06\n\x04\x42\x31\x38\x37\x1a\x06\n\x04\x42\x31\x38\x38\x1a\x06\n\x04\x42\x31\x38\x39\x1a\x06\n\x04\x42\x31\x39\x30\x1a\x06\n\x04\x42\x31\x39\x31\x1a\x06\n\x04\x42\x31\x39\x32\x1a\x06\n\x04\x42\x31\x39\x33\x1a\x06\n\x04\x42\x31\x39\x34\x1a\x06\n\x04\x42\x31\x39\x35\x1a\x06\n\x04\x42\x31\x39\x36\x1a\x06\n\x04\x42\x31\x39\x37\x1a\x06\n\x04\x42\x31\x39\x38\x1a\x06\n\x04\x42\x31\x39\x39\x1a\x06\n\x04\x42\x32\x30\x30\x1a\x06\n\x04\x42\x32\x30\x31\x1a\x06\n\x04\x42\x32\x30\x32\x1a\x06\n\x04\x42\x32\x30\x33\x1a\x06\n\x04\x42\x32\x30\x34\x1a\x06\n\x04\x42\x32\x30\x35\x1a\x06\n\x04\x42\x32\x30\x36\x1a\x06\n\x04\x42\x32\x30\x37\x1a\x06\n\x04\x42\x32\x30\x38\x1a\x06\n\x04\x42\x32\x30\x39\x1a\x06\n\x04\x42\x32\x31\x30\x1a\x06\n\x04\x42\x32\x31\x31\x1a\x06\n\x04\x42\x32\x31\x32\x1a\x06\n\x04\x42\x32\x31\x33\x1a\x06\n\x04\x42\x32\x31\x34\x1a\x06\n\x04\x42\x32\x31\x35\x1a\x06\n\x04\x42\x32\x31\x36\x1a\x06\n\x04\x42\x32\x31\x37\x1a\x06\n\x04\x42\x32\x31\x38\x1a\x06\n\x04\x42\x32\x31\x39\x1a\x06\n\x04\x42\x32\x32\x30\x1a\x06\n\x04\x42\x32\x32\x31\x1a\x06\n\x04\x42\x32\x32\x32\x1a\x06\n\x04\x42\x32\x32\x33\x1a\x06\n\x04\x42\x32\x32\x34\x1a\x06\n\x04\x42\x32\x32\x35\x1a\x06\n\x04\x42\x32\x32\x36\x1a\x06\n\x04\x42\x32\x32\x37\x1a\x06\n\x04\x42\x32\x32\x38\x1a\x06\n\x04\x42\x32\x32\x39\x1a\x06\n\x04\x42\x32\x33\x30\x1a\x06\n\x04\x42\x32\x33\x31\x1a\x06\n\x04\x42\x32\x33\x32\x1a\x06\n\x04\x42\x32\x33\x33\x1a\x06\n\x04\x42\x32\x33\x34\x1a\x06\n\x04\x42\x32\x33\x35\x1a\x06\n\x04\x42\x32\x33\x36\x1a\x06\n\x04\x42\x32\x33\x37\x1a\x06\n\x04\x42\x32\x33\x38\x1a\x06\n\x04\x42\x32\x33\x39\x1a\x06\n\x04\x42\x32\x34\x30\x1a\x06\n\x04\x42\x32\x34\x31\x1a\x06\n\x04\x42\x32\x34\x32\x1a\x06\n\x04\x42\x32\x34\x33\x1a\x06\n\x04\x42\x32\x34\x34\x1a\x06\n\x04\x42\x32\x34\x35\x1a\x06\n\x04\x42\x32\x34\x36\x1a\x06\n\x04\x42\x32\x34\x37\x1a\x06\n\x04\x42\x32\x34\x38\x1a\x06\n\x04\x42\x32\x34\x39\x1a\x06\n\x04\x42\x32\x35\x30\x1a\x06\n\x04\x42\x32\x35\x31\x1a\x06\n\x04\x42\x32\x35\x32\x1a\x06\n\x04\x42\x32\x35\x33\x1a\x06\n\x04\x42\x32\x35\x34\x1a\x06\n\x04\x42\x32\x35\x35*\x1b\n\x02is\x12\x0b\n\x07\x64\x65\x66\x61ult\x10\x00\x12\x08\n\x04\x65lse\x10\x01:C\n\x0foptional_uint64\x12*.google.protobuf.internal.OutOfOrderFields\x18\x04 \x01(\x04:B\n\x0eoptional_int64\x12*.google.protobuf.internal.OutOfOrderFields\x18\x02 \x01(\x03:2\n\x08\x63ontinue\x12\x1f.google.protobuf.internal.class\x18\xe9\x07 \x01(\x05:2\n\x04with\x12#.google.protobuf.internal.class.try\x18\xe9\x07 \x01(\x05') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.internal.more_messages_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - OutOfOrderFields.RegisterExtension(optional_uint64) - OutOfOrderFields.RegisterExtension(optional_int64) - globals()['class'].RegisterExtension(globals()['continue']) - getattr(globals()['class'], 'try').RegisterExtension(globals()['with']) - globals()['class'].RegisterExtension(_EXTENDCLASS.extensions_by_name['return']) - - DESCRIPTOR._options = None - _IS._serialized_start=2669 - _IS._serialized_end=2696 - _OUTOFORDERFIELDS._serialized_start=74 - _OUTOFORDERFIELDS._serialized_end=178 - _CLASS._serialized_start=181 - _CLASS._serialized_end=514 - _CLASS_TRY._serialized_start=448 - _CLASS_TRY._serialized_end=476 - _CLASS_FOR._serialized_start=478 - _CLASS_FOR._serialized_end=506 - _EXTENDCLASS._serialized_start=516 - _EXTENDCLASS._serialized_end=579 - _TESTFULLKEYWORD._serialized_start=581 - _TESTFULLKEYWORD._serialized_end=707 - _LOTSNESTEDMESSAGE._serialized_start=710 - _LOTSNESTEDMESSAGE._serialized_end=2667 - _LOTSNESTEDMESSAGE_B0._serialized_start=731 - _LOTSNESTEDMESSAGE_B0._serialized_end=735 - _LOTSNESTEDMESSAGE_B1._serialized_start=737 - _LOTSNESTEDMESSAGE_B1._serialized_end=741 - _LOTSNESTEDMESSAGE_B2._serialized_start=743 - _LOTSNESTEDMESSAGE_B2._serialized_end=747 - _LOTSNESTEDMESSAGE_B3._serialized_start=749 - _LOTSNESTEDMESSAGE_B3._serialized_end=753 - _LOTSNESTEDMESSAGE_B4._serialized_start=755 - _LOTSNESTEDMESSAGE_B4._serialized_end=759 - _LOTSNESTEDMESSAGE_B5._serialized_start=761 - _LOTSNESTEDMESSAGE_B5._serialized_end=765 - _LOTSNESTEDMESSAGE_B6._serialized_start=767 - _LOTSNESTEDMESSAGE_B6._serialized_end=771 - _LOTSNESTEDMESSAGE_B7._serialized_start=773 - _LOTSNESTEDMESSAGE_B7._serialized_end=777 - _LOTSNESTEDMESSAGE_B8._serialized_start=779 - _LOTSNESTEDMESSAGE_B8._serialized_end=783 - _LOTSNESTEDMESSAGE_B9._serialized_start=785 - _LOTSNESTEDMESSAGE_B9._serialized_end=789 - _LOTSNESTEDMESSAGE_B10._serialized_start=791 - _LOTSNESTEDMESSAGE_B10._serialized_end=796 - _LOTSNESTEDMESSAGE_B11._serialized_start=798 - _LOTSNESTEDMESSAGE_B11._serialized_end=803 - _LOTSNESTEDMESSAGE_B12._serialized_start=805 - _LOTSNESTEDMESSAGE_B12._serialized_end=810 - _LOTSNESTEDMESSAGE_B13._serialized_start=812 - _LOTSNESTEDMESSAGE_B13._serialized_end=817 - _LOTSNESTEDMESSAGE_B14._serialized_start=819 - _LOTSNESTEDMESSAGE_B14._serialized_end=824 - _LOTSNESTEDMESSAGE_B15._serialized_start=826 - _LOTSNESTEDMESSAGE_B15._serialized_end=831 - _LOTSNESTEDMESSAGE_B16._serialized_start=833 - _LOTSNESTEDMESSAGE_B16._serialized_end=838 - _LOTSNESTEDMESSAGE_B17._serialized_start=840 - _LOTSNESTEDMESSAGE_B17._serialized_end=845 - _LOTSNESTEDMESSAGE_B18._serialized_start=847 - _LOTSNESTEDMESSAGE_B18._serialized_end=852 - _LOTSNESTEDMESSAGE_B19._serialized_start=854 - _LOTSNESTEDMESSAGE_B19._serialized_end=859 - _LOTSNESTEDMESSAGE_B20._serialized_start=861 - _LOTSNESTEDMESSAGE_B20._serialized_end=866 - _LOTSNESTEDMESSAGE_B21._serialized_start=868 - _LOTSNESTEDMESSAGE_B21._serialized_end=873 - _LOTSNESTEDMESSAGE_B22._serialized_start=875 - _LOTSNESTEDMESSAGE_B22._serialized_end=880 - _LOTSNESTEDMESSAGE_B23._serialized_start=882 - _LOTSNESTEDMESSAGE_B23._serialized_end=887 - _LOTSNESTEDMESSAGE_B24._serialized_start=889 - _LOTSNESTEDMESSAGE_B24._serialized_end=894 - _LOTSNESTEDMESSAGE_B25._serialized_start=896 - _LOTSNESTEDMESSAGE_B25._serialized_end=901 - _LOTSNESTEDMESSAGE_B26._serialized_start=903 - _LOTSNESTEDMESSAGE_B26._serialized_end=908 - _LOTSNESTEDMESSAGE_B27._serialized_start=910 - _LOTSNESTEDMESSAGE_B27._serialized_end=915 - _LOTSNESTEDMESSAGE_B28._serialized_start=917 - _LOTSNESTEDMESSAGE_B28._serialized_end=922 - _LOTSNESTEDMESSAGE_B29._serialized_start=924 - _LOTSNESTEDMESSAGE_B29._serialized_end=929 - _LOTSNESTEDMESSAGE_B30._serialized_start=931 - _LOTSNESTEDMESSAGE_B30._serialized_end=936 - _LOTSNESTEDMESSAGE_B31._serialized_start=938 - _LOTSNESTEDMESSAGE_B31._serialized_end=943 - _LOTSNESTEDMESSAGE_B32._serialized_start=945 - _LOTSNESTEDMESSAGE_B32._serialized_end=950 - _LOTSNESTEDMESSAGE_B33._serialized_start=952 - _LOTSNESTEDMESSAGE_B33._serialized_end=957 - _LOTSNESTEDMESSAGE_B34._serialized_start=959 - _LOTSNESTEDMESSAGE_B34._serialized_end=964 - _LOTSNESTEDMESSAGE_B35._serialized_start=966 - _LOTSNESTEDMESSAGE_B35._serialized_end=971 - _LOTSNESTEDMESSAGE_B36._serialized_start=973 - _LOTSNESTEDMESSAGE_B36._serialized_end=978 - _LOTSNESTEDMESSAGE_B37._serialized_start=980 - _LOTSNESTEDMESSAGE_B37._serialized_end=985 - _LOTSNESTEDMESSAGE_B38._serialized_start=987 - _LOTSNESTEDMESSAGE_B38._serialized_end=992 - _LOTSNESTEDMESSAGE_B39._serialized_start=994 - _LOTSNESTEDMESSAGE_B39._serialized_end=999 - _LOTSNESTEDMESSAGE_B40._serialized_start=1001 - _LOTSNESTEDMESSAGE_B40._serialized_end=1006 - _LOTSNESTEDMESSAGE_B41._serialized_start=1008 - _LOTSNESTEDMESSAGE_B41._serialized_end=1013 - _LOTSNESTEDMESSAGE_B42._serialized_start=1015 - _LOTSNESTEDMESSAGE_B42._serialized_end=1020 - _LOTSNESTEDMESSAGE_B43._serialized_start=1022 - _LOTSNESTEDMESSAGE_B43._serialized_end=1027 - _LOTSNESTEDMESSAGE_B44._serialized_start=1029 - _LOTSNESTEDMESSAGE_B44._serialized_end=1034 - _LOTSNESTEDMESSAGE_B45._serialized_start=1036 - _LOTSNESTEDMESSAGE_B45._serialized_end=1041 - _LOTSNESTEDMESSAGE_B46._serialized_start=1043 - _LOTSNESTEDMESSAGE_B46._serialized_end=1048 - _LOTSNESTEDMESSAGE_B47._serialized_start=1050 - _LOTSNESTEDMESSAGE_B47._serialized_end=1055 - _LOTSNESTEDMESSAGE_B48._serialized_start=1057 - _LOTSNESTEDMESSAGE_B48._serialized_end=1062 - _LOTSNESTEDMESSAGE_B49._serialized_start=1064 - _LOTSNESTEDMESSAGE_B49._serialized_end=1069 - _LOTSNESTEDMESSAGE_B50._serialized_start=1071 - _LOTSNESTEDMESSAGE_B50._serialized_end=1076 - _LOTSNESTEDMESSAGE_B51._serialized_start=1078 - _LOTSNESTEDMESSAGE_B51._serialized_end=1083 - _LOTSNESTEDMESSAGE_B52._serialized_start=1085 - _LOTSNESTEDMESSAGE_B52._serialized_end=1090 - _LOTSNESTEDMESSAGE_B53._serialized_start=1092 - _LOTSNESTEDMESSAGE_B53._serialized_end=1097 - _LOTSNESTEDMESSAGE_B54._serialized_start=1099 - _LOTSNESTEDMESSAGE_B54._serialized_end=1104 - _LOTSNESTEDMESSAGE_B55._serialized_start=1106 - _LOTSNESTEDMESSAGE_B55._serialized_end=1111 - _LOTSNESTEDMESSAGE_B56._serialized_start=1113 - _LOTSNESTEDMESSAGE_B56._serialized_end=1118 - _LOTSNESTEDMESSAGE_B57._serialized_start=1120 - _LOTSNESTEDMESSAGE_B57._serialized_end=1125 - _LOTSNESTEDMESSAGE_B58._serialized_start=1127 - _LOTSNESTEDMESSAGE_B58._serialized_end=1132 - _LOTSNESTEDMESSAGE_B59._serialized_start=1134 - _LOTSNESTEDMESSAGE_B59._serialized_end=1139 - _LOTSNESTEDMESSAGE_B60._serialized_start=1141 - _LOTSNESTEDMESSAGE_B60._serialized_end=1146 - _LOTSNESTEDMESSAGE_B61._serialized_start=1148 - _LOTSNESTEDMESSAGE_B61._serialized_end=1153 - _LOTSNESTEDMESSAGE_B62._serialized_start=1155 - _LOTSNESTEDMESSAGE_B62._serialized_end=1160 - _LOTSNESTEDMESSAGE_B63._serialized_start=1162 - _LOTSNESTEDMESSAGE_B63._serialized_end=1167 - _LOTSNESTEDMESSAGE_B64._serialized_start=1169 - _LOTSNESTEDMESSAGE_B64._serialized_end=1174 - _LOTSNESTEDMESSAGE_B65._serialized_start=1176 - _LOTSNESTEDMESSAGE_B65._serialized_end=1181 - _LOTSNESTEDMESSAGE_B66._serialized_start=1183 - _LOTSNESTEDMESSAGE_B66._serialized_end=1188 - _LOTSNESTEDMESSAGE_B67._serialized_start=1190 - _LOTSNESTEDMESSAGE_B67._serialized_end=1195 - _LOTSNESTEDMESSAGE_B68._serialized_start=1197 - _LOTSNESTEDMESSAGE_B68._serialized_end=1202 - _LOTSNESTEDMESSAGE_B69._serialized_start=1204 - _LOTSNESTEDMESSAGE_B69._serialized_end=1209 - _LOTSNESTEDMESSAGE_B70._serialized_start=1211 - _LOTSNESTEDMESSAGE_B70._serialized_end=1216 - _LOTSNESTEDMESSAGE_B71._serialized_start=1218 - _LOTSNESTEDMESSAGE_B71._serialized_end=1223 - _LOTSNESTEDMESSAGE_B72._serialized_start=1225 - _LOTSNESTEDMESSAGE_B72._serialized_end=1230 - _LOTSNESTEDMESSAGE_B73._serialized_start=1232 - _LOTSNESTEDMESSAGE_B73._serialized_end=1237 - _LOTSNESTEDMESSAGE_B74._serialized_start=1239 - _LOTSNESTEDMESSAGE_B74._serialized_end=1244 - _LOTSNESTEDMESSAGE_B75._serialized_start=1246 - _LOTSNESTEDMESSAGE_B75._serialized_end=1251 - _LOTSNESTEDMESSAGE_B76._serialized_start=1253 - _LOTSNESTEDMESSAGE_B76._serialized_end=1258 - _LOTSNESTEDMESSAGE_B77._serialized_start=1260 - _LOTSNESTEDMESSAGE_B77._serialized_end=1265 - _LOTSNESTEDMESSAGE_B78._serialized_start=1267 - _LOTSNESTEDMESSAGE_B78._serialized_end=1272 - _LOTSNESTEDMESSAGE_B79._serialized_start=1274 - _LOTSNESTEDMESSAGE_B79._serialized_end=1279 - _LOTSNESTEDMESSAGE_B80._serialized_start=1281 - _LOTSNESTEDMESSAGE_B80._serialized_end=1286 - _LOTSNESTEDMESSAGE_B81._serialized_start=1288 - _LOTSNESTEDMESSAGE_B81._serialized_end=1293 - _LOTSNESTEDMESSAGE_B82._serialized_start=1295 - _LOTSNESTEDMESSAGE_B82._serialized_end=1300 - _LOTSNESTEDMESSAGE_B83._serialized_start=1302 - _LOTSNESTEDMESSAGE_B83._serialized_end=1307 - _LOTSNESTEDMESSAGE_B84._serialized_start=1309 - _LOTSNESTEDMESSAGE_B84._serialized_end=1314 - _LOTSNESTEDMESSAGE_B85._serialized_start=1316 - _LOTSNESTEDMESSAGE_B85._serialized_end=1321 - _LOTSNESTEDMESSAGE_B86._serialized_start=1323 - _LOTSNESTEDMESSAGE_B86._serialized_end=1328 - _LOTSNESTEDMESSAGE_B87._serialized_start=1330 - _LOTSNESTEDMESSAGE_B87._serialized_end=1335 - _LOTSNESTEDMESSAGE_B88._serialized_start=1337 - _LOTSNESTEDMESSAGE_B88._serialized_end=1342 - _LOTSNESTEDMESSAGE_B89._serialized_start=1344 - _LOTSNESTEDMESSAGE_B89._serialized_end=1349 - _LOTSNESTEDMESSAGE_B90._serialized_start=1351 - _LOTSNESTEDMESSAGE_B90._serialized_end=1356 - _LOTSNESTEDMESSAGE_B91._serialized_start=1358 - _LOTSNESTEDMESSAGE_B91._serialized_end=1363 - _LOTSNESTEDMESSAGE_B92._serialized_start=1365 - _LOTSNESTEDMESSAGE_B92._serialized_end=1370 - _LOTSNESTEDMESSAGE_B93._serialized_start=1372 - _LOTSNESTEDMESSAGE_B93._serialized_end=1377 - _LOTSNESTEDMESSAGE_B94._serialized_start=1379 - _LOTSNESTEDMESSAGE_B94._serialized_end=1384 - _LOTSNESTEDMESSAGE_B95._serialized_start=1386 - _LOTSNESTEDMESSAGE_B95._serialized_end=1391 - _LOTSNESTEDMESSAGE_B96._serialized_start=1393 - _LOTSNESTEDMESSAGE_B96._serialized_end=1398 - _LOTSNESTEDMESSAGE_B97._serialized_start=1400 - _LOTSNESTEDMESSAGE_B97._serialized_end=1405 - _LOTSNESTEDMESSAGE_B98._serialized_start=1407 - _LOTSNESTEDMESSAGE_B98._serialized_end=1412 - _LOTSNESTEDMESSAGE_B99._serialized_start=1414 - _LOTSNESTEDMESSAGE_B99._serialized_end=1419 - _LOTSNESTEDMESSAGE_B100._serialized_start=1421 - _LOTSNESTEDMESSAGE_B100._serialized_end=1427 - _LOTSNESTEDMESSAGE_B101._serialized_start=1429 - _LOTSNESTEDMESSAGE_B101._serialized_end=1435 - _LOTSNESTEDMESSAGE_B102._serialized_start=1437 - _LOTSNESTEDMESSAGE_B102._serialized_end=1443 - _LOTSNESTEDMESSAGE_B103._serialized_start=1445 - _LOTSNESTEDMESSAGE_B103._serialized_end=1451 - _LOTSNESTEDMESSAGE_B104._serialized_start=1453 - _LOTSNESTEDMESSAGE_B104._serialized_end=1459 - _LOTSNESTEDMESSAGE_B105._serialized_start=1461 - _LOTSNESTEDMESSAGE_B105._serialized_end=1467 - _LOTSNESTEDMESSAGE_B106._serialized_start=1469 - _LOTSNESTEDMESSAGE_B106._serialized_end=1475 - _LOTSNESTEDMESSAGE_B107._serialized_start=1477 - _LOTSNESTEDMESSAGE_B107._serialized_end=1483 - _LOTSNESTEDMESSAGE_B108._serialized_start=1485 - _LOTSNESTEDMESSAGE_B108._serialized_end=1491 - _LOTSNESTEDMESSAGE_B109._serialized_start=1493 - _LOTSNESTEDMESSAGE_B109._serialized_end=1499 - _LOTSNESTEDMESSAGE_B110._serialized_start=1501 - _LOTSNESTEDMESSAGE_B110._serialized_end=1507 - _LOTSNESTEDMESSAGE_B111._serialized_start=1509 - _LOTSNESTEDMESSAGE_B111._serialized_end=1515 - _LOTSNESTEDMESSAGE_B112._serialized_start=1517 - _LOTSNESTEDMESSAGE_B112._serialized_end=1523 - _LOTSNESTEDMESSAGE_B113._serialized_start=1525 - _LOTSNESTEDMESSAGE_B113._serialized_end=1531 - _LOTSNESTEDMESSAGE_B114._serialized_start=1533 - _LOTSNESTEDMESSAGE_B114._serialized_end=1539 - _LOTSNESTEDMESSAGE_B115._serialized_start=1541 - _LOTSNESTEDMESSAGE_B115._serialized_end=1547 - _LOTSNESTEDMESSAGE_B116._serialized_start=1549 - _LOTSNESTEDMESSAGE_B116._serialized_end=1555 - _LOTSNESTEDMESSAGE_B117._serialized_start=1557 - _LOTSNESTEDMESSAGE_B117._serialized_end=1563 - _LOTSNESTEDMESSAGE_B118._serialized_start=1565 - _LOTSNESTEDMESSAGE_B118._serialized_end=1571 - _LOTSNESTEDMESSAGE_B119._serialized_start=1573 - _LOTSNESTEDMESSAGE_B119._serialized_end=1579 - _LOTSNESTEDMESSAGE_B120._serialized_start=1581 - _LOTSNESTEDMESSAGE_B120._serialized_end=1587 - _LOTSNESTEDMESSAGE_B121._serialized_start=1589 - _LOTSNESTEDMESSAGE_B121._serialized_end=1595 - _LOTSNESTEDMESSAGE_B122._serialized_start=1597 - _LOTSNESTEDMESSAGE_B122._serialized_end=1603 - _LOTSNESTEDMESSAGE_B123._serialized_start=1605 - _LOTSNESTEDMESSAGE_B123._serialized_end=1611 - _LOTSNESTEDMESSAGE_B124._serialized_start=1613 - _LOTSNESTEDMESSAGE_B124._serialized_end=1619 - _LOTSNESTEDMESSAGE_B125._serialized_start=1621 - _LOTSNESTEDMESSAGE_B125._serialized_end=1627 - _LOTSNESTEDMESSAGE_B126._serialized_start=1629 - _LOTSNESTEDMESSAGE_B126._serialized_end=1635 - _LOTSNESTEDMESSAGE_B127._serialized_start=1637 - _LOTSNESTEDMESSAGE_B127._serialized_end=1643 - _LOTSNESTEDMESSAGE_B128._serialized_start=1645 - _LOTSNESTEDMESSAGE_B128._serialized_end=1651 - _LOTSNESTEDMESSAGE_B129._serialized_start=1653 - _LOTSNESTEDMESSAGE_B129._serialized_end=1659 - _LOTSNESTEDMESSAGE_B130._serialized_start=1661 - _LOTSNESTEDMESSAGE_B130._serialized_end=1667 - _LOTSNESTEDMESSAGE_B131._serialized_start=1669 - _LOTSNESTEDMESSAGE_B131._serialized_end=1675 - _LOTSNESTEDMESSAGE_B132._serialized_start=1677 - _LOTSNESTEDMESSAGE_B132._serialized_end=1683 - _LOTSNESTEDMESSAGE_B133._serialized_start=1685 - _LOTSNESTEDMESSAGE_B133._serialized_end=1691 - _LOTSNESTEDMESSAGE_B134._serialized_start=1693 - _LOTSNESTEDMESSAGE_B134._serialized_end=1699 - _LOTSNESTEDMESSAGE_B135._serialized_start=1701 - _LOTSNESTEDMESSAGE_B135._serialized_end=1707 - _LOTSNESTEDMESSAGE_B136._serialized_start=1709 - _LOTSNESTEDMESSAGE_B136._serialized_end=1715 - _LOTSNESTEDMESSAGE_B137._serialized_start=1717 - _LOTSNESTEDMESSAGE_B137._serialized_end=1723 - _LOTSNESTEDMESSAGE_B138._serialized_start=1725 - _LOTSNESTEDMESSAGE_B138._serialized_end=1731 - _LOTSNESTEDMESSAGE_B139._serialized_start=1733 - _LOTSNESTEDMESSAGE_B139._serialized_end=1739 - _LOTSNESTEDMESSAGE_B140._serialized_start=1741 - _LOTSNESTEDMESSAGE_B140._serialized_end=1747 - _LOTSNESTEDMESSAGE_B141._serialized_start=1749 - _LOTSNESTEDMESSAGE_B141._serialized_end=1755 - _LOTSNESTEDMESSAGE_B142._serialized_start=1757 - _LOTSNESTEDMESSAGE_B142._serialized_end=1763 - _LOTSNESTEDMESSAGE_B143._serialized_start=1765 - _LOTSNESTEDMESSAGE_B143._serialized_end=1771 - _LOTSNESTEDMESSAGE_B144._serialized_start=1773 - _LOTSNESTEDMESSAGE_B144._serialized_end=1779 - _LOTSNESTEDMESSAGE_B145._serialized_start=1781 - _LOTSNESTEDMESSAGE_B145._serialized_end=1787 - _LOTSNESTEDMESSAGE_B146._serialized_start=1789 - _LOTSNESTEDMESSAGE_B146._serialized_end=1795 - _LOTSNESTEDMESSAGE_B147._serialized_start=1797 - _LOTSNESTEDMESSAGE_B147._serialized_end=1803 - _LOTSNESTEDMESSAGE_B148._serialized_start=1805 - _LOTSNESTEDMESSAGE_B148._serialized_end=1811 - _LOTSNESTEDMESSAGE_B149._serialized_start=1813 - _LOTSNESTEDMESSAGE_B149._serialized_end=1819 - _LOTSNESTEDMESSAGE_B150._serialized_start=1821 - _LOTSNESTEDMESSAGE_B150._serialized_end=1827 - _LOTSNESTEDMESSAGE_B151._serialized_start=1829 - _LOTSNESTEDMESSAGE_B151._serialized_end=1835 - _LOTSNESTEDMESSAGE_B152._serialized_start=1837 - _LOTSNESTEDMESSAGE_B152._serialized_end=1843 - _LOTSNESTEDMESSAGE_B153._serialized_start=1845 - _LOTSNESTEDMESSAGE_B153._serialized_end=1851 - _LOTSNESTEDMESSAGE_B154._serialized_start=1853 - _LOTSNESTEDMESSAGE_B154._serialized_end=1859 - _LOTSNESTEDMESSAGE_B155._serialized_start=1861 - _LOTSNESTEDMESSAGE_B155._serialized_end=1867 - _LOTSNESTEDMESSAGE_B156._serialized_start=1869 - _LOTSNESTEDMESSAGE_B156._serialized_end=1875 - _LOTSNESTEDMESSAGE_B157._serialized_start=1877 - _LOTSNESTEDMESSAGE_B157._serialized_end=1883 - _LOTSNESTEDMESSAGE_B158._serialized_start=1885 - _LOTSNESTEDMESSAGE_B158._serialized_end=1891 - _LOTSNESTEDMESSAGE_B159._serialized_start=1893 - _LOTSNESTEDMESSAGE_B159._serialized_end=1899 - _LOTSNESTEDMESSAGE_B160._serialized_start=1901 - _LOTSNESTEDMESSAGE_B160._serialized_end=1907 - _LOTSNESTEDMESSAGE_B161._serialized_start=1909 - _LOTSNESTEDMESSAGE_B161._serialized_end=1915 - _LOTSNESTEDMESSAGE_B162._serialized_start=1917 - _LOTSNESTEDMESSAGE_B162._serialized_end=1923 - _LOTSNESTEDMESSAGE_B163._serialized_start=1925 - _LOTSNESTEDMESSAGE_B163._serialized_end=1931 - _LOTSNESTEDMESSAGE_B164._serialized_start=1933 - _LOTSNESTEDMESSAGE_B164._serialized_end=1939 - _LOTSNESTEDMESSAGE_B165._serialized_start=1941 - _LOTSNESTEDMESSAGE_B165._serialized_end=1947 - _LOTSNESTEDMESSAGE_B166._serialized_start=1949 - _LOTSNESTEDMESSAGE_B166._serialized_end=1955 - _LOTSNESTEDMESSAGE_B167._serialized_start=1957 - _LOTSNESTEDMESSAGE_B167._serialized_end=1963 - _LOTSNESTEDMESSAGE_B168._serialized_start=1965 - _LOTSNESTEDMESSAGE_B168._serialized_end=1971 - _LOTSNESTEDMESSAGE_B169._serialized_start=1973 - _LOTSNESTEDMESSAGE_B169._serialized_end=1979 - _LOTSNESTEDMESSAGE_B170._serialized_start=1981 - _LOTSNESTEDMESSAGE_B170._serialized_end=1987 - _LOTSNESTEDMESSAGE_B171._serialized_start=1989 - _LOTSNESTEDMESSAGE_B171._serialized_end=1995 - _LOTSNESTEDMESSAGE_B172._serialized_start=1997 - _LOTSNESTEDMESSAGE_B172._serialized_end=2003 - _LOTSNESTEDMESSAGE_B173._serialized_start=2005 - _LOTSNESTEDMESSAGE_B173._serialized_end=2011 - _LOTSNESTEDMESSAGE_B174._serialized_start=2013 - _LOTSNESTEDMESSAGE_B174._serialized_end=2019 - _LOTSNESTEDMESSAGE_B175._serialized_start=2021 - _LOTSNESTEDMESSAGE_B175._serialized_end=2027 - _LOTSNESTEDMESSAGE_B176._serialized_start=2029 - _LOTSNESTEDMESSAGE_B176._serialized_end=2035 - _LOTSNESTEDMESSAGE_B177._serialized_start=2037 - _LOTSNESTEDMESSAGE_B177._serialized_end=2043 - _LOTSNESTEDMESSAGE_B178._serialized_start=2045 - _LOTSNESTEDMESSAGE_B178._serialized_end=2051 - _LOTSNESTEDMESSAGE_B179._serialized_start=2053 - _LOTSNESTEDMESSAGE_B179._serialized_end=2059 - _LOTSNESTEDMESSAGE_B180._serialized_start=2061 - _LOTSNESTEDMESSAGE_B180._serialized_end=2067 - _LOTSNESTEDMESSAGE_B181._serialized_start=2069 - _LOTSNESTEDMESSAGE_B181._serialized_end=2075 - _LOTSNESTEDMESSAGE_B182._serialized_start=2077 - _LOTSNESTEDMESSAGE_B182._serialized_end=2083 - _LOTSNESTEDMESSAGE_B183._serialized_start=2085 - _LOTSNESTEDMESSAGE_B183._serialized_end=2091 - _LOTSNESTEDMESSAGE_B184._serialized_start=2093 - _LOTSNESTEDMESSAGE_B184._serialized_end=2099 - _LOTSNESTEDMESSAGE_B185._serialized_start=2101 - _LOTSNESTEDMESSAGE_B185._serialized_end=2107 - _LOTSNESTEDMESSAGE_B186._serialized_start=2109 - _LOTSNESTEDMESSAGE_B186._serialized_end=2115 - _LOTSNESTEDMESSAGE_B187._serialized_start=2117 - _LOTSNESTEDMESSAGE_B187._serialized_end=2123 - _LOTSNESTEDMESSAGE_B188._serialized_start=2125 - _LOTSNESTEDMESSAGE_B188._serialized_end=2131 - _LOTSNESTEDMESSAGE_B189._serialized_start=2133 - _LOTSNESTEDMESSAGE_B189._serialized_end=2139 - _LOTSNESTEDMESSAGE_B190._serialized_start=2141 - _LOTSNESTEDMESSAGE_B190._serialized_end=2147 - _LOTSNESTEDMESSAGE_B191._serialized_start=2149 - _LOTSNESTEDMESSAGE_B191._serialized_end=2155 - _LOTSNESTEDMESSAGE_B192._serialized_start=2157 - _LOTSNESTEDMESSAGE_B192._serialized_end=2163 - _LOTSNESTEDMESSAGE_B193._serialized_start=2165 - _LOTSNESTEDMESSAGE_B193._serialized_end=2171 - _LOTSNESTEDMESSAGE_B194._serialized_start=2173 - _LOTSNESTEDMESSAGE_B194._serialized_end=2179 - _LOTSNESTEDMESSAGE_B195._serialized_start=2181 - _LOTSNESTEDMESSAGE_B195._serialized_end=2187 - _LOTSNESTEDMESSAGE_B196._serialized_start=2189 - _LOTSNESTEDMESSAGE_B196._serialized_end=2195 - _LOTSNESTEDMESSAGE_B197._serialized_start=2197 - _LOTSNESTEDMESSAGE_B197._serialized_end=2203 - _LOTSNESTEDMESSAGE_B198._serialized_start=2205 - _LOTSNESTEDMESSAGE_B198._serialized_end=2211 - _LOTSNESTEDMESSAGE_B199._serialized_start=2213 - _LOTSNESTEDMESSAGE_B199._serialized_end=2219 - _LOTSNESTEDMESSAGE_B200._serialized_start=2221 - _LOTSNESTEDMESSAGE_B200._serialized_end=2227 - _LOTSNESTEDMESSAGE_B201._serialized_start=2229 - _LOTSNESTEDMESSAGE_B201._serialized_end=2235 - _LOTSNESTEDMESSAGE_B202._serialized_start=2237 - _LOTSNESTEDMESSAGE_B202._serialized_end=2243 - _LOTSNESTEDMESSAGE_B203._serialized_start=2245 - _LOTSNESTEDMESSAGE_B203._serialized_end=2251 - _LOTSNESTEDMESSAGE_B204._serialized_start=2253 - _LOTSNESTEDMESSAGE_B204._serialized_end=2259 - _LOTSNESTEDMESSAGE_B205._serialized_start=2261 - _LOTSNESTEDMESSAGE_B205._serialized_end=2267 - _LOTSNESTEDMESSAGE_B206._serialized_start=2269 - _LOTSNESTEDMESSAGE_B206._serialized_end=2275 - _LOTSNESTEDMESSAGE_B207._serialized_start=2277 - _LOTSNESTEDMESSAGE_B207._serialized_end=2283 - _LOTSNESTEDMESSAGE_B208._serialized_start=2285 - _LOTSNESTEDMESSAGE_B208._serialized_end=2291 - _LOTSNESTEDMESSAGE_B209._serialized_start=2293 - _LOTSNESTEDMESSAGE_B209._serialized_end=2299 - _LOTSNESTEDMESSAGE_B210._serialized_start=2301 - _LOTSNESTEDMESSAGE_B210._serialized_end=2307 - _LOTSNESTEDMESSAGE_B211._serialized_start=2309 - _LOTSNESTEDMESSAGE_B211._serialized_end=2315 - _LOTSNESTEDMESSAGE_B212._serialized_start=2317 - _LOTSNESTEDMESSAGE_B212._serialized_end=2323 - _LOTSNESTEDMESSAGE_B213._serialized_start=2325 - _LOTSNESTEDMESSAGE_B213._serialized_end=2331 - _LOTSNESTEDMESSAGE_B214._serialized_start=2333 - _LOTSNESTEDMESSAGE_B214._serialized_end=2339 - _LOTSNESTEDMESSAGE_B215._serialized_start=2341 - _LOTSNESTEDMESSAGE_B215._serialized_end=2347 - _LOTSNESTEDMESSAGE_B216._serialized_start=2349 - _LOTSNESTEDMESSAGE_B216._serialized_end=2355 - _LOTSNESTEDMESSAGE_B217._serialized_start=2357 - _LOTSNESTEDMESSAGE_B217._serialized_end=2363 - _LOTSNESTEDMESSAGE_B218._serialized_start=2365 - _LOTSNESTEDMESSAGE_B218._serialized_end=2371 - _LOTSNESTEDMESSAGE_B219._serialized_start=2373 - _LOTSNESTEDMESSAGE_B219._serialized_end=2379 - _LOTSNESTEDMESSAGE_B220._serialized_start=2381 - _LOTSNESTEDMESSAGE_B220._serialized_end=2387 - _LOTSNESTEDMESSAGE_B221._serialized_start=2389 - _LOTSNESTEDMESSAGE_B221._serialized_end=2395 - _LOTSNESTEDMESSAGE_B222._serialized_start=2397 - _LOTSNESTEDMESSAGE_B222._serialized_end=2403 - _LOTSNESTEDMESSAGE_B223._serialized_start=2405 - _LOTSNESTEDMESSAGE_B223._serialized_end=2411 - _LOTSNESTEDMESSAGE_B224._serialized_start=2413 - _LOTSNESTEDMESSAGE_B224._serialized_end=2419 - _LOTSNESTEDMESSAGE_B225._serialized_start=2421 - _LOTSNESTEDMESSAGE_B225._serialized_end=2427 - _LOTSNESTEDMESSAGE_B226._serialized_start=2429 - _LOTSNESTEDMESSAGE_B226._serialized_end=2435 - _LOTSNESTEDMESSAGE_B227._serialized_start=2437 - _LOTSNESTEDMESSAGE_B227._serialized_end=2443 - _LOTSNESTEDMESSAGE_B228._serialized_start=2445 - _LOTSNESTEDMESSAGE_B228._serialized_end=2451 - _LOTSNESTEDMESSAGE_B229._serialized_start=2453 - _LOTSNESTEDMESSAGE_B229._serialized_end=2459 - _LOTSNESTEDMESSAGE_B230._serialized_start=2461 - _LOTSNESTEDMESSAGE_B230._serialized_end=2467 - _LOTSNESTEDMESSAGE_B231._serialized_start=2469 - _LOTSNESTEDMESSAGE_B231._serialized_end=2475 - _LOTSNESTEDMESSAGE_B232._serialized_start=2477 - _LOTSNESTEDMESSAGE_B232._serialized_end=2483 - _LOTSNESTEDMESSAGE_B233._serialized_start=2485 - _LOTSNESTEDMESSAGE_B233._serialized_end=2491 - _LOTSNESTEDMESSAGE_B234._serialized_start=2493 - _LOTSNESTEDMESSAGE_B234._serialized_end=2499 - _LOTSNESTEDMESSAGE_B235._serialized_start=2501 - _LOTSNESTEDMESSAGE_B235._serialized_end=2507 - _LOTSNESTEDMESSAGE_B236._serialized_start=2509 - _LOTSNESTEDMESSAGE_B236._serialized_end=2515 - _LOTSNESTEDMESSAGE_B237._serialized_start=2517 - _LOTSNESTEDMESSAGE_B237._serialized_end=2523 - _LOTSNESTEDMESSAGE_B238._serialized_start=2525 - _LOTSNESTEDMESSAGE_B238._serialized_end=2531 - _LOTSNESTEDMESSAGE_B239._serialized_start=2533 - _LOTSNESTEDMESSAGE_B239._serialized_end=2539 - _LOTSNESTEDMESSAGE_B240._serialized_start=2541 - _LOTSNESTEDMESSAGE_B240._serialized_end=2547 - _LOTSNESTEDMESSAGE_B241._serialized_start=2549 - _LOTSNESTEDMESSAGE_B241._serialized_end=2555 - _LOTSNESTEDMESSAGE_B242._serialized_start=2557 - _LOTSNESTEDMESSAGE_B242._serialized_end=2563 - _LOTSNESTEDMESSAGE_B243._serialized_start=2565 - _LOTSNESTEDMESSAGE_B243._serialized_end=2571 - _LOTSNESTEDMESSAGE_B244._serialized_start=2573 - _LOTSNESTEDMESSAGE_B244._serialized_end=2579 - _LOTSNESTEDMESSAGE_B245._serialized_start=2581 - _LOTSNESTEDMESSAGE_B245._serialized_end=2587 - _LOTSNESTEDMESSAGE_B246._serialized_start=2589 - _LOTSNESTEDMESSAGE_B246._serialized_end=2595 - _LOTSNESTEDMESSAGE_B247._serialized_start=2597 - _LOTSNESTEDMESSAGE_B247._serialized_end=2603 - _LOTSNESTEDMESSAGE_B248._serialized_start=2605 - _LOTSNESTEDMESSAGE_B248._serialized_end=2611 - _LOTSNESTEDMESSAGE_B249._serialized_start=2613 - _LOTSNESTEDMESSAGE_B249._serialized_end=2619 - _LOTSNESTEDMESSAGE_B250._serialized_start=2621 - _LOTSNESTEDMESSAGE_B250._serialized_end=2627 - _LOTSNESTEDMESSAGE_B251._serialized_start=2629 - _LOTSNESTEDMESSAGE_B251._serialized_end=2635 - _LOTSNESTEDMESSAGE_B252._serialized_start=2637 - _LOTSNESTEDMESSAGE_B252._serialized_end=2643 - _LOTSNESTEDMESSAGE_B253._serialized_start=2645 - _LOTSNESTEDMESSAGE_B253._serialized_end=2651 - _LOTSNESTEDMESSAGE_B254._serialized_start=2653 - _LOTSNESTEDMESSAGE_B254._serialized_end=2659 - _LOTSNESTEDMESSAGE_B255._serialized_start=2661 - _LOTSNESTEDMESSAGE_B255._serialized_end=2667 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/no_package_pb2.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/no_package_pb2.py deleted file mode 100644 index d46dee080a..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/no_package_pb2.py +++ /dev/null @@ -1,27 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/internal/no_package.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n)google/protobuf/internal/no_package.proto\";\n\x10NoPackageMessage\x12\'\n\x0fno_package_enum\x18\x01 \x01(\x0e\x32\x0e.NoPackageEnum*?\n\rNoPackageEnum\x12\x16\n\x12NO_PACKAGE_VALUE_0\x10\x00\x12\x16\n\x12NO_PACKAGE_VALUE_1\x10\x01') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.internal.no_package_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - _NOPACKAGEENUM._serialized_start=106 - _NOPACKAGEENUM._serialized_end=169 - _NOPACKAGEMESSAGE._serialized_start=45 - _NOPACKAGEMESSAGE._serialized_end=104 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/python_message.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/python_message.py deleted file mode 100644 index 2921d5cb6e..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/python_message.py +++ /dev/null @@ -1,1539 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -# This code is meant to work on Python 2.4 and above only. -# -# TODO(robinson): Helpers for verbose, common checks like seeing if a -# descriptor's cpp_type is CPPTYPE_MESSAGE. - -"""Contains a metaclass and helper functions used to create -protocol message classes from Descriptor objects at runtime. - -Recall that a metaclass is the "type" of a class. -(A class is to a metaclass what an instance is to a class.) - -In this case, we use the GeneratedProtocolMessageType metaclass -to inject all the useful functionality into the classes -output by the protocol compiler at compile-time. - -The upshot of all this is that the real implementation -details for ALL pure-Python protocol buffers are *here in -this file*. -""" - -__author__ = 'robinson@google.com (Will Robinson)' - -from io import BytesIO -import struct -import sys -import weakref - -# We use "as" to avoid name collisions with variables. -from google.protobuf.internal import api_implementation -from google.protobuf.internal import containers -from google.protobuf.internal import decoder -from google.protobuf.internal import encoder -from google.protobuf.internal import enum_type_wrapper -from google.protobuf.internal import extension_dict -from google.protobuf.internal import message_listener as message_listener_mod -from google.protobuf.internal import type_checkers -from google.protobuf.internal import well_known_types -from google.protobuf.internal import wire_format -from google.protobuf import descriptor as descriptor_mod -from google.protobuf import message as message_mod -from google.protobuf import text_format - -_FieldDescriptor = descriptor_mod.FieldDescriptor -_AnyFullTypeName = 'google.protobuf.Any' -_ExtensionDict = extension_dict._ExtensionDict - -class GeneratedProtocolMessageType(type): - - """Metaclass for protocol message classes created at runtime from Descriptors. - - We add implementations for all methods described in the Message class. We - also create properties to allow getting/setting all fields in the protocol - message. Finally, we create slots to prevent users from accidentally - "setting" nonexistent fields in the protocol message, which then wouldn't get - serialized / deserialized properly. - - The protocol compiler currently uses this metaclass to create protocol - message classes at runtime. Clients can also manually create their own - classes at runtime, as in this example: - - mydescriptor = Descriptor(.....) - factory = symbol_database.Default() - factory.pool.AddDescriptor(mydescriptor) - MyProtoClass = factory.GetPrototype(mydescriptor) - myproto_instance = MyProtoClass() - myproto.foo_field = 23 - ... - """ - - # Must be consistent with the protocol-compiler code in - # proto2/compiler/internal/generator.*. - _DESCRIPTOR_KEY = 'DESCRIPTOR' - - def __new__(cls, name, bases, dictionary): - """Custom allocation for runtime-generated class types. - - We override __new__ because this is apparently the only place - where we can meaningfully set __slots__ on the class we're creating(?). - (The interplay between metaclasses and slots is not very well-documented). - - Args: - name: Name of the class (ignored, but required by the - metaclass protocol). - bases: Base classes of the class we're constructing. - (Should be message.Message). We ignore this field, but - it's required by the metaclass protocol - dictionary: The class dictionary of the class we're - constructing. dictionary[_DESCRIPTOR_KEY] must contain - a Descriptor object describing this protocol message - type. - - Returns: - Newly-allocated class. - - Raises: - RuntimeError: Generated code only work with python cpp extension. - """ - descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY] - - if isinstance(descriptor, str): - raise RuntimeError('The generated code only work with python cpp ' - 'extension, but it is using pure python runtime.') - - # If a concrete class already exists for this descriptor, don't try to - # create another. Doing so will break any messages that already exist with - # the existing class. - # - # The C++ implementation appears to have its own internal `PyMessageFactory` - # to achieve similar results. - # - # This most commonly happens in `text_format.py` when using descriptors from - # a custom pool; it calls symbol_database.Global().getPrototype() on a - # descriptor which already has an existing concrete class. - new_class = getattr(descriptor, '_concrete_class', None) - if new_class: - return new_class - - if descriptor.full_name in well_known_types.WKTBASES: - bases += (well_known_types.WKTBASES[descriptor.full_name],) - _AddClassAttributesForNestedExtensions(descriptor, dictionary) - _AddSlots(descriptor, dictionary) - - superclass = super(GeneratedProtocolMessageType, cls) - new_class = superclass.__new__(cls, name, bases, dictionary) - return new_class - - def __init__(cls, name, bases, dictionary): - """Here we perform the majority of our work on the class. - We add enum getters, an __init__ method, implementations - of all Message methods, and properties for all fields - in the protocol type. - - Args: - name: Name of the class (ignored, but required by the - metaclass protocol). - bases: Base classes of the class we're constructing. - (Should be message.Message). We ignore this field, but - it's required by the metaclass protocol - dictionary: The class dictionary of the class we're - constructing. dictionary[_DESCRIPTOR_KEY] must contain - a Descriptor object describing this protocol message - type. - """ - descriptor = dictionary[GeneratedProtocolMessageType._DESCRIPTOR_KEY] - - # If this is an _existing_ class looked up via `_concrete_class` in the - # __new__ method above, then we don't need to re-initialize anything. - existing_class = getattr(descriptor, '_concrete_class', None) - if existing_class: - assert existing_class is cls, ( - 'Duplicate `GeneratedProtocolMessageType` created for descriptor %r' - % (descriptor.full_name)) - return - - cls._decoders_by_tag = {} - if (descriptor.has_options and - descriptor.GetOptions().message_set_wire_format): - cls._decoders_by_tag[decoder.MESSAGE_SET_ITEM_TAG] = ( - decoder.MessageSetItemDecoder(descriptor), None) - - # Attach stuff to each FieldDescriptor for quick lookup later on. - for field in descriptor.fields: - _AttachFieldHelpers(cls, field) - - descriptor._concrete_class = cls # pylint: disable=protected-access - _AddEnumValues(descriptor, cls) - _AddInitMethod(descriptor, cls) - _AddPropertiesForFields(descriptor, cls) - _AddPropertiesForExtensions(descriptor, cls) - _AddStaticMethods(cls) - _AddMessageMethods(descriptor, cls) - _AddPrivateHelperMethods(descriptor, cls) - - superclass = super(GeneratedProtocolMessageType, cls) - superclass.__init__(name, bases, dictionary) - - -# Stateless helpers for GeneratedProtocolMessageType below. -# Outside clients should not access these directly. -# -# I opted not to make any of these methods on the metaclass, to make it more -# clear that I'm not really using any state there and to keep clients from -# thinking that they have direct access to these construction helpers. - - -def _PropertyName(proto_field_name): - """Returns the name of the public property attribute which - clients can use to get and (in some cases) set the value - of a protocol message field. - - Args: - proto_field_name: The protocol message field name, exactly - as it appears (or would appear) in a .proto file. - """ - # TODO(robinson): Escape Python keywords (e.g., yield), and test this support. - # nnorwitz makes my day by writing: - # """ - # FYI. See the keyword module in the stdlib. This could be as simple as: - # - # if keyword.iskeyword(proto_field_name): - # return proto_field_name + "_" - # return proto_field_name - # """ - # Kenton says: The above is a BAD IDEA. People rely on being able to use - # getattr() and setattr() to reflectively manipulate field values. If we - # rename the properties, then every such user has to also make sure to apply - # the same transformation. Note that currently if you name a field "yield", - # you can still access it just fine using getattr/setattr -- it's not even - # that cumbersome to do so. - # TODO(kenton): Remove this method entirely if/when everyone agrees with my - # position. - return proto_field_name - - -def _AddSlots(message_descriptor, dictionary): - """Adds a __slots__ entry to dictionary, containing the names of all valid - attributes for this message type. - - Args: - message_descriptor: A Descriptor instance describing this message type. - dictionary: Class dictionary to which we'll add a '__slots__' entry. - """ - dictionary['__slots__'] = ['_cached_byte_size', - '_cached_byte_size_dirty', - '_fields', - '_unknown_fields', - '_unknown_field_set', - '_is_present_in_parent', - '_listener', - '_listener_for_children', - '__weakref__', - '_oneofs'] - - -def _IsMessageSetExtension(field): - return (field.is_extension and - field.containing_type.has_options and - field.containing_type.GetOptions().message_set_wire_format and - field.type == _FieldDescriptor.TYPE_MESSAGE and - field.label == _FieldDescriptor.LABEL_OPTIONAL) - - -def _IsMapField(field): - return (field.type == _FieldDescriptor.TYPE_MESSAGE and - field.message_type.has_options and - field.message_type.GetOptions().map_entry) - - -def _IsMessageMapField(field): - value_type = field.message_type.fields_by_name['value'] - return value_type.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE - - -def _AttachFieldHelpers(cls, field_descriptor): - is_repeated = (field_descriptor.label == _FieldDescriptor.LABEL_REPEATED) - is_packable = (is_repeated and - wire_format.IsTypePackable(field_descriptor.type)) - is_proto3 = field_descriptor.containing_type.syntax == 'proto3' - if not is_packable: - is_packed = False - elif field_descriptor.containing_type.syntax == 'proto2': - is_packed = (field_descriptor.has_options and - field_descriptor.GetOptions().packed) - else: - has_packed_false = (field_descriptor.has_options and - field_descriptor.GetOptions().HasField('packed') and - field_descriptor.GetOptions().packed == False) - is_packed = not has_packed_false - is_map_entry = _IsMapField(field_descriptor) - - if is_map_entry: - field_encoder = encoder.MapEncoder(field_descriptor) - sizer = encoder.MapSizer(field_descriptor, - _IsMessageMapField(field_descriptor)) - elif _IsMessageSetExtension(field_descriptor): - field_encoder = encoder.MessageSetItemEncoder(field_descriptor.number) - sizer = encoder.MessageSetItemSizer(field_descriptor.number) - else: - field_encoder = type_checkers.TYPE_TO_ENCODER[field_descriptor.type]( - field_descriptor.number, is_repeated, is_packed) - sizer = type_checkers.TYPE_TO_SIZER[field_descriptor.type]( - field_descriptor.number, is_repeated, is_packed) - - field_descriptor._encoder = field_encoder - field_descriptor._sizer = sizer - field_descriptor._default_constructor = _DefaultValueConstructorForField( - field_descriptor) - - def AddDecoder(wiretype, is_packed): - tag_bytes = encoder.TagBytes(field_descriptor.number, wiretype) - decode_type = field_descriptor.type - if (decode_type == _FieldDescriptor.TYPE_ENUM and - type_checkers.SupportsOpenEnums(field_descriptor)): - decode_type = _FieldDescriptor.TYPE_INT32 - - oneof_descriptor = None - clear_if_default = False - if field_descriptor.containing_oneof is not None: - oneof_descriptor = field_descriptor - elif (is_proto3 and not is_repeated and - field_descriptor.cpp_type != _FieldDescriptor.CPPTYPE_MESSAGE): - clear_if_default = True - - if is_map_entry: - is_message_map = _IsMessageMapField(field_descriptor) - - field_decoder = decoder.MapDecoder( - field_descriptor, _GetInitializeDefaultForMap(field_descriptor), - is_message_map) - elif decode_type == _FieldDescriptor.TYPE_STRING: - field_decoder = decoder.StringDecoder( - field_descriptor.number, is_repeated, is_packed, - field_descriptor, field_descriptor._default_constructor, - clear_if_default) - elif field_descriptor.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - field_decoder = type_checkers.TYPE_TO_DECODER[decode_type]( - field_descriptor.number, is_repeated, is_packed, - field_descriptor, field_descriptor._default_constructor) - else: - field_decoder = type_checkers.TYPE_TO_DECODER[decode_type]( - field_descriptor.number, is_repeated, is_packed, - # pylint: disable=protected-access - field_descriptor, field_descriptor._default_constructor, - clear_if_default) - - cls._decoders_by_tag[tag_bytes] = (field_decoder, oneof_descriptor) - - AddDecoder(type_checkers.FIELD_TYPE_TO_WIRE_TYPE[field_descriptor.type], - False) - - if is_repeated and wire_format.IsTypePackable(field_descriptor.type): - # To support wire compatibility of adding packed = true, add a decoder for - # packed values regardless of the field's options. - AddDecoder(wire_format.WIRETYPE_LENGTH_DELIMITED, True) - - -def _AddClassAttributesForNestedExtensions(descriptor, dictionary): - extensions = descriptor.extensions_by_name - for extension_name, extension_field in extensions.items(): - assert extension_name not in dictionary - dictionary[extension_name] = extension_field - - -def _AddEnumValues(descriptor, cls): - """Sets class-level attributes for all enum fields defined in this message. - - Also exporting a class-level object that can name enum values. - - Args: - descriptor: Descriptor object for this message type. - cls: Class we're constructing for this message type. - """ - for enum_type in descriptor.enum_types: - setattr(cls, enum_type.name, enum_type_wrapper.EnumTypeWrapper(enum_type)) - for enum_value in enum_type.values: - setattr(cls, enum_value.name, enum_value.number) - - -def _GetInitializeDefaultForMap(field): - if field.label != _FieldDescriptor.LABEL_REPEATED: - raise ValueError('map_entry set on non-repeated field %s' % ( - field.name)) - fields_by_name = field.message_type.fields_by_name - key_checker = type_checkers.GetTypeChecker(fields_by_name['key']) - - value_field = fields_by_name['value'] - if _IsMessageMapField(field): - def MakeMessageMapDefault(message): - return containers.MessageMap( - message._listener_for_children, value_field.message_type, key_checker, - field.message_type) - return MakeMessageMapDefault - else: - value_checker = type_checkers.GetTypeChecker(value_field) - def MakePrimitiveMapDefault(message): - return containers.ScalarMap( - message._listener_for_children, key_checker, value_checker, - field.message_type) - return MakePrimitiveMapDefault - -def _DefaultValueConstructorForField(field): - """Returns a function which returns a default value for a field. - - Args: - field: FieldDescriptor object for this field. - - The returned function has one argument: - message: Message instance containing this field, or a weakref proxy - of same. - - That function in turn returns a default value for this field. The default - value may refer back to |message| via a weak reference. - """ - - if _IsMapField(field): - return _GetInitializeDefaultForMap(field) - - if field.label == _FieldDescriptor.LABEL_REPEATED: - if field.has_default_value and field.default_value != []: - raise ValueError('Repeated field default value not empty list: %s' % ( - field.default_value)) - if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - # We can't look at _concrete_class yet since it might not have - # been set. (Depends on order in which we initialize the classes). - message_type = field.message_type - def MakeRepeatedMessageDefault(message): - return containers.RepeatedCompositeFieldContainer( - message._listener_for_children, field.message_type) - return MakeRepeatedMessageDefault - else: - type_checker = type_checkers.GetTypeChecker(field) - def MakeRepeatedScalarDefault(message): - return containers.RepeatedScalarFieldContainer( - message._listener_for_children, type_checker) - return MakeRepeatedScalarDefault - - if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - # _concrete_class may not yet be initialized. - message_type = field.message_type - def MakeSubMessageDefault(message): - assert getattr(message_type, '_concrete_class', None), ( - 'Uninitialized concrete class found for field %r (message type %r)' - % (field.full_name, message_type.full_name)) - result = message_type._concrete_class() - result._SetListener( - _OneofListener(message, field) - if field.containing_oneof is not None - else message._listener_for_children) - return result - return MakeSubMessageDefault - - def MakeScalarDefault(message): - # TODO(protobuf-team): This may be broken since there may not be - # default_value. Combine with has_default_value somehow. - return field.default_value - return MakeScalarDefault - - -def _ReraiseTypeErrorWithFieldName(message_name, field_name): - """Re-raise the currently-handled TypeError with the field name added.""" - exc = sys.exc_info()[1] - if len(exc.args) == 1 and type(exc) is TypeError: - # simple TypeError; add field name to exception message - exc = TypeError('%s for field %s.%s' % (str(exc), message_name, field_name)) - - # re-raise possibly-amended exception with original traceback: - raise exc.with_traceback(sys.exc_info()[2]) - - -def _AddInitMethod(message_descriptor, cls): - """Adds an __init__ method to cls.""" - - def _GetIntegerEnumValue(enum_type, value): - """Convert a string or integer enum value to an integer. - - If the value is a string, it is converted to the enum value in - enum_type with the same name. If the value is not a string, it's - returned as-is. (No conversion or bounds-checking is done.) - """ - if isinstance(value, str): - try: - return enum_type.values_by_name[value].number - except KeyError: - raise ValueError('Enum type %s: unknown label "%s"' % ( - enum_type.full_name, value)) - return value - - def init(self, **kwargs): - self._cached_byte_size = 0 - self._cached_byte_size_dirty = len(kwargs) > 0 - self._fields = {} - # Contains a mapping from oneof field descriptors to the descriptor - # of the currently set field in that oneof field. - self._oneofs = {} - - # _unknown_fields is () when empty for efficiency, and will be turned into - # a list if fields are added. - self._unknown_fields = () - # _unknown_field_set is None when empty for efficiency, and will be - # turned into UnknownFieldSet struct if fields are added. - self._unknown_field_set = None # pylint: disable=protected-access - self._is_present_in_parent = False - self._listener = message_listener_mod.NullMessageListener() - self._listener_for_children = _Listener(self) - for field_name, field_value in kwargs.items(): - field = _GetFieldByName(message_descriptor, field_name) - if field is None: - raise TypeError('%s() got an unexpected keyword argument "%s"' % - (message_descriptor.name, field_name)) - if field_value is None: - # field=None is the same as no field at all. - continue - if field.label == _FieldDescriptor.LABEL_REPEATED: - copy = field._default_constructor(self) - if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: # Composite - if _IsMapField(field): - if _IsMessageMapField(field): - for key in field_value: - copy[key].MergeFrom(field_value[key]) - else: - copy.update(field_value) - else: - for val in field_value: - if isinstance(val, dict): - copy.add(**val) - else: - copy.add().MergeFrom(val) - else: # Scalar - if field.cpp_type == _FieldDescriptor.CPPTYPE_ENUM: - field_value = [_GetIntegerEnumValue(field.enum_type, val) - for val in field_value] - copy.extend(field_value) - self._fields[field] = copy - elif field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - copy = field._default_constructor(self) - new_val = field_value - if isinstance(field_value, dict): - new_val = field.message_type._concrete_class(**field_value) - try: - copy.MergeFrom(new_val) - except TypeError: - _ReraiseTypeErrorWithFieldName(message_descriptor.name, field_name) - self._fields[field] = copy - else: - if field.cpp_type == _FieldDescriptor.CPPTYPE_ENUM: - field_value = _GetIntegerEnumValue(field.enum_type, field_value) - try: - setattr(self, field_name, field_value) - except TypeError: - _ReraiseTypeErrorWithFieldName(message_descriptor.name, field_name) - - init.__module__ = None - init.__doc__ = None - cls.__init__ = init - - -def _GetFieldByName(message_descriptor, field_name): - """Returns a field descriptor by field name. - - Args: - message_descriptor: A Descriptor describing all fields in message. - field_name: The name of the field to retrieve. - Returns: - The field descriptor associated with the field name. - """ - try: - return message_descriptor.fields_by_name[field_name] - except KeyError: - raise ValueError('Protocol message %s has no "%s" field.' % - (message_descriptor.name, field_name)) - - -def _AddPropertiesForFields(descriptor, cls): - """Adds properties for all fields in this protocol message type.""" - for field in descriptor.fields: - _AddPropertiesForField(field, cls) - - if descriptor.is_extendable: - # _ExtensionDict is just an adaptor with no state so we allocate a new one - # every time it is accessed. - cls.Extensions = property(lambda self: _ExtensionDict(self)) - - -def _AddPropertiesForField(field, cls): - """Adds a public property for a protocol message field. - Clients can use this property to get and (in the case - of non-repeated scalar fields) directly set the value - of a protocol message field. - - Args: - field: A FieldDescriptor for this field. - cls: The class we're constructing. - """ - # Catch it if we add other types that we should - # handle specially here. - assert _FieldDescriptor.MAX_CPPTYPE == 10 - - constant_name = field.name.upper() + '_FIELD_NUMBER' - setattr(cls, constant_name, field.number) - - if field.label == _FieldDescriptor.LABEL_REPEATED: - _AddPropertiesForRepeatedField(field, cls) - elif field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - _AddPropertiesForNonRepeatedCompositeField(field, cls) - else: - _AddPropertiesForNonRepeatedScalarField(field, cls) - - -class _FieldProperty(property): - __slots__ = ('DESCRIPTOR',) - - def __init__(self, descriptor, getter, setter, doc): - property.__init__(self, getter, setter, doc=doc) - self.DESCRIPTOR = descriptor - - -def _AddPropertiesForRepeatedField(field, cls): - """Adds a public property for a "repeated" protocol message field. Clients - can use this property to get the value of the field, which will be either a - RepeatedScalarFieldContainer or RepeatedCompositeFieldContainer (see - below). - - Note that when clients add values to these containers, we perform - type-checking in the case of repeated scalar fields, and we also set any - necessary "has" bits as a side-effect. - - Args: - field: A FieldDescriptor for this field. - cls: The class we're constructing. - """ - proto_field_name = field.name - property_name = _PropertyName(proto_field_name) - - def getter(self): - field_value = self._fields.get(field) - if field_value is None: - # Construct a new object to represent this field. - field_value = field._default_constructor(self) - - # Atomically check if another thread has preempted us and, if not, swap - # in the new object we just created. If someone has preempted us, we - # take that object and discard ours. - # WARNING: We are relying on setdefault() being atomic. This is true - # in CPython but we haven't investigated others. This warning appears - # in several other locations in this file. - field_value = self._fields.setdefault(field, field_value) - return field_value - getter.__module__ = None - getter.__doc__ = 'Getter for %s.' % proto_field_name - - # We define a setter just so we can throw an exception with a more - # helpful error message. - def setter(self, new_value): - raise AttributeError('Assignment not allowed to repeated field ' - '"%s" in protocol message object.' % proto_field_name) - - doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name - setattr(cls, property_name, _FieldProperty(field, getter, setter, doc=doc)) - - -def _AddPropertiesForNonRepeatedScalarField(field, cls): - """Adds a public property for a nonrepeated, scalar protocol message field. - Clients can use this property to get and directly set the value of the field. - Note that when the client sets the value of a field by using this property, - all necessary "has" bits are set as a side-effect, and we also perform - type-checking. - - Args: - field: A FieldDescriptor for this field. - cls: The class we're constructing. - """ - proto_field_name = field.name - property_name = _PropertyName(proto_field_name) - type_checker = type_checkers.GetTypeChecker(field) - default_value = field.default_value - is_proto3 = field.containing_type.syntax == 'proto3' - - def getter(self): - # TODO(protobuf-team): This may be broken since there may not be - # default_value. Combine with has_default_value somehow. - return self._fields.get(field, default_value) - getter.__module__ = None - getter.__doc__ = 'Getter for %s.' % proto_field_name - - clear_when_set_to_default = is_proto3 and not field.containing_oneof - - def field_setter(self, new_value): - # pylint: disable=protected-access - # Testing the value for truthiness captures all of the proto3 defaults - # (0, 0.0, enum 0, and False). - try: - new_value = type_checker.CheckValue(new_value) - except TypeError as e: - raise TypeError( - 'Cannot set %s to %.1024r: %s' % (field.full_name, new_value, e)) - if clear_when_set_to_default and not new_value: - self._fields.pop(field, None) - else: - self._fields[field] = new_value - # Check _cached_byte_size_dirty inline to improve performance, since scalar - # setters are called frequently. - if not self._cached_byte_size_dirty: - self._Modified() - - if field.containing_oneof: - def setter(self, new_value): - field_setter(self, new_value) - self._UpdateOneofState(field) - else: - setter = field_setter - - setter.__module__ = None - setter.__doc__ = 'Setter for %s.' % proto_field_name - - # Add a property to encapsulate the getter/setter. - doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name - setattr(cls, property_name, _FieldProperty(field, getter, setter, doc=doc)) - - -def _AddPropertiesForNonRepeatedCompositeField(field, cls): - """Adds a public property for a nonrepeated, composite protocol message field. - A composite field is a "group" or "message" field. - - Clients can use this property to get the value of the field, but cannot - assign to the property directly. - - Args: - field: A FieldDescriptor for this field. - cls: The class we're constructing. - """ - # TODO(robinson): Remove duplication with similar method - # for non-repeated scalars. - proto_field_name = field.name - property_name = _PropertyName(proto_field_name) - - def getter(self): - field_value = self._fields.get(field) - if field_value is None: - # Construct a new object to represent this field. - field_value = field._default_constructor(self) - - # Atomically check if another thread has preempted us and, if not, swap - # in the new object we just created. If someone has preempted us, we - # take that object and discard ours. - # WARNING: We are relying on setdefault() being atomic. This is true - # in CPython but we haven't investigated others. This warning appears - # in several other locations in this file. - field_value = self._fields.setdefault(field, field_value) - return field_value - getter.__module__ = None - getter.__doc__ = 'Getter for %s.' % proto_field_name - - # We define a setter just so we can throw an exception with a more - # helpful error message. - def setter(self, new_value): - raise AttributeError('Assignment not allowed to composite field ' - '"%s" in protocol message object.' % proto_field_name) - - # Add a property to encapsulate the getter. - doc = 'Magic attribute generated for "%s" proto field.' % proto_field_name - setattr(cls, property_name, _FieldProperty(field, getter, setter, doc=doc)) - - -def _AddPropertiesForExtensions(descriptor, cls): - """Adds properties for all fields in this protocol message type.""" - extensions = descriptor.extensions_by_name - for extension_name, extension_field in extensions.items(): - constant_name = extension_name.upper() + '_FIELD_NUMBER' - setattr(cls, constant_name, extension_field.number) - - # TODO(amauryfa): Migrate all users of these attributes to functions like - # pool.FindExtensionByNumber(descriptor). - if descriptor.file is not None: - # TODO(amauryfa): Use cls.MESSAGE_FACTORY.pool when available. - pool = descriptor.file.pool - cls._extensions_by_number = pool._extensions_by_number[descriptor] - cls._extensions_by_name = pool._extensions_by_name[descriptor] - -def _AddStaticMethods(cls): - # TODO(robinson): This probably needs to be thread-safe(?) - def RegisterExtension(extension_handle): - extension_handle.containing_type = cls.DESCRIPTOR - # TODO(amauryfa): Use cls.MESSAGE_FACTORY.pool when available. - # pylint: disable=protected-access - cls.DESCRIPTOR.file.pool._AddExtensionDescriptor(extension_handle) - _AttachFieldHelpers(cls, extension_handle) - cls.RegisterExtension = staticmethod(RegisterExtension) - - def FromString(s): - message = cls() - message.MergeFromString(s) - return message - cls.FromString = staticmethod(FromString) - - -def _IsPresent(item): - """Given a (FieldDescriptor, value) tuple from _fields, return true if the - value should be included in the list returned by ListFields().""" - - if item[0].label == _FieldDescriptor.LABEL_REPEATED: - return bool(item[1]) - elif item[0].cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - return item[1]._is_present_in_parent - else: - return True - - -def _AddListFieldsMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - - def ListFields(self): - all_fields = [item for item in self._fields.items() if _IsPresent(item)] - all_fields.sort(key = lambda item: item[0].number) - return all_fields - - cls.ListFields = ListFields - -_PROTO3_ERROR_TEMPLATE = \ - ('Protocol message %s has no non-repeated submessage field "%s" ' - 'nor marked as optional') -_PROTO2_ERROR_TEMPLATE = 'Protocol message %s has no non-repeated field "%s"' - -def _AddHasFieldMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - - is_proto3 = (message_descriptor.syntax == "proto3") - error_msg = _PROTO3_ERROR_TEMPLATE if is_proto3 else _PROTO2_ERROR_TEMPLATE - - hassable_fields = {} - for field in message_descriptor.fields: - if field.label == _FieldDescriptor.LABEL_REPEATED: - continue - # For proto3, only submessages and fields inside a oneof have presence. - if (is_proto3 and field.cpp_type != _FieldDescriptor.CPPTYPE_MESSAGE and - not field.containing_oneof): - continue - hassable_fields[field.name] = field - - # Has methods are supported for oneof descriptors. - for oneof in message_descriptor.oneofs: - hassable_fields[oneof.name] = oneof - - def HasField(self, field_name): - try: - field = hassable_fields[field_name] - except KeyError: - raise ValueError(error_msg % (message_descriptor.full_name, field_name)) - - if isinstance(field, descriptor_mod.OneofDescriptor): - try: - return HasField(self, self._oneofs[field].name) - except KeyError: - return False - else: - if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - value = self._fields.get(field) - return value is not None and value._is_present_in_parent - else: - return field in self._fields - - cls.HasField = HasField - - -def _AddClearFieldMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - def ClearField(self, field_name): - try: - field = message_descriptor.fields_by_name[field_name] - except KeyError: - try: - field = message_descriptor.oneofs_by_name[field_name] - if field in self._oneofs: - field = self._oneofs[field] - else: - return - except KeyError: - raise ValueError('Protocol message %s has no "%s" field.' % - (message_descriptor.name, field_name)) - - if field in self._fields: - # To match the C++ implementation, we need to invalidate iterators - # for map fields when ClearField() happens. - if hasattr(self._fields[field], 'InvalidateIterators'): - self._fields[field].InvalidateIterators() - - # Note: If the field is a sub-message, its listener will still point - # at us. That's fine, because the worst than can happen is that it - # will call _Modified() and invalidate our byte size. Big deal. - del self._fields[field] - - if self._oneofs.get(field.containing_oneof, None) is field: - del self._oneofs[field.containing_oneof] - - # Always call _Modified() -- even if nothing was changed, this is - # a mutating method, and thus calling it should cause the field to become - # present in the parent message. - self._Modified() - - cls.ClearField = ClearField - - -def _AddClearExtensionMethod(cls): - """Helper for _AddMessageMethods().""" - def ClearExtension(self, extension_handle): - extension_dict._VerifyExtensionHandle(self, extension_handle) - - # Similar to ClearField(), above. - if extension_handle in self._fields: - del self._fields[extension_handle] - self._Modified() - cls.ClearExtension = ClearExtension - - -def _AddHasExtensionMethod(cls): - """Helper for _AddMessageMethods().""" - def HasExtension(self, extension_handle): - extension_dict._VerifyExtensionHandle(self, extension_handle) - if extension_handle.label == _FieldDescriptor.LABEL_REPEATED: - raise KeyError('"%s" is repeated.' % extension_handle.full_name) - - if extension_handle.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - value = self._fields.get(extension_handle) - return value is not None and value._is_present_in_parent - else: - return extension_handle in self._fields - cls.HasExtension = HasExtension - -def _InternalUnpackAny(msg): - """Unpacks Any message and returns the unpacked message. - - This internal method is different from public Any Unpack method which takes - the target message as argument. _InternalUnpackAny method does not have - target message type and need to find the message type in descriptor pool. - - Args: - msg: An Any message to be unpacked. - - Returns: - The unpacked message. - """ - # TODO(amauryfa): Don't use the factory of generated messages. - # To make Any work with custom factories, use the message factory of the - # parent message. - # pylint: disable=g-import-not-at-top - from google.protobuf import symbol_database - factory = symbol_database.Default() - - type_url = msg.type_url - - if not type_url: - return None - - # TODO(haberman): For now we just strip the hostname. Better logic will be - # required. - type_name = type_url.split('/')[-1] - descriptor = factory.pool.FindMessageTypeByName(type_name) - - if descriptor is None: - return None - - message_class = factory.GetPrototype(descriptor) - message = message_class() - - message.ParseFromString(msg.value) - return message - - -def _AddEqualsMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - def __eq__(self, other): - if (not isinstance(other, message_mod.Message) or - other.DESCRIPTOR != self.DESCRIPTOR): - return False - - if self is other: - return True - - if self.DESCRIPTOR.full_name == _AnyFullTypeName: - any_a = _InternalUnpackAny(self) - any_b = _InternalUnpackAny(other) - if any_a and any_b: - return any_a == any_b - - if not self.ListFields() == other.ListFields(): - return False - - # TODO(jieluo): Fix UnknownFieldSet to consider MessageSet extensions, - # then use it for the comparison. - unknown_fields = list(self._unknown_fields) - unknown_fields.sort() - other_unknown_fields = list(other._unknown_fields) - other_unknown_fields.sort() - return unknown_fields == other_unknown_fields - - cls.__eq__ = __eq__ - - -def _AddStrMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - def __str__(self): - return text_format.MessageToString(self) - cls.__str__ = __str__ - - -def _AddReprMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - def __repr__(self): - return text_format.MessageToString(self) - cls.__repr__ = __repr__ - - -def _AddUnicodeMethod(unused_message_descriptor, cls): - """Helper for _AddMessageMethods().""" - - def __unicode__(self): - return text_format.MessageToString(self, as_utf8=True).decode('utf-8') - cls.__unicode__ = __unicode__ - - -def _BytesForNonRepeatedElement(value, field_number, field_type): - """Returns the number of bytes needed to serialize a non-repeated element. - The returned byte count includes space for tag information and any - other additional space associated with serializing value. - - Args: - value: Value we're serializing. - field_number: Field number of this value. (Since the field number - is stored as part of a varint-encoded tag, this has an impact - on the total bytes required to serialize the value). - field_type: The type of the field. One of the TYPE_* constants - within FieldDescriptor. - """ - try: - fn = type_checkers.TYPE_TO_BYTE_SIZE_FN[field_type] - return fn(field_number, value) - except KeyError: - raise message_mod.EncodeError('Unrecognized field type: %d' % field_type) - - -def _AddByteSizeMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - - def ByteSize(self): - if not self._cached_byte_size_dirty: - return self._cached_byte_size - - size = 0 - descriptor = self.DESCRIPTOR - if descriptor.GetOptions().map_entry: - # Fields of map entry should always be serialized. - size = descriptor.fields_by_name['key']._sizer(self.key) - size += descriptor.fields_by_name['value']._sizer(self.value) - else: - for field_descriptor, field_value in self.ListFields(): - size += field_descriptor._sizer(field_value) - for tag_bytes, value_bytes in self._unknown_fields: - size += len(tag_bytes) + len(value_bytes) - - self._cached_byte_size = size - self._cached_byte_size_dirty = False - self._listener_for_children.dirty = False - return size - - cls.ByteSize = ByteSize - - -def _AddSerializeToStringMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - - def SerializeToString(self, **kwargs): - # Check if the message has all of its required fields set. - if not self.IsInitialized(): - raise message_mod.EncodeError( - 'Message %s is missing required fields: %s' % ( - self.DESCRIPTOR.full_name, ','.join(self.FindInitializationErrors()))) - return self.SerializePartialToString(**kwargs) - cls.SerializeToString = SerializeToString - - -def _AddSerializePartialToStringMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - - def SerializePartialToString(self, **kwargs): - out = BytesIO() - self._InternalSerialize(out.write, **kwargs) - return out.getvalue() - cls.SerializePartialToString = SerializePartialToString - - def InternalSerialize(self, write_bytes, deterministic=None): - if deterministic is None: - deterministic = ( - api_implementation.IsPythonDefaultSerializationDeterministic()) - else: - deterministic = bool(deterministic) - - descriptor = self.DESCRIPTOR - if descriptor.GetOptions().map_entry: - # Fields of map entry should always be serialized. - descriptor.fields_by_name['key']._encoder( - write_bytes, self.key, deterministic) - descriptor.fields_by_name['value']._encoder( - write_bytes, self.value, deterministic) - else: - for field_descriptor, field_value in self.ListFields(): - field_descriptor._encoder(write_bytes, field_value, deterministic) - for tag_bytes, value_bytes in self._unknown_fields: - write_bytes(tag_bytes) - write_bytes(value_bytes) - cls._InternalSerialize = InternalSerialize - - -def _AddMergeFromStringMethod(message_descriptor, cls): - """Helper for _AddMessageMethods().""" - def MergeFromString(self, serialized): - serialized = memoryview(serialized) - length = len(serialized) - try: - if self._InternalParse(serialized, 0, length) != length: - # The only reason _InternalParse would return early is if it - # encountered an end-group tag. - raise message_mod.DecodeError('Unexpected end-group tag.') - except (IndexError, TypeError): - # Now ord(buf[p:p+1]) == ord('') gets TypeError. - raise message_mod.DecodeError('Truncated message.') - except struct.error as e: - raise message_mod.DecodeError(e) - return length # Return this for legacy reasons. - cls.MergeFromString = MergeFromString - - local_ReadTag = decoder.ReadTag - local_SkipField = decoder.SkipField - decoders_by_tag = cls._decoders_by_tag - - def InternalParse(self, buffer, pos, end): - """Create a message from serialized bytes. - - Args: - self: Message, instance of the proto message object. - buffer: memoryview of the serialized data. - pos: int, position to start in the serialized data. - end: int, end position of the serialized data. - - Returns: - Message object. - """ - # Guard against internal misuse, since this function is called internally - # quite extensively, and its easy to accidentally pass bytes. - assert isinstance(buffer, memoryview) - self._Modified() - field_dict = self._fields - # pylint: disable=protected-access - unknown_field_set = self._unknown_field_set - while pos != end: - (tag_bytes, new_pos) = local_ReadTag(buffer, pos) - field_decoder, field_desc = decoders_by_tag.get(tag_bytes, (None, None)) - if field_decoder is None: - if not self._unknown_fields: # pylint: disable=protected-access - self._unknown_fields = [] # pylint: disable=protected-access - if unknown_field_set is None: - # pylint: disable=protected-access - self._unknown_field_set = containers.UnknownFieldSet() - # pylint: disable=protected-access - unknown_field_set = self._unknown_field_set - # pylint: disable=protected-access - (tag, _) = decoder._DecodeVarint(tag_bytes, 0) - field_number, wire_type = wire_format.UnpackTag(tag) - if field_number == 0: - raise message_mod.DecodeError('Field number 0 is illegal.') - # TODO(jieluo): remove old_pos. - old_pos = new_pos - (data, new_pos) = decoder._DecodeUnknownField( - buffer, new_pos, wire_type) # pylint: disable=protected-access - if new_pos == -1: - return pos - # pylint: disable=protected-access - unknown_field_set._add(field_number, wire_type, data) - # TODO(jieluo): remove _unknown_fields. - new_pos = local_SkipField(buffer, old_pos, end, tag_bytes) - if new_pos == -1: - return pos - self._unknown_fields.append( - (tag_bytes, buffer[old_pos:new_pos].tobytes())) - pos = new_pos - else: - pos = field_decoder(buffer, new_pos, end, self, field_dict) - if field_desc: - self._UpdateOneofState(field_desc) - return pos - cls._InternalParse = InternalParse - - -def _AddIsInitializedMethod(message_descriptor, cls): - """Adds the IsInitialized and FindInitializationError methods to the - protocol message class.""" - - required_fields = [field for field in message_descriptor.fields - if field.label == _FieldDescriptor.LABEL_REQUIRED] - - def IsInitialized(self, errors=None): - """Checks if all required fields of a message are set. - - Args: - errors: A list which, if provided, will be populated with the field - paths of all missing required fields. - - Returns: - True iff the specified message has all required fields set. - """ - - # Performance is critical so we avoid HasField() and ListFields(). - - for field in required_fields: - if (field not in self._fields or - (field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE and - not self._fields[field]._is_present_in_parent)): - if errors is not None: - errors.extend(self.FindInitializationErrors()) - return False - - for field, value in list(self._fields.items()): # dict can change size! - if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - if field.label == _FieldDescriptor.LABEL_REPEATED: - if (field.message_type.has_options and - field.message_type.GetOptions().map_entry): - continue - for element in value: - if not element.IsInitialized(): - if errors is not None: - errors.extend(self.FindInitializationErrors()) - return False - elif value._is_present_in_parent and not value.IsInitialized(): - if errors is not None: - errors.extend(self.FindInitializationErrors()) - return False - - return True - - cls.IsInitialized = IsInitialized - - def FindInitializationErrors(self): - """Finds required fields which are not initialized. - - Returns: - A list of strings. Each string is a path to an uninitialized field from - the top-level message, e.g. "foo.bar[5].baz". - """ - - errors = [] # simplify things - - for field in required_fields: - if not self.HasField(field.name): - errors.append(field.name) - - for field, value in self.ListFields(): - if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - if field.is_extension: - name = '(%s)' % field.full_name - else: - name = field.name - - if _IsMapField(field): - if _IsMessageMapField(field): - for key in value: - element = value[key] - prefix = '%s[%s].' % (name, key) - sub_errors = element.FindInitializationErrors() - errors += [prefix + error for error in sub_errors] - else: - # ScalarMaps can't have any initialization errors. - pass - elif field.label == _FieldDescriptor.LABEL_REPEATED: - for i in range(len(value)): - element = value[i] - prefix = '%s[%d].' % (name, i) - sub_errors = element.FindInitializationErrors() - errors += [prefix + error for error in sub_errors] - else: - prefix = name + '.' - sub_errors = value.FindInitializationErrors() - errors += [prefix + error for error in sub_errors] - - return errors - - cls.FindInitializationErrors = FindInitializationErrors - - -def _FullyQualifiedClassName(klass): - module = klass.__module__ - name = getattr(klass, '__qualname__', klass.__name__) - if module in (None, 'builtins', '__builtin__'): - return name - return module + '.' + name - - -def _AddMergeFromMethod(cls): - LABEL_REPEATED = _FieldDescriptor.LABEL_REPEATED - CPPTYPE_MESSAGE = _FieldDescriptor.CPPTYPE_MESSAGE - - def MergeFrom(self, msg): - if not isinstance(msg, cls): - raise TypeError( - 'Parameter to MergeFrom() must be instance of same class: ' - 'expected %s got %s.' % (_FullyQualifiedClassName(cls), - _FullyQualifiedClassName(msg.__class__))) - - assert msg is not self - self._Modified() - - fields = self._fields - - for field, value in msg._fields.items(): - if field.label == LABEL_REPEATED: - field_value = fields.get(field) - if field_value is None: - # Construct a new object to represent this field. - field_value = field._default_constructor(self) - fields[field] = field_value - field_value.MergeFrom(value) - elif field.cpp_type == CPPTYPE_MESSAGE: - if value._is_present_in_parent: - field_value = fields.get(field) - if field_value is None: - # Construct a new object to represent this field. - field_value = field._default_constructor(self) - fields[field] = field_value - field_value.MergeFrom(value) - else: - self._fields[field] = value - if field.containing_oneof: - self._UpdateOneofState(field) - - if msg._unknown_fields: - if not self._unknown_fields: - self._unknown_fields = [] - self._unknown_fields.extend(msg._unknown_fields) - # pylint: disable=protected-access - if self._unknown_field_set is None: - self._unknown_field_set = containers.UnknownFieldSet() - self._unknown_field_set._extend(msg._unknown_field_set) - - cls.MergeFrom = MergeFrom - - -def _AddWhichOneofMethod(message_descriptor, cls): - def WhichOneof(self, oneof_name): - """Returns the name of the currently set field inside a oneof, or None.""" - try: - field = message_descriptor.oneofs_by_name[oneof_name] - except KeyError: - raise ValueError( - 'Protocol message has no oneof "%s" field.' % oneof_name) - - nested_field = self._oneofs.get(field, None) - if nested_field is not None and self.HasField(nested_field.name): - return nested_field.name - else: - return None - - cls.WhichOneof = WhichOneof - - -def _Clear(self): - # Clear fields. - self._fields = {} - self._unknown_fields = () - # pylint: disable=protected-access - if self._unknown_field_set is not None: - self._unknown_field_set._clear() - self._unknown_field_set = None - - self._oneofs = {} - self._Modified() - - -def _UnknownFields(self): - if self._unknown_field_set is None: # pylint: disable=protected-access - # pylint: disable=protected-access - self._unknown_field_set = containers.UnknownFieldSet() - return self._unknown_field_set # pylint: disable=protected-access - - -def _DiscardUnknownFields(self): - self._unknown_fields = [] - self._unknown_field_set = None # pylint: disable=protected-access - for field, value in self.ListFields(): - if field.cpp_type == _FieldDescriptor.CPPTYPE_MESSAGE: - if _IsMapField(field): - if _IsMessageMapField(field): - for key in value: - value[key].DiscardUnknownFields() - elif field.label == _FieldDescriptor.LABEL_REPEATED: - for sub_message in value: - sub_message.DiscardUnknownFields() - else: - value.DiscardUnknownFields() - - -def _SetListener(self, listener): - if listener is None: - self._listener = message_listener_mod.NullMessageListener() - else: - self._listener = listener - - -def _AddMessageMethods(message_descriptor, cls): - """Adds implementations of all Message methods to cls.""" - _AddListFieldsMethod(message_descriptor, cls) - _AddHasFieldMethod(message_descriptor, cls) - _AddClearFieldMethod(message_descriptor, cls) - if message_descriptor.is_extendable: - _AddClearExtensionMethod(cls) - _AddHasExtensionMethod(cls) - _AddEqualsMethod(message_descriptor, cls) - _AddStrMethod(message_descriptor, cls) - _AddReprMethod(message_descriptor, cls) - _AddUnicodeMethod(message_descriptor, cls) - _AddByteSizeMethod(message_descriptor, cls) - _AddSerializeToStringMethod(message_descriptor, cls) - _AddSerializePartialToStringMethod(message_descriptor, cls) - _AddMergeFromStringMethod(message_descriptor, cls) - _AddIsInitializedMethod(message_descriptor, cls) - _AddMergeFromMethod(cls) - _AddWhichOneofMethod(message_descriptor, cls) - # Adds methods which do not depend on cls. - cls.Clear = _Clear - cls.UnknownFields = _UnknownFields - cls.DiscardUnknownFields = _DiscardUnknownFields - cls._SetListener = _SetListener - - -def _AddPrivateHelperMethods(message_descriptor, cls): - """Adds implementation of private helper methods to cls.""" - - def Modified(self): - """Sets the _cached_byte_size_dirty bit to true, - and propagates this to our listener iff this was a state change. - """ - - # Note: Some callers check _cached_byte_size_dirty before calling - # _Modified() as an extra optimization. So, if this method is ever - # changed such that it does stuff even when _cached_byte_size_dirty is - # already true, the callers need to be updated. - if not self._cached_byte_size_dirty: - self._cached_byte_size_dirty = True - self._listener_for_children.dirty = True - self._is_present_in_parent = True - self._listener.Modified() - - def _UpdateOneofState(self, field): - """Sets field as the active field in its containing oneof. - - Will also delete currently active field in the oneof, if it is different - from the argument. Does not mark the message as modified. - """ - other_field = self._oneofs.setdefault(field.containing_oneof, field) - if other_field is not field: - del self._fields[other_field] - self._oneofs[field.containing_oneof] = field - - cls._Modified = Modified - cls.SetInParent = Modified - cls._UpdateOneofState = _UpdateOneofState - - -class _Listener(object): - - """MessageListener implementation that a parent message registers with its - child message. - - In order to support semantics like: - - foo.bar.baz.qux = 23 - assert foo.HasField('bar') - - ...child objects must have back references to their parents. - This helper class is at the heart of this support. - """ - - def __init__(self, parent_message): - """Args: - parent_message: The message whose _Modified() method we should call when - we receive Modified() messages. - """ - # This listener establishes a back reference from a child (contained) object - # to its parent (containing) object. We make this a weak reference to avoid - # creating cyclic garbage when the client finishes with the 'parent' object - # in the tree. - if isinstance(parent_message, weakref.ProxyType): - self._parent_message_weakref = parent_message - else: - self._parent_message_weakref = weakref.proxy(parent_message) - - # As an optimization, we also indicate directly on the listener whether - # or not the parent message is dirty. This way we can avoid traversing - # up the tree in the common case. - self.dirty = False - - def Modified(self): - if self.dirty: - return - try: - # Propagate the signal to our parents iff this is the first field set. - self._parent_message_weakref._Modified() - except ReferenceError: - # We can get here if a client has kept a reference to a child object, - # and is now setting a field on it, but the child's parent has been - # garbage-collected. This is not an error. - pass - - -class _OneofListener(_Listener): - """Special listener implementation for setting composite oneof fields.""" - - def __init__(self, parent_message, field): - """Args: - parent_message: The message whose _Modified() method we should call when - we receive Modified() messages. - field: The descriptor of the field being set in the parent message. - """ - super(_OneofListener, self).__init__(parent_message) - self._field = field - - def Modified(self): - """Also updates the state of the containing oneof in the parent message.""" - try: - self._parent_message_weakref._UpdateOneofState(self._field) - super(_OneofListener, self).Modified() - except ReferenceError: - pass diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/type_checkers.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/type_checkers.py deleted file mode 100644 index a53e71fe8e..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/type_checkers.py +++ /dev/null @@ -1,435 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Provides type checking routines. - -This module defines type checking utilities in the forms of dictionaries: - -VALUE_CHECKERS: A dictionary of field types and a value validation object. -TYPE_TO_BYTE_SIZE_FN: A dictionary with field types and a size computing - function. -TYPE_TO_SERIALIZE_METHOD: A dictionary with field types and serialization - function. -FIELD_TYPE_TO_WIRE_TYPE: A dictionary with field typed and their - corresponding wire types. -TYPE_TO_DESERIALIZE_METHOD: A dictionary with field types and deserialization - function. -""" - -__author__ = 'robinson@google.com (Will Robinson)' - -import ctypes -import numbers - -from google.protobuf.internal import decoder -from google.protobuf.internal import encoder -from google.protobuf.internal import wire_format -from google.protobuf import descriptor - -_FieldDescriptor = descriptor.FieldDescriptor - - -def TruncateToFourByteFloat(original): - return ctypes.c_float(original).value - - -def ToShortestFloat(original): - """Returns the shortest float that has same value in wire.""" - # All 4 byte floats have between 6 and 9 significant digits, so we - # start with 6 as the lower bound. - # It has to be iterative because use '.9g' directly can not get rid - # of the noises for most values. For example if set a float_field=0.9 - # use '.9g' will print 0.899999976. - precision = 6 - rounded = float('{0:.{1}g}'.format(original, precision)) - while TruncateToFourByteFloat(rounded) != original: - precision += 1 - rounded = float('{0:.{1}g}'.format(original, precision)) - return rounded - - -def SupportsOpenEnums(field_descriptor): - return field_descriptor.containing_type.syntax == 'proto3' - - -def GetTypeChecker(field): - """Returns a type checker for a message field of the specified types. - - Args: - field: FieldDescriptor object for this field. - - Returns: - An instance of TypeChecker which can be used to verify the types - of values assigned to a field of the specified type. - """ - if (field.cpp_type == _FieldDescriptor.CPPTYPE_STRING and - field.type == _FieldDescriptor.TYPE_STRING): - return UnicodeValueChecker() - if field.cpp_type == _FieldDescriptor.CPPTYPE_ENUM: - if SupportsOpenEnums(field): - # When open enums are supported, any int32 can be assigned. - return _VALUE_CHECKERS[_FieldDescriptor.CPPTYPE_INT32] - else: - return EnumValueChecker(field.enum_type) - return _VALUE_CHECKERS[field.cpp_type] - - -# None of the typecheckers below make any attempt to guard against people -# subclassing builtin types and doing weird things. We're not trying to -# protect against malicious clients here, just people accidentally shooting -# themselves in the foot in obvious ways. -class TypeChecker(object): - - """Type checker used to catch type errors as early as possible - when the client is setting scalar fields in protocol messages. - """ - - def __init__(self, *acceptable_types): - self._acceptable_types = acceptable_types - - def CheckValue(self, proposed_value): - """Type check the provided value and return it. - - The returned value might have been normalized to another type. - """ - if not isinstance(proposed_value, self._acceptable_types): - message = ('%.1024r has type %s, but expected one of: %s' % - (proposed_value, type(proposed_value), self._acceptable_types)) - raise TypeError(message) - return proposed_value - - -class TypeCheckerWithDefault(TypeChecker): - - def __init__(self, default_value, *acceptable_types): - TypeChecker.__init__(self, *acceptable_types) - self._default_value = default_value - - def DefaultValue(self): - return self._default_value - - -class BoolValueChecker(object): - """Type checker used for bool fields.""" - - def CheckValue(self, proposed_value): - if not hasattr(proposed_value, '__index__') or ( - type(proposed_value).__module__ == 'numpy' and - type(proposed_value).__name__ == 'ndarray'): - message = ('%.1024r has type %s, but expected one of: %s' % - (proposed_value, type(proposed_value), (bool, int))) - raise TypeError(message) - return bool(proposed_value) - - def DefaultValue(self): - return False - - -# IntValueChecker and its subclasses perform integer type-checks -# and bounds-checks. -class IntValueChecker(object): - - """Checker used for integer fields. Performs type-check and range check.""" - - def CheckValue(self, proposed_value): - if not hasattr(proposed_value, '__index__') or ( - type(proposed_value).__module__ == 'numpy' and - type(proposed_value).__name__ == 'ndarray'): - message = ('%.1024r has type %s, but expected one of: %s' % - (proposed_value, type(proposed_value), (int,))) - raise TypeError(message) - - if not self._MIN <= int(proposed_value) <= self._MAX: - raise ValueError('Value out of range: %d' % proposed_value) - # We force all values to int to make alternate implementations where the - # distinction is more significant (e.g. the C++ implementation) simpler. - proposed_value = int(proposed_value) - return proposed_value - - def DefaultValue(self): - return 0 - - -class EnumValueChecker(object): - - """Checker used for enum fields. Performs type-check and range check.""" - - def __init__(self, enum_type): - self._enum_type = enum_type - - def CheckValue(self, proposed_value): - if not isinstance(proposed_value, numbers.Integral): - message = ('%.1024r has type %s, but expected one of: %s' % - (proposed_value, type(proposed_value), (int,))) - raise TypeError(message) - if int(proposed_value) not in self._enum_type.values_by_number: - raise ValueError('Unknown enum value: %d' % proposed_value) - return proposed_value - - def DefaultValue(self): - return self._enum_type.values[0].number - - -class UnicodeValueChecker(object): - - """Checker used for string fields. - - Always returns a unicode value, even if the input is of type str. - """ - - def CheckValue(self, proposed_value): - if not isinstance(proposed_value, (bytes, str)): - message = ('%.1024r has type %s, but expected one of: %s' % - (proposed_value, type(proposed_value), (bytes, str))) - raise TypeError(message) - - # If the value is of type 'bytes' make sure that it is valid UTF-8 data. - if isinstance(proposed_value, bytes): - try: - proposed_value = proposed_value.decode('utf-8') - except UnicodeDecodeError: - raise ValueError('%.1024r has type bytes, but isn\'t valid UTF-8 ' - 'encoding. Non-UTF-8 strings must be converted to ' - 'unicode objects before being added.' % - (proposed_value)) - else: - try: - proposed_value.encode('utf8') - except UnicodeEncodeError: - raise ValueError('%.1024r isn\'t a valid unicode string and ' - 'can\'t be encoded in UTF-8.'% - (proposed_value)) - - return proposed_value - - def DefaultValue(self): - return u"" - - -class Int32ValueChecker(IntValueChecker): - # We're sure to use ints instead of longs here since comparison may be more - # efficient. - _MIN = -2147483648 - _MAX = 2147483647 - - -class Uint32ValueChecker(IntValueChecker): - _MIN = 0 - _MAX = (1 << 32) - 1 - - -class Int64ValueChecker(IntValueChecker): - _MIN = -(1 << 63) - _MAX = (1 << 63) - 1 - - -class Uint64ValueChecker(IntValueChecker): - _MIN = 0 - _MAX = (1 << 64) - 1 - - -# The max 4 bytes float is about 3.4028234663852886e+38 -_FLOAT_MAX = float.fromhex('0x1.fffffep+127') -_FLOAT_MIN = -_FLOAT_MAX -_INF = float('inf') -_NEG_INF = float('-inf') - - -class DoubleValueChecker(object): - """Checker used for double fields. - - Performs type-check and range check. - """ - - def CheckValue(self, proposed_value): - """Check and convert proposed_value to float.""" - if (not hasattr(proposed_value, '__float__') and - not hasattr(proposed_value, '__index__')) or ( - type(proposed_value).__module__ == 'numpy' and - type(proposed_value).__name__ == 'ndarray'): - message = ('%.1024r has type %s, but expected one of: int, float' % - (proposed_value, type(proposed_value))) - raise TypeError(message) - return float(proposed_value) - - def DefaultValue(self): - return 0.0 - - -class FloatValueChecker(DoubleValueChecker): - """Checker used for float fields. - - Performs type-check and range check. - - Values exceeding a 32-bit float will be converted to inf/-inf. - """ - - def CheckValue(self, proposed_value): - """Check and convert proposed_value to float.""" - converted_value = super().CheckValue(proposed_value) - # This inf rounding matches the C++ proto SafeDoubleToFloat logic. - if converted_value > _FLOAT_MAX: - return _INF - if converted_value < _FLOAT_MIN: - return _NEG_INF - - return TruncateToFourByteFloat(converted_value) - -# Type-checkers for all scalar CPPTYPEs. -_VALUE_CHECKERS = { - _FieldDescriptor.CPPTYPE_INT32: Int32ValueChecker(), - _FieldDescriptor.CPPTYPE_INT64: Int64ValueChecker(), - _FieldDescriptor.CPPTYPE_UINT32: Uint32ValueChecker(), - _FieldDescriptor.CPPTYPE_UINT64: Uint64ValueChecker(), - _FieldDescriptor.CPPTYPE_DOUBLE: DoubleValueChecker(), - _FieldDescriptor.CPPTYPE_FLOAT: FloatValueChecker(), - _FieldDescriptor.CPPTYPE_BOOL: BoolValueChecker(), - _FieldDescriptor.CPPTYPE_STRING: TypeCheckerWithDefault(b'', bytes), -} - - -# Map from field type to a function F, such that F(field_num, value) -# gives the total byte size for a value of the given type. This -# byte size includes tag information and any other additional space -# associated with serializing "value". -TYPE_TO_BYTE_SIZE_FN = { - _FieldDescriptor.TYPE_DOUBLE: wire_format.DoubleByteSize, - _FieldDescriptor.TYPE_FLOAT: wire_format.FloatByteSize, - _FieldDescriptor.TYPE_INT64: wire_format.Int64ByteSize, - _FieldDescriptor.TYPE_UINT64: wire_format.UInt64ByteSize, - _FieldDescriptor.TYPE_INT32: wire_format.Int32ByteSize, - _FieldDescriptor.TYPE_FIXED64: wire_format.Fixed64ByteSize, - _FieldDescriptor.TYPE_FIXED32: wire_format.Fixed32ByteSize, - _FieldDescriptor.TYPE_BOOL: wire_format.BoolByteSize, - _FieldDescriptor.TYPE_STRING: wire_format.StringByteSize, - _FieldDescriptor.TYPE_GROUP: wire_format.GroupByteSize, - _FieldDescriptor.TYPE_MESSAGE: wire_format.MessageByteSize, - _FieldDescriptor.TYPE_BYTES: wire_format.BytesByteSize, - _FieldDescriptor.TYPE_UINT32: wire_format.UInt32ByteSize, - _FieldDescriptor.TYPE_ENUM: wire_format.EnumByteSize, - _FieldDescriptor.TYPE_SFIXED32: wire_format.SFixed32ByteSize, - _FieldDescriptor.TYPE_SFIXED64: wire_format.SFixed64ByteSize, - _FieldDescriptor.TYPE_SINT32: wire_format.SInt32ByteSize, - _FieldDescriptor.TYPE_SINT64: wire_format.SInt64ByteSize - } - - -# Maps from field types to encoder constructors. -TYPE_TO_ENCODER = { - _FieldDescriptor.TYPE_DOUBLE: encoder.DoubleEncoder, - _FieldDescriptor.TYPE_FLOAT: encoder.FloatEncoder, - _FieldDescriptor.TYPE_INT64: encoder.Int64Encoder, - _FieldDescriptor.TYPE_UINT64: encoder.UInt64Encoder, - _FieldDescriptor.TYPE_INT32: encoder.Int32Encoder, - _FieldDescriptor.TYPE_FIXED64: encoder.Fixed64Encoder, - _FieldDescriptor.TYPE_FIXED32: encoder.Fixed32Encoder, - _FieldDescriptor.TYPE_BOOL: encoder.BoolEncoder, - _FieldDescriptor.TYPE_STRING: encoder.StringEncoder, - _FieldDescriptor.TYPE_GROUP: encoder.GroupEncoder, - _FieldDescriptor.TYPE_MESSAGE: encoder.MessageEncoder, - _FieldDescriptor.TYPE_BYTES: encoder.BytesEncoder, - _FieldDescriptor.TYPE_UINT32: encoder.UInt32Encoder, - _FieldDescriptor.TYPE_ENUM: encoder.EnumEncoder, - _FieldDescriptor.TYPE_SFIXED32: encoder.SFixed32Encoder, - _FieldDescriptor.TYPE_SFIXED64: encoder.SFixed64Encoder, - _FieldDescriptor.TYPE_SINT32: encoder.SInt32Encoder, - _FieldDescriptor.TYPE_SINT64: encoder.SInt64Encoder, - } - - -# Maps from field types to sizer constructors. -TYPE_TO_SIZER = { - _FieldDescriptor.TYPE_DOUBLE: encoder.DoubleSizer, - _FieldDescriptor.TYPE_FLOAT: encoder.FloatSizer, - _FieldDescriptor.TYPE_INT64: encoder.Int64Sizer, - _FieldDescriptor.TYPE_UINT64: encoder.UInt64Sizer, - _FieldDescriptor.TYPE_INT32: encoder.Int32Sizer, - _FieldDescriptor.TYPE_FIXED64: encoder.Fixed64Sizer, - _FieldDescriptor.TYPE_FIXED32: encoder.Fixed32Sizer, - _FieldDescriptor.TYPE_BOOL: encoder.BoolSizer, - _FieldDescriptor.TYPE_STRING: encoder.StringSizer, - _FieldDescriptor.TYPE_GROUP: encoder.GroupSizer, - _FieldDescriptor.TYPE_MESSAGE: encoder.MessageSizer, - _FieldDescriptor.TYPE_BYTES: encoder.BytesSizer, - _FieldDescriptor.TYPE_UINT32: encoder.UInt32Sizer, - _FieldDescriptor.TYPE_ENUM: encoder.EnumSizer, - _FieldDescriptor.TYPE_SFIXED32: encoder.SFixed32Sizer, - _FieldDescriptor.TYPE_SFIXED64: encoder.SFixed64Sizer, - _FieldDescriptor.TYPE_SINT32: encoder.SInt32Sizer, - _FieldDescriptor.TYPE_SINT64: encoder.SInt64Sizer, - } - - -# Maps from field type to a decoder constructor. -TYPE_TO_DECODER = { - _FieldDescriptor.TYPE_DOUBLE: decoder.DoubleDecoder, - _FieldDescriptor.TYPE_FLOAT: decoder.FloatDecoder, - _FieldDescriptor.TYPE_INT64: decoder.Int64Decoder, - _FieldDescriptor.TYPE_UINT64: decoder.UInt64Decoder, - _FieldDescriptor.TYPE_INT32: decoder.Int32Decoder, - _FieldDescriptor.TYPE_FIXED64: decoder.Fixed64Decoder, - _FieldDescriptor.TYPE_FIXED32: decoder.Fixed32Decoder, - _FieldDescriptor.TYPE_BOOL: decoder.BoolDecoder, - _FieldDescriptor.TYPE_STRING: decoder.StringDecoder, - _FieldDescriptor.TYPE_GROUP: decoder.GroupDecoder, - _FieldDescriptor.TYPE_MESSAGE: decoder.MessageDecoder, - _FieldDescriptor.TYPE_BYTES: decoder.BytesDecoder, - _FieldDescriptor.TYPE_UINT32: decoder.UInt32Decoder, - _FieldDescriptor.TYPE_ENUM: decoder.EnumDecoder, - _FieldDescriptor.TYPE_SFIXED32: decoder.SFixed32Decoder, - _FieldDescriptor.TYPE_SFIXED64: decoder.SFixed64Decoder, - _FieldDescriptor.TYPE_SINT32: decoder.SInt32Decoder, - _FieldDescriptor.TYPE_SINT64: decoder.SInt64Decoder, - } - -# Maps from field type to expected wiretype. -FIELD_TYPE_TO_WIRE_TYPE = { - _FieldDescriptor.TYPE_DOUBLE: wire_format.WIRETYPE_FIXED64, - _FieldDescriptor.TYPE_FLOAT: wire_format.WIRETYPE_FIXED32, - _FieldDescriptor.TYPE_INT64: wire_format.WIRETYPE_VARINT, - _FieldDescriptor.TYPE_UINT64: wire_format.WIRETYPE_VARINT, - _FieldDescriptor.TYPE_INT32: wire_format.WIRETYPE_VARINT, - _FieldDescriptor.TYPE_FIXED64: wire_format.WIRETYPE_FIXED64, - _FieldDescriptor.TYPE_FIXED32: wire_format.WIRETYPE_FIXED32, - _FieldDescriptor.TYPE_BOOL: wire_format.WIRETYPE_VARINT, - _FieldDescriptor.TYPE_STRING: - wire_format.WIRETYPE_LENGTH_DELIMITED, - _FieldDescriptor.TYPE_GROUP: wire_format.WIRETYPE_START_GROUP, - _FieldDescriptor.TYPE_MESSAGE: - wire_format.WIRETYPE_LENGTH_DELIMITED, - _FieldDescriptor.TYPE_BYTES: - wire_format.WIRETYPE_LENGTH_DELIMITED, - _FieldDescriptor.TYPE_UINT32: wire_format.WIRETYPE_VARINT, - _FieldDescriptor.TYPE_ENUM: wire_format.WIRETYPE_VARINT, - _FieldDescriptor.TYPE_SFIXED32: wire_format.WIRETYPE_FIXED32, - _FieldDescriptor.TYPE_SFIXED64: wire_format.WIRETYPE_FIXED64, - _FieldDescriptor.TYPE_SINT32: wire_format.WIRETYPE_VARINT, - _FieldDescriptor.TYPE_SINT64: wire_format.WIRETYPE_VARINT, - } diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/well_known_types.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/well_known_types.py deleted file mode 100644 index b581ab750a..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/well_known_types.py +++ /dev/null @@ -1,878 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Contains well known classes. - -This files defines well known classes which need extra maintenance including: - - Any - - Duration - - FieldMask - - Struct - - Timestamp -""" - -__author__ = 'jieluo@google.com (Jie Luo)' - -import calendar -import collections.abc -import datetime - -from google.protobuf.descriptor import FieldDescriptor - -_TIMESTAMPFOMAT = '%Y-%m-%dT%H:%M:%S' -_NANOS_PER_SECOND = 1000000000 -_NANOS_PER_MILLISECOND = 1000000 -_NANOS_PER_MICROSECOND = 1000 -_MILLIS_PER_SECOND = 1000 -_MICROS_PER_SECOND = 1000000 -_SECONDS_PER_DAY = 24 * 3600 -_DURATION_SECONDS_MAX = 315576000000 - - -class Any(object): - """Class for Any Message type.""" - - __slots__ = () - - def Pack(self, msg, type_url_prefix='type.googleapis.com/', - deterministic=None): - """Packs the specified message into current Any message.""" - if len(type_url_prefix) < 1 or type_url_prefix[-1] != '/': - self.type_url = '%s/%s' % (type_url_prefix, msg.DESCRIPTOR.full_name) - else: - self.type_url = '%s%s' % (type_url_prefix, msg.DESCRIPTOR.full_name) - self.value = msg.SerializeToString(deterministic=deterministic) - - def Unpack(self, msg): - """Unpacks the current Any message into specified message.""" - descriptor = msg.DESCRIPTOR - if not self.Is(descriptor): - return False - msg.ParseFromString(self.value) - return True - - def TypeName(self): - """Returns the protobuf type name of the inner message.""" - # Only last part is to be used: b/25630112 - return self.type_url.split('/')[-1] - - def Is(self, descriptor): - """Checks if this Any represents the given protobuf type.""" - return '/' in self.type_url and self.TypeName() == descriptor.full_name - - -_EPOCH_DATETIME_NAIVE = datetime.datetime.utcfromtimestamp(0) -_EPOCH_DATETIME_AWARE = datetime.datetime.fromtimestamp( - 0, tz=datetime.timezone.utc) - - -class Timestamp(object): - """Class for Timestamp message type.""" - - __slots__ = () - - def ToJsonString(self): - """Converts Timestamp to RFC 3339 date string format. - - Returns: - A string converted from timestamp. The string is always Z-normalized - and uses 3, 6 or 9 fractional digits as required to represent the - exact time. Example of the return format: '1972-01-01T10:00:20.021Z' - """ - nanos = self.nanos % _NANOS_PER_SECOND - total_sec = self.seconds + (self.nanos - nanos) // _NANOS_PER_SECOND - seconds = total_sec % _SECONDS_PER_DAY - days = (total_sec - seconds) // _SECONDS_PER_DAY - dt = datetime.datetime(1970, 1, 1) + datetime.timedelta(days, seconds) - - result = dt.isoformat() - if (nanos % 1e9) == 0: - # If there are 0 fractional digits, the fractional - # point '.' should be omitted when serializing. - return result + 'Z' - if (nanos % 1e6) == 0: - # Serialize 3 fractional digits. - return result + '.%03dZ' % (nanos / 1e6) - if (nanos % 1e3) == 0: - # Serialize 6 fractional digits. - return result + '.%06dZ' % (nanos / 1e3) - # Serialize 9 fractional digits. - return result + '.%09dZ' % nanos - - def FromJsonString(self, value): - """Parse a RFC 3339 date string format to Timestamp. - - Args: - value: A date string. Any fractional digits (or none) and any offset are - accepted as long as they fit into nano-seconds precision. - Example of accepted format: '1972-01-01T10:00:20.021-05:00' - - Raises: - ValueError: On parsing problems. - """ - if not isinstance(value, str): - raise ValueError('Timestamp JSON value not a string: {!r}'.format(value)) - timezone_offset = value.find('Z') - if timezone_offset == -1: - timezone_offset = value.find('+') - if timezone_offset == -1: - timezone_offset = value.rfind('-') - if timezone_offset == -1: - raise ValueError( - 'Failed to parse timestamp: missing valid timezone offset.') - time_value = value[0:timezone_offset] - # Parse datetime and nanos. - point_position = time_value.find('.') - if point_position == -1: - second_value = time_value - nano_value = '' - else: - second_value = time_value[:point_position] - nano_value = time_value[point_position + 1:] - if 't' in second_value: - raise ValueError( - 'time data \'{0}\' does not match format \'%Y-%m-%dT%H:%M:%S\', ' - 'lowercase \'t\' is not accepted'.format(second_value)) - date_object = datetime.datetime.strptime(second_value, _TIMESTAMPFOMAT) - td = date_object - datetime.datetime(1970, 1, 1) - seconds = td.seconds + td.days * _SECONDS_PER_DAY - if len(nano_value) > 9: - raise ValueError( - 'Failed to parse Timestamp: nanos {0} more than ' - '9 fractional digits.'.format(nano_value)) - if nano_value: - nanos = round(float('0.' + nano_value) * 1e9) - else: - nanos = 0 - # Parse timezone offsets. - if value[timezone_offset] == 'Z': - if len(value) != timezone_offset + 1: - raise ValueError('Failed to parse timestamp: invalid trailing' - ' data {0}.'.format(value)) - else: - timezone = value[timezone_offset:] - pos = timezone.find(':') - if pos == -1: - raise ValueError( - 'Invalid timezone offset value: {0}.'.format(timezone)) - if timezone[0] == '+': - seconds -= (int(timezone[1:pos])*60+int(timezone[pos+1:]))*60 - else: - seconds += (int(timezone[1:pos])*60+int(timezone[pos+1:]))*60 - # Set seconds and nanos - self.seconds = int(seconds) - self.nanos = int(nanos) - - def GetCurrentTime(self): - """Get the current UTC into Timestamp.""" - self.FromDatetime(datetime.datetime.utcnow()) - - def ToNanoseconds(self): - """Converts Timestamp to nanoseconds since epoch.""" - return self.seconds * _NANOS_PER_SECOND + self.nanos - - def ToMicroseconds(self): - """Converts Timestamp to microseconds since epoch.""" - return (self.seconds * _MICROS_PER_SECOND + - self.nanos // _NANOS_PER_MICROSECOND) - - def ToMilliseconds(self): - """Converts Timestamp to milliseconds since epoch.""" - return (self.seconds * _MILLIS_PER_SECOND + - self.nanos // _NANOS_PER_MILLISECOND) - - def ToSeconds(self): - """Converts Timestamp to seconds since epoch.""" - return self.seconds - - def FromNanoseconds(self, nanos): - """Converts nanoseconds since epoch to Timestamp.""" - self.seconds = nanos // _NANOS_PER_SECOND - self.nanos = nanos % _NANOS_PER_SECOND - - def FromMicroseconds(self, micros): - """Converts microseconds since epoch to Timestamp.""" - self.seconds = micros // _MICROS_PER_SECOND - self.nanos = (micros % _MICROS_PER_SECOND) * _NANOS_PER_MICROSECOND - - def FromMilliseconds(self, millis): - """Converts milliseconds since epoch to Timestamp.""" - self.seconds = millis // _MILLIS_PER_SECOND - self.nanos = (millis % _MILLIS_PER_SECOND) * _NANOS_PER_MILLISECOND - - def FromSeconds(self, seconds): - """Converts seconds since epoch to Timestamp.""" - self.seconds = seconds - self.nanos = 0 - - def ToDatetime(self, tzinfo=None): - """Converts Timestamp to a datetime. - - Args: - tzinfo: A datetime.tzinfo subclass; defaults to None. - - Returns: - If tzinfo is None, returns a timezone-naive UTC datetime (with no timezone - information, i.e. not aware that it's UTC). - - Otherwise, returns a timezone-aware datetime in the input timezone. - """ - delta = datetime.timedelta( - seconds=self.seconds, - microseconds=_RoundTowardZero(self.nanos, _NANOS_PER_MICROSECOND)) - if tzinfo is None: - return _EPOCH_DATETIME_NAIVE + delta - else: - return _EPOCH_DATETIME_AWARE.astimezone(tzinfo) + delta - - def FromDatetime(self, dt): - """Converts datetime to Timestamp. - - Args: - dt: A datetime. If it's timezone-naive, it's assumed to be in UTC. - """ - # Using this guide: http://wiki.python.org/moin/WorkingWithTime - # And this conversion guide: http://docs.python.org/library/time.html - - # Turn the date parameter into a tuple (struct_time) that can then be - # manipulated into a long value of seconds. During the conversion from - # struct_time to long, the source date in UTC, and so it follows that the - # correct transformation is calendar.timegm() - self.seconds = calendar.timegm(dt.utctimetuple()) - self.nanos = dt.microsecond * _NANOS_PER_MICROSECOND - - -class Duration(object): - """Class for Duration message type.""" - - __slots__ = () - - def ToJsonString(self): - """Converts Duration to string format. - - Returns: - A string converted from self. The string format will contains - 3, 6, or 9 fractional digits depending on the precision required to - represent the exact Duration value. For example: "1s", "1.010s", - "1.000000100s", "-3.100s" - """ - _CheckDurationValid(self.seconds, self.nanos) - if self.seconds < 0 or self.nanos < 0: - result = '-' - seconds = - self.seconds + int((0 - self.nanos) // 1e9) - nanos = (0 - self.nanos) % 1e9 - else: - result = '' - seconds = self.seconds + int(self.nanos // 1e9) - nanos = self.nanos % 1e9 - result += '%d' % seconds - if (nanos % 1e9) == 0: - # If there are 0 fractional digits, the fractional - # point '.' should be omitted when serializing. - return result + 's' - if (nanos % 1e6) == 0: - # Serialize 3 fractional digits. - return result + '.%03ds' % (nanos / 1e6) - if (nanos % 1e3) == 0: - # Serialize 6 fractional digits. - return result + '.%06ds' % (nanos / 1e3) - # Serialize 9 fractional digits. - return result + '.%09ds' % nanos - - def FromJsonString(self, value): - """Converts a string to Duration. - - Args: - value: A string to be converted. The string must end with 's'. Any - fractional digits (or none) are accepted as long as they fit into - precision. For example: "1s", "1.01s", "1.0000001s", "-3.100s - - Raises: - ValueError: On parsing problems. - """ - if not isinstance(value, str): - raise ValueError('Duration JSON value not a string: {!r}'.format(value)) - if len(value) < 1 or value[-1] != 's': - raise ValueError( - 'Duration must end with letter "s": {0}.'.format(value)) - try: - pos = value.find('.') - if pos == -1: - seconds = int(value[:-1]) - nanos = 0 - else: - seconds = int(value[:pos]) - if value[0] == '-': - nanos = int(round(float('-0{0}'.format(value[pos: -1])) *1e9)) - else: - nanos = int(round(float('0{0}'.format(value[pos: -1])) *1e9)) - _CheckDurationValid(seconds, nanos) - self.seconds = seconds - self.nanos = nanos - except ValueError as e: - raise ValueError( - 'Couldn\'t parse duration: {0} : {1}.'.format(value, e)) - - def ToNanoseconds(self): - """Converts a Duration to nanoseconds.""" - return self.seconds * _NANOS_PER_SECOND + self.nanos - - def ToMicroseconds(self): - """Converts a Duration to microseconds.""" - micros = _RoundTowardZero(self.nanos, _NANOS_PER_MICROSECOND) - return self.seconds * _MICROS_PER_SECOND + micros - - def ToMilliseconds(self): - """Converts a Duration to milliseconds.""" - millis = _RoundTowardZero(self.nanos, _NANOS_PER_MILLISECOND) - return self.seconds * _MILLIS_PER_SECOND + millis - - def ToSeconds(self): - """Converts a Duration to seconds.""" - return self.seconds - - def FromNanoseconds(self, nanos): - """Converts nanoseconds to Duration.""" - self._NormalizeDuration(nanos // _NANOS_PER_SECOND, - nanos % _NANOS_PER_SECOND) - - def FromMicroseconds(self, micros): - """Converts microseconds to Duration.""" - self._NormalizeDuration( - micros // _MICROS_PER_SECOND, - (micros % _MICROS_PER_SECOND) * _NANOS_PER_MICROSECOND) - - def FromMilliseconds(self, millis): - """Converts milliseconds to Duration.""" - self._NormalizeDuration( - millis // _MILLIS_PER_SECOND, - (millis % _MILLIS_PER_SECOND) * _NANOS_PER_MILLISECOND) - - def FromSeconds(self, seconds): - """Converts seconds to Duration.""" - self.seconds = seconds - self.nanos = 0 - - def ToTimedelta(self): - """Converts Duration to timedelta.""" - return datetime.timedelta( - seconds=self.seconds, microseconds=_RoundTowardZero( - self.nanos, _NANOS_PER_MICROSECOND)) - - def FromTimedelta(self, td): - """Converts timedelta to Duration.""" - self._NormalizeDuration(td.seconds + td.days * _SECONDS_PER_DAY, - td.microseconds * _NANOS_PER_MICROSECOND) - - def _NormalizeDuration(self, seconds, nanos): - """Set Duration by seconds and nanos.""" - # Force nanos to be negative if the duration is negative. - if seconds < 0 and nanos > 0: - seconds += 1 - nanos -= _NANOS_PER_SECOND - self.seconds = seconds - self.nanos = nanos - - -def _CheckDurationValid(seconds, nanos): - if seconds < -_DURATION_SECONDS_MAX or seconds > _DURATION_SECONDS_MAX: - raise ValueError( - 'Duration is not valid: Seconds {0} must be in range ' - '[-315576000000, 315576000000].'.format(seconds)) - if nanos <= -_NANOS_PER_SECOND or nanos >= _NANOS_PER_SECOND: - raise ValueError( - 'Duration is not valid: Nanos {0} must be in range ' - '[-999999999, 999999999].'.format(nanos)) - if (nanos < 0 and seconds > 0) or (nanos > 0 and seconds < 0): - raise ValueError( - 'Duration is not valid: Sign mismatch.') - - -def _RoundTowardZero(value, divider): - """Truncates the remainder part after division.""" - # For some languages, the sign of the remainder is implementation - # dependent if any of the operands is negative. Here we enforce - # "rounded toward zero" semantics. For example, for (-5) / 2 an - # implementation may give -3 as the result with the remainder being - # 1. This function ensures we always return -2 (closer to zero). - result = value // divider - remainder = value % divider - if result < 0 and remainder > 0: - return result + 1 - else: - return result - - -class FieldMask(object): - """Class for FieldMask message type.""" - - __slots__ = () - - def ToJsonString(self): - """Converts FieldMask to string according to proto3 JSON spec.""" - camelcase_paths = [] - for path in self.paths: - camelcase_paths.append(_SnakeCaseToCamelCase(path)) - return ','.join(camelcase_paths) - - def FromJsonString(self, value): - """Converts string to FieldMask according to proto3 JSON spec.""" - if not isinstance(value, str): - raise ValueError('FieldMask JSON value not a string: {!r}'.format(value)) - self.Clear() - if value: - for path in value.split(','): - self.paths.append(_CamelCaseToSnakeCase(path)) - - def IsValidForDescriptor(self, message_descriptor): - """Checks whether the FieldMask is valid for Message Descriptor.""" - for path in self.paths: - if not _IsValidPath(message_descriptor, path): - return False - return True - - def AllFieldsFromDescriptor(self, message_descriptor): - """Gets all direct fields of Message Descriptor to FieldMask.""" - self.Clear() - for field in message_descriptor.fields: - self.paths.append(field.name) - - def CanonicalFormFromMask(self, mask): - """Converts a FieldMask to the canonical form. - - Removes paths that are covered by another path. For example, - "foo.bar" is covered by "foo" and will be removed if "foo" - is also in the FieldMask. Then sorts all paths in alphabetical order. - - Args: - mask: The original FieldMask to be converted. - """ - tree = _FieldMaskTree(mask) - tree.ToFieldMask(self) - - def Union(self, mask1, mask2): - """Merges mask1 and mask2 into this FieldMask.""" - _CheckFieldMaskMessage(mask1) - _CheckFieldMaskMessage(mask2) - tree = _FieldMaskTree(mask1) - tree.MergeFromFieldMask(mask2) - tree.ToFieldMask(self) - - def Intersect(self, mask1, mask2): - """Intersects mask1 and mask2 into this FieldMask.""" - _CheckFieldMaskMessage(mask1) - _CheckFieldMaskMessage(mask2) - tree = _FieldMaskTree(mask1) - intersection = _FieldMaskTree() - for path in mask2.paths: - tree.IntersectPath(path, intersection) - intersection.ToFieldMask(self) - - def MergeMessage( - self, source, destination, - replace_message_field=False, replace_repeated_field=False): - """Merges fields specified in FieldMask from source to destination. - - Args: - source: Source message. - destination: The destination message to be merged into. - replace_message_field: Replace message field if True. Merge message - field if False. - replace_repeated_field: Replace repeated field if True. Append - elements of repeated field if False. - """ - tree = _FieldMaskTree(self) - tree.MergeMessage( - source, destination, replace_message_field, replace_repeated_field) - - -def _IsValidPath(message_descriptor, path): - """Checks whether the path is valid for Message Descriptor.""" - parts = path.split('.') - last = parts.pop() - for name in parts: - field = message_descriptor.fields_by_name.get(name) - if (field is None or - field.label == FieldDescriptor.LABEL_REPEATED or - field.type != FieldDescriptor.TYPE_MESSAGE): - return False - message_descriptor = field.message_type - return last in message_descriptor.fields_by_name - - -def _CheckFieldMaskMessage(message): - """Raises ValueError if message is not a FieldMask.""" - message_descriptor = message.DESCRIPTOR - if (message_descriptor.name != 'FieldMask' or - message_descriptor.file.name != 'google/protobuf/field_mask.proto'): - raise ValueError('Message {0} is not a FieldMask.'.format( - message_descriptor.full_name)) - - -def _SnakeCaseToCamelCase(path_name): - """Converts a path name from snake_case to camelCase.""" - result = [] - after_underscore = False - for c in path_name: - if c.isupper(): - raise ValueError( - 'Fail to print FieldMask to Json string: Path name ' - '{0} must not contain uppercase letters.'.format(path_name)) - if after_underscore: - if c.islower(): - result.append(c.upper()) - after_underscore = False - else: - raise ValueError( - 'Fail to print FieldMask to Json string: The ' - 'character after a "_" must be a lowercase letter ' - 'in path name {0}.'.format(path_name)) - elif c == '_': - after_underscore = True - else: - result += c - - if after_underscore: - raise ValueError('Fail to print FieldMask to Json string: Trailing "_" ' - 'in path name {0}.'.format(path_name)) - return ''.join(result) - - -def _CamelCaseToSnakeCase(path_name): - """Converts a field name from camelCase to snake_case.""" - result = [] - for c in path_name: - if c == '_': - raise ValueError('Fail to parse FieldMask: Path name ' - '{0} must not contain "_"s.'.format(path_name)) - if c.isupper(): - result += '_' - result += c.lower() - else: - result += c - return ''.join(result) - - -class _FieldMaskTree(object): - """Represents a FieldMask in a tree structure. - - For example, given a FieldMask "foo.bar,foo.baz,bar.baz", - the FieldMaskTree will be: - [_root] -+- foo -+- bar - | | - | +- baz - | - +- bar --- baz - In the tree, each leaf node represents a field path. - """ - - __slots__ = ('_root',) - - def __init__(self, field_mask=None): - """Initializes the tree by FieldMask.""" - self._root = {} - if field_mask: - self.MergeFromFieldMask(field_mask) - - def MergeFromFieldMask(self, field_mask): - """Merges a FieldMask to the tree.""" - for path in field_mask.paths: - self.AddPath(path) - - def AddPath(self, path): - """Adds a field path into the tree. - - If the field path to add is a sub-path of an existing field path - in the tree (i.e., a leaf node), it means the tree already matches - the given path so nothing will be added to the tree. If the path - matches an existing non-leaf node in the tree, that non-leaf node - will be turned into a leaf node with all its children removed because - the path matches all the node's children. Otherwise, a new path will - be added. - - Args: - path: The field path to add. - """ - node = self._root - for name in path.split('.'): - if name not in node: - node[name] = {} - elif not node[name]: - # Pre-existing empty node implies we already have this entire tree. - return - node = node[name] - # Remove any sub-trees we might have had. - node.clear() - - def ToFieldMask(self, field_mask): - """Converts the tree to a FieldMask.""" - field_mask.Clear() - _AddFieldPaths(self._root, '', field_mask) - - def IntersectPath(self, path, intersection): - """Calculates the intersection part of a field path with this tree. - - Args: - path: The field path to calculates. - intersection: The out tree to record the intersection part. - """ - node = self._root - for name in path.split('.'): - if name not in node: - return - elif not node[name]: - intersection.AddPath(path) - return - node = node[name] - intersection.AddLeafNodes(path, node) - - def AddLeafNodes(self, prefix, node): - """Adds leaf nodes begin with prefix to this tree.""" - if not node: - self.AddPath(prefix) - for name in node: - child_path = prefix + '.' + name - self.AddLeafNodes(child_path, node[name]) - - def MergeMessage( - self, source, destination, - replace_message, replace_repeated): - """Merge all fields specified by this tree from source to destination.""" - _MergeMessage( - self._root, source, destination, replace_message, replace_repeated) - - -def _StrConvert(value): - """Converts value to str if it is not.""" - # This file is imported by c extension and some methods like ClearField - # requires string for the field name. py2/py3 has different text - # type and may use unicode. - if not isinstance(value, str): - return value.encode('utf-8') - return value - - -def _MergeMessage( - node, source, destination, replace_message, replace_repeated): - """Merge all fields specified by a sub-tree from source to destination.""" - source_descriptor = source.DESCRIPTOR - for name in node: - child = node[name] - field = source_descriptor.fields_by_name[name] - if field is None: - raise ValueError('Error: Can\'t find field {0} in message {1}.'.format( - name, source_descriptor.full_name)) - if child: - # Sub-paths are only allowed for singular message fields. - if (field.label == FieldDescriptor.LABEL_REPEATED or - field.cpp_type != FieldDescriptor.CPPTYPE_MESSAGE): - raise ValueError('Error: Field {0} in message {1} is not a singular ' - 'message field and cannot have sub-fields.'.format( - name, source_descriptor.full_name)) - if source.HasField(name): - _MergeMessage( - child, getattr(source, name), getattr(destination, name), - replace_message, replace_repeated) - continue - if field.label == FieldDescriptor.LABEL_REPEATED: - if replace_repeated: - destination.ClearField(_StrConvert(name)) - repeated_source = getattr(source, name) - repeated_destination = getattr(destination, name) - repeated_destination.MergeFrom(repeated_source) - else: - if field.cpp_type == FieldDescriptor.CPPTYPE_MESSAGE: - if replace_message: - destination.ClearField(_StrConvert(name)) - if source.HasField(name): - getattr(destination, name).MergeFrom(getattr(source, name)) - else: - setattr(destination, name, getattr(source, name)) - - -def _AddFieldPaths(node, prefix, field_mask): - """Adds the field paths descended from node to field_mask.""" - if not node and prefix: - field_mask.paths.append(prefix) - return - for name in sorted(node): - if prefix: - child_path = prefix + '.' + name - else: - child_path = name - _AddFieldPaths(node[name], child_path, field_mask) - - -def _SetStructValue(struct_value, value): - if value is None: - struct_value.null_value = 0 - elif isinstance(value, bool): - # Note: this check must come before the number check because in Python - # True and False are also considered numbers. - struct_value.bool_value = value - elif isinstance(value, str): - struct_value.string_value = value - elif isinstance(value, (int, float)): - struct_value.number_value = value - elif isinstance(value, (dict, Struct)): - struct_value.struct_value.Clear() - struct_value.struct_value.update(value) - elif isinstance(value, (list, ListValue)): - struct_value.list_value.Clear() - struct_value.list_value.extend(value) - else: - raise ValueError('Unexpected type') - - -def _GetStructValue(struct_value): - which = struct_value.WhichOneof('kind') - if which == 'struct_value': - return struct_value.struct_value - elif which == 'null_value': - return None - elif which == 'number_value': - return struct_value.number_value - elif which == 'string_value': - return struct_value.string_value - elif which == 'bool_value': - return struct_value.bool_value - elif which == 'list_value': - return struct_value.list_value - elif which is None: - raise ValueError('Value not set') - - -class Struct(object): - """Class for Struct message type.""" - - __slots__ = () - - def __getitem__(self, key): - return _GetStructValue(self.fields[key]) - - def __contains__(self, item): - return item in self.fields - - def __setitem__(self, key, value): - _SetStructValue(self.fields[key], value) - - def __delitem__(self, key): - del self.fields[key] - - def __len__(self): - return len(self.fields) - - def __iter__(self): - return iter(self.fields) - - def keys(self): # pylint: disable=invalid-name - return self.fields.keys() - - def values(self): # pylint: disable=invalid-name - return [self[key] for key in self] - - def items(self): # pylint: disable=invalid-name - return [(key, self[key]) for key in self] - - def get_or_create_list(self, key): - """Returns a list for this key, creating if it didn't exist already.""" - if not self.fields[key].HasField('list_value'): - # Clear will mark list_value modified which will indeed create a list. - self.fields[key].list_value.Clear() - return self.fields[key].list_value - - def get_or_create_struct(self, key): - """Returns a struct for this key, creating if it didn't exist already.""" - if not self.fields[key].HasField('struct_value'): - # Clear will mark struct_value modified which will indeed create a struct. - self.fields[key].struct_value.Clear() - return self.fields[key].struct_value - - def update(self, dictionary): # pylint: disable=invalid-name - for key, value in dictionary.items(): - _SetStructValue(self.fields[key], value) - -collections.abc.MutableMapping.register(Struct) - - -class ListValue(object): - """Class for ListValue message type.""" - - __slots__ = () - - def __len__(self): - return len(self.values) - - def append(self, value): - _SetStructValue(self.values.add(), value) - - def extend(self, elem_seq): - for value in elem_seq: - self.append(value) - - def __getitem__(self, index): - """Retrieves item by the specified index.""" - return _GetStructValue(self.values.__getitem__(index)) - - def __setitem__(self, index, value): - _SetStructValue(self.values.__getitem__(index), value) - - def __delitem__(self, key): - del self.values[key] - - def items(self): - for i in range(len(self)): - yield self[i] - - def add_struct(self): - """Appends and returns a struct value as the next value in the list.""" - struct_value = self.values.add().struct_value - # Clear will mark struct_value modified which will indeed create a struct. - struct_value.Clear() - return struct_value - - def add_list(self): - """Appends and returns a list value as the next value in the list.""" - list_value = self.values.add().list_value - # Clear will mark list_value modified which will indeed create a list. - list_value.Clear() - return list_value - -collections.abc.MutableSequence.register(ListValue) - - -WKTBASES = { - 'google.protobuf.Any': Any, - 'google.protobuf.Duration': Duration, - 'google.protobuf.FieldMask': FieldMask, - 'google.protobuf.ListValue': ListValue, - 'google.protobuf.Struct': Struct, - 'google.protobuf.Timestamp': Timestamp, -} diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/wire_format.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/wire_format.py deleted file mode 100644 index 883f525585..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/internal/wire_format.py +++ /dev/null @@ -1,268 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Constants and static functions to support protocol buffer wire format.""" - -__author__ = 'robinson@google.com (Will Robinson)' - -import struct -from google.protobuf import descriptor -from google.protobuf import message - - -TAG_TYPE_BITS = 3 # Number of bits used to hold type info in a proto tag. -TAG_TYPE_MASK = (1 << TAG_TYPE_BITS) - 1 # 0x7 - -# These numbers identify the wire type of a protocol buffer value. -# We use the least-significant TAG_TYPE_BITS bits of the varint-encoded -# tag-and-type to store one of these WIRETYPE_* constants. -# These values must match WireType enum in google/protobuf/wire_format.h. -WIRETYPE_VARINT = 0 -WIRETYPE_FIXED64 = 1 -WIRETYPE_LENGTH_DELIMITED = 2 -WIRETYPE_START_GROUP = 3 -WIRETYPE_END_GROUP = 4 -WIRETYPE_FIXED32 = 5 -_WIRETYPE_MAX = 5 - - -# Bounds for various integer types. -INT32_MAX = int((1 << 31) - 1) -INT32_MIN = int(-(1 << 31)) -UINT32_MAX = (1 << 32) - 1 - -INT64_MAX = (1 << 63) - 1 -INT64_MIN = -(1 << 63) -UINT64_MAX = (1 << 64) - 1 - -# "struct" format strings that will encode/decode the specified formats. -FORMAT_UINT32_LITTLE_ENDIAN = '> TAG_TYPE_BITS), (tag & TAG_TYPE_MASK) - - -def ZigZagEncode(value): - """ZigZag Transform: Encodes signed integers so that they can be - effectively used with varint encoding. See wire_format.h for - more details. - """ - if value >= 0: - return value << 1 - return (value << 1) ^ (~0) - - -def ZigZagDecode(value): - """Inverse of ZigZagEncode().""" - if not value & 0x1: - return value >> 1 - return (value >> 1) ^ (~0) - - - -# The *ByteSize() functions below return the number of bytes required to -# serialize "field number + type" information and then serialize the value. - - -def Int32ByteSize(field_number, int32): - return Int64ByteSize(field_number, int32) - - -def Int32ByteSizeNoTag(int32): - return _VarUInt64ByteSizeNoTag(0xffffffffffffffff & int32) - - -def Int64ByteSize(field_number, int64): - # Have to convert to uint before calling UInt64ByteSize(). - return UInt64ByteSize(field_number, 0xffffffffffffffff & int64) - - -def UInt32ByteSize(field_number, uint32): - return UInt64ByteSize(field_number, uint32) - - -def UInt64ByteSize(field_number, uint64): - return TagByteSize(field_number) + _VarUInt64ByteSizeNoTag(uint64) - - -def SInt32ByteSize(field_number, int32): - return UInt32ByteSize(field_number, ZigZagEncode(int32)) - - -def SInt64ByteSize(field_number, int64): - return UInt64ByteSize(field_number, ZigZagEncode(int64)) - - -def Fixed32ByteSize(field_number, fixed32): - return TagByteSize(field_number) + 4 - - -def Fixed64ByteSize(field_number, fixed64): - return TagByteSize(field_number) + 8 - - -def SFixed32ByteSize(field_number, sfixed32): - return TagByteSize(field_number) + 4 - - -def SFixed64ByteSize(field_number, sfixed64): - return TagByteSize(field_number) + 8 - - -def FloatByteSize(field_number, flt): - return TagByteSize(field_number) + 4 - - -def DoubleByteSize(field_number, double): - return TagByteSize(field_number) + 8 - - -def BoolByteSize(field_number, b): - return TagByteSize(field_number) + 1 - - -def EnumByteSize(field_number, enum): - return UInt32ByteSize(field_number, enum) - - -def StringByteSize(field_number, string): - return BytesByteSize(field_number, string.encode('utf-8')) - - -def BytesByteSize(field_number, b): - return (TagByteSize(field_number) - + _VarUInt64ByteSizeNoTag(len(b)) - + len(b)) - - -def GroupByteSize(field_number, message): - return (2 * TagByteSize(field_number) # START and END group. - + message.ByteSize()) - - -def MessageByteSize(field_number, message): - return (TagByteSize(field_number) - + _VarUInt64ByteSizeNoTag(message.ByteSize()) - + message.ByteSize()) - - -def MessageSetItemByteSize(field_number, msg): - # First compute the sizes of the tags. - # There are 2 tags for the beginning and ending of the repeated group, that - # is field number 1, one with field number 2 (type_id) and one with field - # number 3 (message). - total_size = (2 * TagByteSize(1) + TagByteSize(2) + TagByteSize(3)) - - # Add the number of bytes for type_id. - total_size += _VarUInt64ByteSizeNoTag(field_number) - - message_size = msg.ByteSize() - - # The number of bytes for encoding the length of the message. - total_size += _VarUInt64ByteSizeNoTag(message_size) - - # The size of the message. - total_size += message_size - return total_size - - -def TagByteSize(field_number): - """Returns the bytes required to serialize a tag with this field number.""" - # Just pass in type 0, since the type won't affect the tag+type size. - return _VarUInt64ByteSizeNoTag(PackTag(field_number, 0)) - - -# Private helper function for the *ByteSize() functions above. - -def _VarUInt64ByteSizeNoTag(uint64): - """Returns the number of bytes required to serialize a single varint - using boundary value comparisons. (unrolled loop optimization -WPierce) - uint64 must be unsigned. - """ - if uint64 <= 0x7f: return 1 - if uint64 <= 0x3fff: return 2 - if uint64 <= 0x1fffff: return 3 - if uint64 <= 0xfffffff: return 4 - if uint64 <= 0x7ffffffff: return 5 - if uint64 <= 0x3ffffffffff: return 6 - if uint64 <= 0x1ffffffffffff: return 7 - if uint64 <= 0xffffffffffffff: return 8 - if uint64 <= 0x7fffffffffffffff: return 9 - if uint64 > UINT64_MAX: - raise message.EncodeError('Value out of range: %d' % uint64) - return 10 - - -NON_PACKABLE_TYPES = ( - descriptor.FieldDescriptor.TYPE_STRING, - descriptor.FieldDescriptor.TYPE_GROUP, - descriptor.FieldDescriptor.TYPE_MESSAGE, - descriptor.FieldDescriptor.TYPE_BYTES -) - - -def IsTypePackable(field_type): - """Return true iff packable = true is valid for fields of this type. - - Args: - field_type: a FieldDescriptor::Type value. - - Returns: - True iff fields of this type are packable. - """ - return field_type not in NON_PACKABLE_TYPES diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/json_format.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/json_format.py deleted file mode 100644 index 5024ed89d7..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/json_format.py +++ /dev/null @@ -1,912 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Contains routines for printing protocol messages in JSON format. - -Simple usage example: - - # Create a proto object and serialize it to a json format string. - message = my_proto_pb2.MyMessage(foo='bar') - json_string = json_format.MessageToJson(message) - - # Parse a json format string to proto object. - message = json_format.Parse(json_string, my_proto_pb2.MyMessage()) -""" - -__author__ = 'jieluo@google.com (Jie Luo)' - - -import base64 -from collections import OrderedDict -import json -import math -from operator import methodcaller -import re -import sys - -from google.protobuf.internal import type_checkers -from google.protobuf import descriptor -from google.protobuf import symbol_database - - -_TIMESTAMPFOMAT = '%Y-%m-%dT%H:%M:%S' -_INT_TYPES = frozenset([descriptor.FieldDescriptor.CPPTYPE_INT32, - descriptor.FieldDescriptor.CPPTYPE_UINT32, - descriptor.FieldDescriptor.CPPTYPE_INT64, - descriptor.FieldDescriptor.CPPTYPE_UINT64]) -_INT64_TYPES = frozenset([descriptor.FieldDescriptor.CPPTYPE_INT64, - descriptor.FieldDescriptor.CPPTYPE_UINT64]) -_FLOAT_TYPES = frozenset([descriptor.FieldDescriptor.CPPTYPE_FLOAT, - descriptor.FieldDescriptor.CPPTYPE_DOUBLE]) -_INFINITY = 'Infinity' -_NEG_INFINITY = '-Infinity' -_NAN = 'NaN' - -_UNPAIRED_SURROGATE_PATTERN = re.compile( - u'[\ud800-\udbff](?![\udc00-\udfff])|(? self.max_recursion_depth: - raise ParseError('Message too deep. Max recursion depth is {0}'.format( - self.max_recursion_depth)) - message_descriptor = message.DESCRIPTOR - full_name = message_descriptor.full_name - if not path: - path = message_descriptor.name - if _IsWrapperMessage(message_descriptor): - self._ConvertWrapperMessage(value, message, path) - elif full_name in _WKTJSONMETHODS: - methodcaller(_WKTJSONMETHODS[full_name][1], value, message, path)(self) - else: - self._ConvertFieldValuePair(value, message, path) - self.recursion_depth -= 1 - - def _ConvertFieldValuePair(self, js, message, path): - """Convert field value pairs into regular message. - - Args: - js: A JSON object to convert the field value pairs. - message: A regular protocol message to record the data. - path: parent path to log parse error info. - - Raises: - ParseError: In case of problems converting. - """ - names = [] - message_descriptor = message.DESCRIPTOR - fields_by_json_name = dict((f.json_name, f) - for f in message_descriptor.fields) - for name in js: - try: - field = fields_by_json_name.get(name, None) - if not field: - field = message_descriptor.fields_by_name.get(name, None) - if not field and _VALID_EXTENSION_NAME.match(name): - if not message_descriptor.is_extendable: - raise ParseError( - 'Message type {0} does not have extensions at {1}'.format( - message_descriptor.full_name, path)) - identifier = name[1:-1] # strip [] brackets - # pylint: disable=protected-access - field = message.Extensions._FindExtensionByName(identifier) - # pylint: enable=protected-access - if not field: - # Try looking for extension by the message type name, dropping the - # field name following the final . separator in full_name. - identifier = '.'.join(identifier.split('.')[:-1]) - # pylint: disable=protected-access - field = message.Extensions._FindExtensionByName(identifier) - # pylint: enable=protected-access - if not field: - if self.ignore_unknown_fields: - continue - raise ParseError( - ('Message type "{0}" has no field named "{1}" at "{2}".\n' - ' Available Fields(except extensions): "{3}"').format( - message_descriptor.full_name, name, path, - [f.json_name for f in message_descriptor.fields])) - if name in names: - raise ParseError('Message type "{0}" should not have multiple ' - '"{1}" fields at "{2}".'.format( - message.DESCRIPTOR.full_name, name, path)) - names.append(name) - value = js[name] - # Check no other oneof field is parsed. - if field.containing_oneof is not None and value is not None: - oneof_name = field.containing_oneof.name - if oneof_name in names: - raise ParseError('Message type "{0}" should not have multiple ' - '"{1}" oneof fields at "{2}".'.format( - message.DESCRIPTOR.full_name, oneof_name, - path)) - names.append(oneof_name) - - if value is None: - if (field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE - and field.message_type.full_name == 'google.protobuf.Value'): - sub_message = getattr(message, field.name) - sub_message.null_value = 0 - elif (field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_ENUM - and field.enum_type.full_name == 'google.protobuf.NullValue'): - setattr(message, field.name, 0) - else: - message.ClearField(field.name) - continue - - # Parse field value. - if _IsMapEntry(field): - message.ClearField(field.name) - self._ConvertMapFieldValue(value, message, field, - '{0}.{1}'.format(path, name)) - elif field.label == descriptor.FieldDescriptor.LABEL_REPEATED: - message.ClearField(field.name) - if not isinstance(value, list): - raise ParseError('repeated field {0} must be in [] which is ' - '{1} at {2}'.format(name, value, path)) - if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: - # Repeated message field. - for index, item in enumerate(value): - sub_message = getattr(message, field.name).add() - # None is a null_value in Value. - if (item is None and - sub_message.DESCRIPTOR.full_name != 'google.protobuf.Value'): - raise ParseError('null is not allowed to be used as an element' - ' in a repeated field at {0}.{1}[{2}]'.format( - path, name, index)) - self.ConvertMessage(item, sub_message, - '{0}.{1}[{2}]'.format(path, name, index)) - else: - # Repeated scalar field. - for index, item in enumerate(value): - if item is None: - raise ParseError('null is not allowed to be used as an element' - ' in a repeated field at {0}.{1}[{2}]'.format( - path, name, index)) - getattr(message, field.name).append( - _ConvertScalarFieldValue( - item, field, '{0}.{1}[{2}]'.format(path, name, index))) - elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: - if field.is_extension: - sub_message = message.Extensions[field] - else: - sub_message = getattr(message, field.name) - sub_message.SetInParent() - self.ConvertMessage(value, sub_message, '{0}.{1}'.format(path, name)) - else: - if field.is_extension: - message.Extensions[field] = _ConvertScalarFieldValue( - value, field, '{0}.{1}'.format(path, name)) - else: - setattr( - message, field.name, - _ConvertScalarFieldValue(value, field, - '{0}.{1}'.format(path, name))) - except ParseError as e: - if field and field.containing_oneof is None: - raise ParseError('Failed to parse {0} field: {1}.'.format(name, e)) - else: - raise ParseError(str(e)) - except ValueError as e: - raise ParseError('Failed to parse {0} field: {1}.'.format(name, e)) - except TypeError as e: - raise ParseError('Failed to parse {0} field: {1}.'.format(name, e)) - - def _ConvertAnyMessage(self, value, message, path): - """Convert a JSON representation into Any message.""" - if isinstance(value, dict) and not value: - return - try: - type_url = value['@type'] - except KeyError: - raise ParseError( - '@type is missing when parsing any message at {0}'.format(path)) - - try: - sub_message = _CreateMessageFromTypeUrl(type_url, self.descriptor_pool) - except TypeError as e: - raise ParseError('{0} at {1}'.format(e, path)) - message_descriptor = sub_message.DESCRIPTOR - full_name = message_descriptor.full_name - if _IsWrapperMessage(message_descriptor): - self._ConvertWrapperMessage(value['value'], sub_message, - '{0}.value'.format(path)) - elif full_name in _WKTJSONMETHODS: - methodcaller(_WKTJSONMETHODS[full_name][1], value['value'], sub_message, - '{0}.value'.format(path))( - self) - else: - del value['@type'] - self._ConvertFieldValuePair(value, sub_message, path) - value['@type'] = type_url - # Sets Any message - message.value = sub_message.SerializeToString() - message.type_url = type_url - - def _ConvertGenericMessage(self, value, message, path): - """Convert a JSON representation into message with FromJsonString.""" - # Duration, Timestamp, FieldMask have a FromJsonString method to do the - # conversion. Users can also call the method directly. - try: - message.FromJsonString(value) - except ValueError as e: - raise ParseError('{0} at {1}'.format(e, path)) - - def _ConvertValueMessage(self, value, message, path): - """Convert a JSON representation into Value message.""" - if isinstance(value, dict): - self._ConvertStructMessage(value, message.struct_value, path) - elif isinstance(value, list): - self._ConvertListValueMessage(value, message.list_value, path) - elif value is None: - message.null_value = 0 - elif isinstance(value, bool): - message.bool_value = value - elif isinstance(value, str): - message.string_value = value - elif isinstance(value, _INT_OR_FLOAT): - message.number_value = value - else: - raise ParseError('Value {0} has unexpected type {1} at {2}'.format( - value, type(value), path)) - - def _ConvertListValueMessage(self, value, message, path): - """Convert a JSON representation into ListValue message.""" - if not isinstance(value, list): - raise ParseError('ListValue must be in [] which is {0} at {1}'.format( - value, path)) - message.ClearField('values') - for index, item in enumerate(value): - self._ConvertValueMessage(item, message.values.add(), - '{0}[{1}]'.format(path, index)) - - def _ConvertStructMessage(self, value, message, path): - """Convert a JSON representation into Struct message.""" - if not isinstance(value, dict): - raise ParseError('Struct must be in a dict which is {0} at {1}'.format( - value, path)) - # Clear will mark the struct as modified so it will be created even if - # there are no values. - message.Clear() - for key in value: - self._ConvertValueMessage(value[key], message.fields[key], - '{0}.{1}'.format(path, key)) - return - - def _ConvertWrapperMessage(self, value, message, path): - """Convert a JSON representation into Wrapper message.""" - field = message.DESCRIPTOR.fields_by_name['value'] - setattr( - message, 'value', - _ConvertScalarFieldValue(value, field, path='{0}.value'.format(path))) - - def _ConvertMapFieldValue(self, value, message, field, path): - """Convert map field value for a message map field. - - Args: - value: A JSON object to convert the map field value. - message: A protocol message to record the converted data. - field: The descriptor of the map field to be converted. - path: parent path to log parse error info. - - Raises: - ParseError: In case of convert problems. - """ - if not isinstance(value, dict): - raise ParseError( - 'Map field {0} must be in a dict which is {1} at {2}'.format( - field.name, value, path)) - key_field = field.message_type.fields_by_name['key'] - value_field = field.message_type.fields_by_name['value'] - for key in value: - key_value = _ConvertScalarFieldValue(key, key_field, - '{0}.key'.format(path), True) - if value_field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: - self.ConvertMessage(value[key], - getattr(message, field.name)[key_value], - '{0}[{1}]'.format(path, key_value)) - else: - getattr(message, field.name)[key_value] = _ConvertScalarFieldValue( - value[key], value_field, path='{0}[{1}]'.format(path, key_value)) - - -def _ConvertScalarFieldValue(value, field, path, require_str=False): - """Convert a single scalar field value. - - Args: - value: A scalar value to convert the scalar field value. - field: The descriptor of the field to convert. - path: parent path to log parse error info. - require_str: If True, the field value must be a str. - - Returns: - The converted scalar field value - - Raises: - ParseError: In case of convert problems. - """ - try: - if field.cpp_type in _INT_TYPES: - return _ConvertInteger(value) - elif field.cpp_type in _FLOAT_TYPES: - return _ConvertFloat(value, field) - elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_BOOL: - return _ConvertBool(value, require_str) - elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_STRING: - if field.type == descriptor.FieldDescriptor.TYPE_BYTES: - if isinstance(value, str): - encoded = value.encode('utf-8') - else: - encoded = value - # Add extra padding '=' - padded_value = encoded + b'=' * (4 - len(encoded) % 4) - return base64.urlsafe_b64decode(padded_value) - else: - # Checking for unpaired surrogates appears to be unreliable, - # depending on the specific Python version, so we check manually. - if _UNPAIRED_SURROGATE_PATTERN.search(value): - raise ParseError('Unpaired surrogate') - return value - elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_ENUM: - # Convert an enum value. - enum_value = field.enum_type.values_by_name.get(value, None) - if enum_value is None: - try: - number = int(value) - enum_value = field.enum_type.values_by_number.get(number, None) - except ValueError: - raise ParseError('Invalid enum value {0} for enum type {1}'.format( - value, field.enum_type.full_name)) - if enum_value is None: - if field.file.syntax == 'proto3': - # Proto3 accepts unknown enums. - return number - raise ParseError('Invalid enum value {0} for enum type {1}'.format( - value, field.enum_type.full_name)) - return enum_value.number - except ParseError as e: - raise ParseError('{0} at {1}'.format(e, path)) - - -def _ConvertInteger(value): - """Convert an integer. - - Args: - value: A scalar value to convert. - - Returns: - The integer value. - - Raises: - ParseError: If an integer couldn't be consumed. - """ - if isinstance(value, float) and not value.is_integer(): - raise ParseError('Couldn\'t parse integer: {0}'.format(value)) - - if isinstance(value, str) and value.find(' ') != -1: - raise ParseError('Couldn\'t parse integer: "{0}"'.format(value)) - - if isinstance(value, bool): - raise ParseError('Bool value {0} is not acceptable for ' - 'integer field'.format(value)) - - return int(value) - - -def _ConvertFloat(value, field): - """Convert an floating point number.""" - if isinstance(value, float): - if math.isnan(value): - raise ParseError('Couldn\'t parse NaN, use quoted "NaN" instead') - if math.isinf(value): - if value > 0: - raise ParseError('Couldn\'t parse Infinity or value too large, ' - 'use quoted "Infinity" instead') - else: - raise ParseError('Couldn\'t parse -Infinity or value too small, ' - 'use quoted "-Infinity" instead') - if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_FLOAT: - # pylint: disable=protected-access - if value > type_checkers._FLOAT_MAX: - raise ParseError('Float value too large') - # pylint: disable=protected-access - if value < type_checkers._FLOAT_MIN: - raise ParseError('Float value too small') - if value == 'nan': - raise ParseError('Couldn\'t parse float "nan", use "NaN" instead') - try: - # Assume Python compatible syntax. - return float(value) - except ValueError: - # Check alternative spellings. - if value == _NEG_INFINITY: - return float('-inf') - elif value == _INFINITY: - return float('inf') - elif value == _NAN: - return float('nan') - else: - raise ParseError('Couldn\'t parse float: {0}'.format(value)) - - -def _ConvertBool(value, require_str): - """Convert a boolean value. - - Args: - value: A scalar value to convert. - require_str: If True, value must be a str. - - Returns: - The bool parsed. - - Raises: - ParseError: If a boolean value couldn't be consumed. - """ - if require_str: - if value == 'true': - return True - elif value == 'false': - return False - else: - raise ParseError('Expected "true" or "false", not {0}'.format(value)) - - if not isinstance(value, bool): - raise ParseError('Expected true or false without quotes') - return value - -_WKTJSONMETHODS = { - 'google.protobuf.Any': ['_AnyMessageToJsonObject', - '_ConvertAnyMessage'], - 'google.protobuf.Duration': ['_GenericMessageToJsonObject', - '_ConvertGenericMessage'], - 'google.protobuf.FieldMask': ['_GenericMessageToJsonObject', - '_ConvertGenericMessage'], - 'google.protobuf.ListValue': ['_ListValueMessageToJsonObject', - '_ConvertListValueMessage'], - 'google.protobuf.Struct': ['_StructMessageToJsonObject', - '_ConvertStructMessage'], - 'google.protobuf.Timestamp': ['_GenericMessageToJsonObject', - '_ConvertGenericMessage'], - 'google.protobuf.Value': ['_ValueMessageToJsonObject', - '_ConvertValueMessage'] -} diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/message.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/message.py deleted file mode 100644 index 76c6802f70..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/message.py +++ /dev/null @@ -1,424 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -# TODO(robinson): We should just make these methods all "pure-virtual" and move -# all implementation out, into reflection.py for now. - - -"""Contains an abstract base class for protocol messages.""" - -__author__ = 'robinson@google.com (Will Robinson)' - -class Error(Exception): - """Base error type for this module.""" - pass - - -class DecodeError(Error): - """Exception raised when deserializing messages.""" - pass - - -class EncodeError(Error): - """Exception raised when serializing messages.""" - pass - - -class Message(object): - - """Abstract base class for protocol messages. - - Protocol message classes are almost always generated by the protocol - compiler. These generated types subclass Message and implement the methods - shown below. - """ - - # TODO(robinson): Link to an HTML document here. - - # TODO(robinson): Document that instances of this class will also - # have an Extensions attribute with __getitem__ and __setitem__. - # Again, not sure how to best convey this. - - # TODO(robinson): Document that the class must also have a static - # RegisterExtension(extension_field) method. - # Not sure how to best express at this point. - - # TODO(robinson): Document these fields and methods. - - __slots__ = [] - - #: The :class:`google.protobuf.descriptor.Descriptor` for this message type. - DESCRIPTOR = None - - def __deepcopy__(self, memo=None): - clone = type(self)() - clone.MergeFrom(self) - return clone - - def __eq__(self, other_msg): - """Recursively compares two messages by value and structure.""" - raise NotImplementedError - - def __ne__(self, other_msg): - # Can't just say self != other_msg, since that would infinitely recurse. :) - return not self == other_msg - - def __hash__(self): - raise TypeError('unhashable object') - - def __str__(self): - """Outputs a human-readable representation of the message.""" - raise NotImplementedError - - def __unicode__(self): - """Outputs a human-readable representation of the message.""" - raise NotImplementedError - - def MergeFrom(self, other_msg): - """Merges the contents of the specified message into current message. - - This method merges the contents of the specified message into the current - message. Singular fields that are set in the specified message overwrite - the corresponding fields in the current message. Repeated fields are - appended. Singular sub-messages and groups are recursively merged. - - Args: - other_msg (Message): A message to merge into the current message. - """ - raise NotImplementedError - - def CopyFrom(self, other_msg): - """Copies the content of the specified message into the current message. - - The method clears the current message and then merges the specified - message using MergeFrom. - - Args: - other_msg (Message): A message to copy into the current one. - """ - if self is other_msg: - return - self.Clear() - self.MergeFrom(other_msg) - - def Clear(self): - """Clears all data that was set in the message.""" - raise NotImplementedError - - def SetInParent(self): - """Mark this as present in the parent. - - This normally happens automatically when you assign a field of a - sub-message, but sometimes you want to make the sub-message - present while keeping it empty. If you find yourself using this, - you may want to reconsider your design. - """ - raise NotImplementedError - - def IsInitialized(self): - """Checks if the message is initialized. - - Returns: - bool: The method returns True if the message is initialized (i.e. all of - its required fields are set). - """ - raise NotImplementedError - - # TODO(robinson): MergeFromString() should probably return None and be - # implemented in terms of a helper that returns the # of bytes read. Our - # deserialization routines would use the helper when recursively - # deserializing, but the end user would almost always just want the no-return - # MergeFromString(). - - def MergeFromString(self, serialized): - """Merges serialized protocol buffer data into this message. - - When we find a field in `serialized` that is already present - in this message: - - - If it's a "repeated" field, we append to the end of our list. - - Else, if it's a scalar, we overwrite our field. - - Else, (it's a nonrepeated composite), we recursively merge - into the existing composite. - - Args: - serialized (bytes): Any object that allows us to call - ``memoryview(serialized)`` to access a string of bytes using the - buffer interface. - - Returns: - int: The number of bytes read from `serialized`. - For non-group messages, this will always be `len(serialized)`, - but for messages which are actually groups, this will - generally be less than `len(serialized)`, since we must - stop when we reach an ``END_GROUP`` tag. Note that if - we *do* stop because of an ``END_GROUP`` tag, the number - of bytes returned does not include the bytes - for the ``END_GROUP`` tag information. - - Raises: - DecodeError: if the input cannot be parsed. - """ - # TODO(robinson): Document handling of unknown fields. - # TODO(robinson): When we switch to a helper, this will return None. - raise NotImplementedError - - def ParseFromString(self, serialized): - """Parse serialized protocol buffer data into this message. - - Like :func:`MergeFromString()`, except we clear the object first. - - Raises: - message.DecodeError if the input cannot be parsed. - """ - self.Clear() - return self.MergeFromString(serialized) - - def SerializeToString(self, **kwargs): - """Serializes the protocol message to a binary string. - - Keyword Args: - deterministic (bool): If true, requests deterministic serialization - of the protobuf, with predictable ordering of map keys. - - Returns: - A binary string representation of the message if all of the required - fields in the message are set (i.e. the message is initialized). - - Raises: - EncodeError: if the message isn't initialized (see :func:`IsInitialized`). - """ - raise NotImplementedError - - def SerializePartialToString(self, **kwargs): - """Serializes the protocol message to a binary string. - - This method is similar to SerializeToString but doesn't check if the - message is initialized. - - Keyword Args: - deterministic (bool): If true, requests deterministic serialization - of the protobuf, with predictable ordering of map keys. - - Returns: - bytes: A serialized representation of the partial message. - """ - raise NotImplementedError - - # TODO(robinson): Decide whether we like these better - # than auto-generated has_foo() and clear_foo() methods - # on the instances themselves. This way is less consistent - # with C++, but it makes reflection-type access easier and - # reduces the number of magically autogenerated things. - # - # TODO(robinson): Be sure to document (and test) exactly - # which field names are accepted here. Are we case-sensitive? - # What do we do with fields that share names with Python keywords - # like 'lambda' and 'yield'? - # - # nnorwitz says: - # """ - # Typically (in python), an underscore is appended to names that are - # keywords. So they would become lambda_ or yield_. - # """ - def ListFields(self): - """Returns a list of (FieldDescriptor, value) tuples for present fields. - - A message field is non-empty if HasField() would return true. A singular - primitive field is non-empty if HasField() would return true in proto2 or it - is non zero in proto3. A repeated field is non-empty if it contains at least - one element. The fields are ordered by field number. - - Returns: - list[tuple(FieldDescriptor, value)]: field descriptors and values - for all fields in the message which are not empty. The values vary by - field type. - """ - raise NotImplementedError - - def HasField(self, field_name): - """Checks if a certain field is set for the message. - - For a oneof group, checks if any field inside is set. Note that if the - field_name is not defined in the message descriptor, :exc:`ValueError` will - be raised. - - Args: - field_name (str): The name of the field to check for presence. - - Returns: - bool: Whether a value has been set for the named field. - - Raises: - ValueError: if the `field_name` is not a member of this message. - """ - raise NotImplementedError - - def ClearField(self, field_name): - """Clears the contents of a given field. - - Inside a oneof group, clears the field set. If the name neither refers to a - defined field or oneof group, :exc:`ValueError` is raised. - - Args: - field_name (str): The name of the field to check for presence. - - Raises: - ValueError: if the `field_name` is not a member of this message. - """ - raise NotImplementedError - - def WhichOneof(self, oneof_group): - """Returns the name of the field that is set inside a oneof group. - - If no field is set, returns None. - - Args: - oneof_group (str): the name of the oneof group to check. - - Returns: - str or None: The name of the group that is set, or None. - - Raises: - ValueError: no group with the given name exists - """ - raise NotImplementedError - - def HasExtension(self, extension_handle): - """Checks if a certain extension is present for this message. - - Extensions are retrieved using the :attr:`Extensions` mapping (if present). - - Args: - extension_handle: The handle for the extension to check. - - Returns: - bool: Whether the extension is present for this message. - - Raises: - KeyError: if the extension is repeated. Similar to repeated fields, - there is no separate notion of presence: a "not present" repeated - extension is an empty list. - """ - raise NotImplementedError - - def ClearExtension(self, extension_handle): - """Clears the contents of a given extension. - - Args: - extension_handle: The handle for the extension to clear. - """ - raise NotImplementedError - - def UnknownFields(self): - """Returns the UnknownFieldSet. - - Returns: - UnknownFieldSet: The unknown fields stored in this message. - """ - raise NotImplementedError - - def DiscardUnknownFields(self): - """Clears all fields in the :class:`UnknownFieldSet`. - - This operation is recursive for nested message. - """ - raise NotImplementedError - - def ByteSize(self): - """Returns the serialized size of this message. - - Recursively calls ByteSize() on all contained messages. - - Returns: - int: The number of bytes required to serialize this message. - """ - raise NotImplementedError - - @classmethod - def FromString(cls, s): - raise NotImplementedError - - @staticmethod - def RegisterExtension(extension_handle): - raise NotImplementedError - - def _SetListener(self, message_listener): - """Internal method used by the protocol message implementation. - Clients should not call this directly. - - Sets a listener that this message will call on certain state transitions. - - The purpose of this method is to register back-edges from children to - parents at runtime, for the purpose of setting "has" bits and - byte-size-dirty bits in the parent and ancestor objects whenever a child or - descendant object is modified. - - If the client wants to disconnect this Message from the object tree, she - explicitly sets callback to None. - - If message_listener is None, unregisters any existing listener. Otherwise, - message_listener must implement the MessageListener interface in - internal/message_listener.py, and we discard any listener registered - via a previous _SetListener() call. - """ - raise NotImplementedError - - def __getstate__(self): - """Support the pickle protocol.""" - return dict(serialized=self.SerializePartialToString()) - - def __setstate__(self, state): - """Support the pickle protocol.""" - self.__init__() - serialized = state['serialized'] - # On Python 3, using encoding='latin1' is required for unpickling - # protos pickled by Python 2. - if not isinstance(serialized, bytes): - serialized = serialized.encode('latin1') - self.ParseFromString(serialized) - - def __reduce__(self): - message_descriptor = self.DESCRIPTOR - if message_descriptor.containing_type is None: - return type(self), (), self.__getstate__() - # the message type must be nested. - # Python does not pickle nested classes; use the symbol_database on the - # receiving end. - container = message_descriptor - return (_InternalConstructMessage, (container.full_name,), - self.__getstate__()) - - -def _InternalConstructMessage(full_name): - """Constructs a nested message.""" - from google.protobuf import symbol_database # pylint:disable=g-import-not-at-top - - return symbol_database.Default().GetSymbol(full_name)() diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/message_factory.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/message_factory.py deleted file mode 100644 index 3656fa6874..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/message_factory.py +++ /dev/null @@ -1,185 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Provides a factory class for generating dynamic messages. - -The easiest way to use this class is if you have access to the FileDescriptor -protos containing the messages you want to create you can just do the following: - -message_classes = message_factory.GetMessages(iterable_of_file_descriptors) -my_proto_instance = message_classes['some.proto.package.MessageName']() -""" - -__author__ = 'matthewtoia@google.com (Matt Toia)' - -from google.protobuf.internal import api_implementation -from google.protobuf import descriptor_pool -from google.protobuf import message - -if api_implementation.Type() == 'cpp': - from google.protobuf.pyext import cpp_message as message_impl -else: - from google.protobuf.internal import python_message as message_impl - - -# The type of all Message classes. -_GENERATED_PROTOCOL_MESSAGE_TYPE = message_impl.GeneratedProtocolMessageType - - -class MessageFactory(object): - """Factory for creating Proto2 messages from descriptors in a pool.""" - - def __init__(self, pool=None): - """Initializes a new factory.""" - self.pool = pool or descriptor_pool.DescriptorPool() - - # local cache of all classes built from protobuf descriptors - self._classes = {} - - def GetPrototype(self, descriptor): - """Obtains a proto2 message class based on the passed in descriptor. - - Passing a descriptor with a fully qualified name matching a previous - invocation will cause the same class to be returned. - - Args: - descriptor: The descriptor to build from. - - Returns: - A class describing the passed in descriptor. - """ - if descriptor not in self._classes: - result_class = self.CreatePrototype(descriptor) - # The assignment to _classes is redundant for the base implementation, but - # might avoid confusion in cases where CreatePrototype gets overridden and - # does not call the base implementation. - self._classes[descriptor] = result_class - return result_class - return self._classes[descriptor] - - def CreatePrototype(self, descriptor): - """Builds a proto2 message class based on the passed in descriptor. - - Don't call this function directly, it always creates a new class. Call - GetPrototype() instead. This method is meant to be overridden in subblasses - to perform additional operations on the newly constructed class. - - Args: - descriptor: The descriptor to build from. - - Returns: - A class describing the passed in descriptor. - """ - descriptor_name = descriptor.name - result_class = _GENERATED_PROTOCOL_MESSAGE_TYPE( - descriptor_name, - (message.Message,), - { - 'DESCRIPTOR': descriptor, - # If module not set, it wrongly points to message_factory module. - '__module__': None, - }) - result_class._FACTORY = self # pylint: disable=protected-access - # Assign in _classes before doing recursive calls to avoid infinite - # recursion. - self._classes[descriptor] = result_class - for field in descriptor.fields: - if field.message_type: - self.GetPrototype(field.message_type) - for extension in result_class.DESCRIPTOR.extensions: - if extension.containing_type not in self._classes: - self.GetPrototype(extension.containing_type) - extended_class = self._classes[extension.containing_type] - extended_class.RegisterExtension(extension) - return result_class - - def GetMessages(self, files): - """Gets all the messages from a specified file. - - This will find and resolve dependencies, failing if the descriptor - pool cannot satisfy them. - - Args: - files: The file names to extract messages from. - - Returns: - A dictionary mapping proto names to the message classes. This will include - any dependent messages as well as any messages defined in the same file as - a specified message. - """ - result = {} - for file_name in files: - file_desc = self.pool.FindFileByName(file_name) - for desc in file_desc.message_types_by_name.values(): - result[desc.full_name] = self.GetPrototype(desc) - - # While the extension FieldDescriptors are created by the descriptor pool, - # the python classes created in the factory need them to be registered - # explicitly, which is done below. - # - # The call to RegisterExtension will specifically check if the - # extension was already registered on the object and either - # ignore the registration if the original was the same, or raise - # an error if they were different. - - for extension in file_desc.extensions_by_name.values(): - if extension.containing_type not in self._classes: - self.GetPrototype(extension.containing_type) - extended_class = self._classes[extension.containing_type] - extended_class.RegisterExtension(extension) - return result - - -_FACTORY = MessageFactory() - - -def GetMessages(file_protos): - """Builds a dictionary of all the messages available in a set of files. - - Args: - file_protos: Iterable of FileDescriptorProto to build messages out of. - - Returns: - A dictionary mapping proto names to the message classes. This will include - any dependent messages as well as any messages defined in the same file as - a specified message. - """ - # The cpp implementation of the protocol buffer library requires to add the - # message in topological order of the dependency graph. - file_by_name = {file_proto.name: file_proto for file_proto in file_protos} - def _AddFile(file_proto): - for dependency in file_proto.dependency: - if dependency in file_by_name: - # Remove from elements to be visited, in order to cut cycles. - _AddFile(file_by_name.pop(dependency)) - _FACTORY.pool.Add(file_proto) - while file_by_name: - _AddFile(file_by_name.popitem()[1]) - return _FACTORY.GetMessages([file_proto.name for file_proto in file_protos]) diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/proto_builder.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/proto_builder.py deleted file mode 100644 index a4667ce63e..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/proto_builder.py +++ /dev/null @@ -1,134 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Dynamic Protobuf class creator.""" - -from collections import OrderedDict -import hashlib -import os - -from google.protobuf import descriptor_pb2 -from google.protobuf import descriptor -from google.protobuf import message_factory - - -def _GetMessageFromFactory(factory, full_name): - """Get a proto class from the MessageFactory by name. - - Args: - factory: a MessageFactory instance. - full_name: str, the fully qualified name of the proto type. - Returns: - A class, for the type identified by full_name. - Raises: - KeyError, if the proto is not found in the factory's descriptor pool. - """ - proto_descriptor = factory.pool.FindMessageTypeByName(full_name) - proto_cls = factory.GetPrototype(proto_descriptor) - return proto_cls - - -def MakeSimpleProtoClass(fields, full_name=None, pool=None): - """Create a Protobuf class whose fields are basic types. - - Note: this doesn't validate field names! - - Args: - fields: dict of {name: field_type} mappings for each field in the proto. If - this is an OrderedDict the order will be maintained, otherwise the - fields will be sorted by name. - full_name: optional str, the fully-qualified name of the proto type. - pool: optional DescriptorPool instance. - Returns: - a class, the new protobuf class with a FileDescriptor. - """ - factory = message_factory.MessageFactory(pool=pool) - - if full_name is not None: - try: - proto_cls = _GetMessageFromFactory(factory, full_name) - return proto_cls - except KeyError: - # The factory's DescriptorPool doesn't know about this class yet. - pass - - # Get a list of (name, field_type) tuples from the fields dict. If fields was - # an OrderedDict we keep the order, but otherwise we sort the field to ensure - # consistent ordering. - field_items = fields.items() - if not isinstance(fields, OrderedDict): - field_items = sorted(field_items) - - # Use a consistent file name that is unlikely to conflict with any imported - # proto files. - fields_hash = hashlib.sha1() - for f_name, f_type in field_items: - fields_hash.update(f_name.encode('utf-8')) - fields_hash.update(str(f_type).encode('utf-8')) - proto_file_name = fields_hash.hexdigest() + '.proto' - - # If the proto is anonymous, use the same hash to name it. - if full_name is None: - full_name = ('net.proto2.python.public.proto_builder.AnonymousProto_' + - fields_hash.hexdigest()) - try: - proto_cls = _GetMessageFromFactory(factory, full_name) - return proto_cls - except KeyError: - # The factory's DescriptorPool doesn't know about this class yet. - pass - - # This is the first time we see this proto: add a new descriptor to the pool. - factory.pool.Add( - _MakeFileDescriptorProto(proto_file_name, full_name, field_items)) - return _GetMessageFromFactory(factory, full_name) - - -def _MakeFileDescriptorProto(proto_file_name, full_name, field_items): - """Populate FileDescriptorProto for MessageFactory's DescriptorPool.""" - package, name = full_name.rsplit('.', 1) - file_proto = descriptor_pb2.FileDescriptorProto() - file_proto.name = os.path.join(package.replace('.', '/'), proto_file_name) - file_proto.package = package - desc_proto = file_proto.message_type.add() - desc_proto.name = name - for f_number, (f_name, f_type) in enumerate(field_items, 1): - field_proto = desc_proto.field.add() - field_proto.name = f_name - # # If the number falls in the reserved range, reassign it to the correct - # # number after the range. - if f_number >= descriptor.FieldDescriptor.FIRST_RESERVED_FIELD_NUMBER: - f_number += ( - descriptor.FieldDescriptor.LAST_RESERVED_FIELD_NUMBER - - descriptor.FieldDescriptor.FIRST_RESERVED_FIELD_NUMBER + 1) - field_proto.number = f_number - field_proto.label = descriptor_pb2.FieldDescriptorProto.LABEL_OPTIONAL - field_proto.type = f_type - return file_proto diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/pyext/__init__.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/pyext/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/pyext/cpp_message.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/pyext/cpp_message.py deleted file mode 100644 index fc8eb32d79..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/pyext/cpp_message.py +++ /dev/null @@ -1,65 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Protocol message implementation hooks for C++ implementation. - -Contains helper functions used to create protocol message classes from -Descriptor objects at runtime backed by the protocol buffer C++ API. -""" - -__author__ = 'tibell@google.com (Johan Tibell)' - -from google.protobuf.pyext import _message - - -class GeneratedProtocolMessageType(_message.MessageMeta): - - """Metaclass for protocol message classes created at runtime from Descriptors. - - The protocol compiler currently uses this metaclass to create protocol - message classes at runtime. Clients can also manually create their own - classes at runtime, as in this example: - - mydescriptor = Descriptor(.....) - factory = symbol_database.Default() - factory.pool.AddDescriptor(mydescriptor) - MyProtoClass = factory.GetPrototype(mydescriptor) - myproto_instance = MyProtoClass() - myproto.foo_field = 23 - ... - - The above example will not work for nested types. If you wish to include them, - use reflection.MakeClass() instead of manually instantiating the class in - order to create the appropriate class structure. - """ - - # Must be consistent with the protocol-compiler code in - # proto2/compiler/internal/generator.*. - _DESCRIPTOR_KEY = 'DESCRIPTOR' diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/pyext/python_pb2.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/pyext/python_pb2.py deleted file mode 100644 index 2c6ecf4c98..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/pyext/python_pb2.py +++ /dev/null @@ -1,34 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/pyext/python.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\"google/protobuf/pyext/python.proto\x12\x1fgoogle.protobuf.python.internal\"\xbc\x02\n\x0cTestAllTypes\x12\\\n\x17repeated_nested_message\x18\x01 \x03(\x0b\x32;.google.protobuf.python.internal.TestAllTypes.NestedMessage\x12\\\n\x17optional_nested_message\x18\x02 \x01(\x0b\x32;.google.protobuf.python.internal.TestAllTypes.NestedMessage\x12\x16\n\x0eoptional_int32\x18\x03 \x01(\x05\x1aX\n\rNestedMessage\x12\n\n\x02\x62\x62\x18\x01 \x01(\x05\x12;\n\x02\x63\x63\x18\x02 \x01(\x0b\x32/.google.protobuf.python.internal.ForeignMessage\"&\n\x0e\x46oreignMessage\x12\t\n\x01\x63\x18\x01 \x01(\x05\x12\t\n\x01\x64\x18\x02 \x03(\x05\"\x1d\n\x11TestAllExtensions*\x08\x08\x01\x10\x80\x80\x80\x80\x02:\x9a\x01\n!optional_nested_message_extension\x12\x32.google.protobuf.python.internal.TestAllExtensions\x18\x01 \x01(\x0b\x32;.google.protobuf.python.internal.TestAllTypes.NestedMessage:\x9a\x01\n!repeated_nested_message_extension\x12\x32.google.protobuf.python.internal.TestAllExtensions\x18\x02 \x03(\x0b\x32;.google.protobuf.python.internal.TestAllTypes.NestedMessageB\x02H\x01') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.pyext.python_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - TestAllExtensions.RegisterExtension(optional_nested_message_extension) - TestAllExtensions.RegisterExtension(repeated_nested_message_extension) - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'H\001' - _TESTALLTYPES._serialized_start=72 - _TESTALLTYPES._serialized_end=388 - _TESTALLTYPES_NESTEDMESSAGE._serialized_start=300 - _TESTALLTYPES_NESTEDMESSAGE._serialized_end=388 - _FOREIGNMESSAGE._serialized_start=390 - _FOREIGNMESSAGE._serialized_end=428 - _TESTALLEXTENSIONS._serialized_start=430 - _TESTALLEXTENSIONS._serialized_end=459 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/reflection.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/reflection.py deleted file mode 100644 index 81e18859a8..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/reflection.py +++ /dev/null @@ -1,95 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -# This code is meant to work on Python 2.4 and above only. - -"""Contains a metaclass and helper functions used to create -protocol message classes from Descriptor objects at runtime. - -Recall that a metaclass is the "type" of a class. -(A class is to a metaclass what an instance is to a class.) - -In this case, we use the GeneratedProtocolMessageType metaclass -to inject all the useful functionality into the classes -output by the protocol compiler at compile-time. - -The upshot of all this is that the real implementation -details for ALL pure-Python protocol buffers are *here in -this file*. -""" - -__author__ = 'robinson@google.com (Will Robinson)' - - -from google.protobuf import message_factory -from google.protobuf import symbol_database - -# The type of all Message classes. -# Part of the public interface, but normally only used by message factories. -GeneratedProtocolMessageType = message_factory._GENERATED_PROTOCOL_MESSAGE_TYPE - -MESSAGE_CLASS_CACHE = {} - - -# Deprecated. Please NEVER use reflection.ParseMessage(). -def ParseMessage(descriptor, byte_str): - """Generate a new Message instance from this Descriptor and a byte string. - - DEPRECATED: ParseMessage is deprecated because it is using MakeClass(). - Please use MessageFactory.GetPrototype() instead. - - Args: - descriptor: Protobuf Descriptor object - byte_str: Serialized protocol buffer byte string - - Returns: - Newly created protobuf Message object. - """ - result_class = MakeClass(descriptor) - new_msg = result_class() - new_msg.ParseFromString(byte_str) - return new_msg - - -# Deprecated. Please NEVER use reflection.MakeClass(). -def MakeClass(descriptor): - """Construct a class object for a protobuf described by descriptor. - - DEPRECATED: use MessageFactory.GetPrototype() instead. - - Args: - descriptor: A descriptor.Descriptor object describing the protobuf. - Returns: - The Message class object described by the descriptor. - """ - # Original implementation leads to duplicate message classes, which won't play - # well with extensions. Message factory info is also missing. - # Redirect to message_factory. - return symbol_database.Default().GetPrototype(descriptor) diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/service.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/service.py deleted file mode 100644 index 5625246324..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/service.py +++ /dev/null @@ -1,228 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""DEPRECATED: Declares the RPC service interfaces. - -This module declares the abstract interfaces underlying proto2 RPC -services. These are intended to be independent of any particular RPC -implementation, so that proto2 services can be used on top of a variety -of implementations. Starting with version 2.3.0, RPC implementations should -not try to build on these, but should instead provide code generator plugins -which generate code specific to the particular RPC implementation. This way -the generated code can be more appropriate for the implementation in use -and can avoid unnecessary layers of indirection. -""" - -__author__ = 'petar@google.com (Petar Petrov)' - - -class RpcException(Exception): - """Exception raised on failed blocking RPC method call.""" - pass - - -class Service(object): - - """Abstract base interface for protocol-buffer-based RPC services. - - Services themselves are abstract classes (implemented either by servers or as - stubs), but they subclass this base interface. The methods of this - interface can be used to call the methods of the service without knowing - its exact type at compile time (analogous to the Message interface). - """ - - def GetDescriptor(): - """Retrieves this service's descriptor.""" - raise NotImplementedError - - def CallMethod(self, method_descriptor, rpc_controller, - request, done): - """Calls a method of the service specified by method_descriptor. - - If "done" is None then the call is blocking and the response - message will be returned directly. Otherwise the call is asynchronous - and "done" will later be called with the response value. - - In the blocking case, RpcException will be raised on error. - - Preconditions: - - * method_descriptor.service == GetDescriptor - * request is of the exact same classes as returned by - GetRequestClass(method). - * After the call has started, the request must not be modified. - * "rpc_controller" is of the correct type for the RPC implementation being - used by this Service. For stubs, the "correct type" depends on the - RpcChannel which the stub is using. - - Postconditions: - - * "done" will be called when the method is complete. This may be - before CallMethod() returns or it may be at some point in the future. - * If the RPC failed, the response value passed to "done" will be None. - Further details about the failure can be found by querying the - RpcController. - """ - raise NotImplementedError - - def GetRequestClass(self, method_descriptor): - """Returns the class of the request message for the specified method. - - CallMethod() requires that the request is of a particular subclass of - Message. GetRequestClass() gets the default instance of this required - type. - - Example: - method = service.GetDescriptor().FindMethodByName("Foo") - request = stub.GetRequestClass(method)() - request.ParseFromString(input) - service.CallMethod(method, request, callback) - """ - raise NotImplementedError - - def GetResponseClass(self, method_descriptor): - """Returns the class of the response message for the specified method. - - This method isn't really needed, as the RpcChannel's CallMethod constructs - the response protocol message. It's provided anyway in case it is useful - for the caller to know the response type in advance. - """ - raise NotImplementedError - - -class RpcController(object): - - """An RpcController mediates a single method call. - - The primary purpose of the controller is to provide a way to manipulate - settings specific to the RPC implementation and to find out about RPC-level - errors. The methods provided by the RpcController interface are intended - to be a "least common denominator" set of features which we expect all - implementations to support. Specific implementations may provide more - advanced features (e.g. deadline propagation). - """ - - # Client-side methods below - - def Reset(self): - """Resets the RpcController to its initial state. - - After the RpcController has been reset, it may be reused in - a new call. Must not be called while an RPC is in progress. - """ - raise NotImplementedError - - def Failed(self): - """Returns true if the call failed. - - After a call has finished, returns true if the call failed. The possible - reasons for failure depend on the RPC implementation. Failed() must not - be called before a call has finished. If Failed() returns true, the - contents of the response message are undefined. - """ - raise NotImplementedError - - def ErrorText(self): - """If Failed is true, returns a human-readable description of the error.""" - raise NotImplementedError - - def StartCancel(self): - """Initiate cancellation. - - Advises the RPC system that the caller desires that the RPC call be - canceled. The RPC system may cancel it immediately, may wait awhile and - then cancel it, or may not even cancel the call at all. If the call is - canceled, the "done" callback will still be called and the RpcController - will indicate that the call failed at that time. - """ - raise NotImplementedError - - # Server-side methods below - - def SetFailed(self, reason): - """Sets a failure reason. - - Causes Failed() to return true on the client side. "reason" will be - incorporated into the message returned by ErrorText(). If you find - you need to return machine-readable information about failures, you - should incorporate it into your response protocol buffer and should - NOT call SetFailed(). - """ - raise NotImplementedError - - def IsCanceled(self): - """Checks if the client cancelled the RPC. - - If true, indicates that the client canceled the RPC, so the server may - as well give up on replying to it. The server should still call the - final "done" callback. - """ - raise NotImplementedError - - def NotifyOnCancel(self, callback): - """Sets a callback to invoke on cancel. - - Asks that the given callback be called when the RPC is canceled. The - callback will always be called exactly once. If the RPC completes without - being canceled, the callback will be called after completion. If the RPC - has already been canceled when NotifyOnCancel() is called, the callback - will be called immediately. - - NotifyOnCancel() must be called no more than once per request. - """ - raise NotImplementedError - - -class RpcChannel(object): - - """Abstract interface for an RPC channel. - - An RpcChannel represents a communication line to a service which can be used - to call that service's methods. The service may be running on another - machine. Normally, you should not use an RpcChannel directly, but instead - construct a stub {@link Service} wrapping it. Example: - - Example: - RpcChannel channel = rpcImpl.Channel("remotehost.example.com:1234") - RpcController controller = rpcImpl.Controller() - MyService service = MyService_Stub(channel) - service.MyMethod(controller, request, callback) - """ - - def CallMethod(self, method_descriptor, rpc_controller, - request, response_class, done): - """Calls the method identified by the descriptor. - - Call the given method of the remote service. The signature of this - procedure looks the same as Service.CallMethod(), but the requirements - are less strict in one important way: the request object doesn't have to - be of any specific class as long as its descriptor is method.input_type. - """ - raise NotImplementedError diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/service_reflection.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/service_reflection.py deleted file mode 100644 index f82ab7145a..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/service_reflection.py +++ /dev/null @@ -1,295 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Contains metaclasses used to create protocol service and service stub -classes from ServiceDescriptor objects at runtime. - -The GeneratedServiceType and GeneratedServiceStubType metaclasses are used to -inject all useful functionality into the classes output by the protocol -compiler at compile-time. -""" - -__author__ = 'petar@google.com (Petar Petrov)' - - -class GeneratedServiceType(type): - - """Metaclass for service classes created at runtime from ServiceDescriptors. - - Implementations for all methods described in the Service class are added here - by this class. We also create properties to allow getting/setting all fields - in the protocol message. - - The protocol compiler currently uses this metaclass to create protocol service - classes at runtime. Clients can also manually create their own classes at - runtime, as in this example:: - - mydescriptor = ServiceDescriptor(.....) - class MyProtoService(service.Service): - __metaclass__ = GeneratedServiceType - DESCRIPTOR = mydescriptor - myservice_instance = MyProtoService() - # ... - """ - - _DESCRIPTOR_KEY = 'DESCRIPTOR' - - def __init__(cls, name, bases, dictionary): - """Creates a message service class. - - Args: - name: Name of the class (ignored, but required by the metaclass - protocol). - bases: Base classes of the class being constructed. - dictionary: The class dictionary of the class being constructed. - dictionary[_DESCRIPTOR_KEY] must contain a ServiceDescriptor object - describing this protocol service type. - """ - # Don't do anything if this class doesn't have a descriptor. This happens - # when a service class is subclassed. - if GeneratedServiceType._DESCRIPTOR_KEY not in dictionary: - return - - descriptor = dictionary[GeneratedServiceType._DESCRIPTOR_KEY] - service_builder = _ServiceBuilder(descriptor) - service_builder.BuildService(cls) - cls.DESCRIPTOR = descriptor - - -class GeneratedServiceStubType(GeneratedServiceType): - - """Metaclass for service stubs created at runtime from ServiceDescriptors. - - This class has similar responsibilities as GeneratedServiceType, except that - it creates the service stub classes. - """ - - _DESCRIPTOR_KEY = 'DESCRIPTOR' - - def __init__(cls, name, bases, dictionary): - """Creates a message service stub class. - - Args: - name: Name of the class (ignored, here). - bases: Base classes of the class being constructed. - dictionary: The class dictionary of the class being constructed. - dictionary[_DESCRIPTOR_KEY] must contain a ServiceDescriptor object - describing this protocol service type. - """ - super(GeneratedServiceStubType, cls).__init__(name, bases, dictionary) - # Don't do anything if this class doesn't have a descriptor. This happens - # when a service stub is subclassed. - if GeneratedServiceStubType._DESCRIPTOR_KEY not in dictionary: - return - - descriptor = dictionary[GeneratedServiceStubType._DESCRIPTOR_KEY] - service_stub_builder = _ServiceStubBuilder(descriptor) - service_stub_builder.BuildServiceStub(cls) - - -class _ServiceBuilder(object): - - """This class constructs a protocol service class using a service descriptor. - - Given a service descriptor, this class constructs a class that represents - the specified service descriptor. One service builder instance constructs - exactly one service class. That means all instances of that class share the - same builder. - """ - - def __init__(self, service_descriptor): - """Initializes an instance of the service class builder. - - Args: - service_descriptor: ServiceDescriptor to use when constructing the - service class. - """ - self.descriptor = service_descriptor - - def BuildService(builder, cls): - """Constructs the service class. - - Args: - cls: The class that will be constructed. - """ - - # CallMethod needs to operate with an instance of the Service class. This - # internal wrapper function exists only to be able to pass the service - # instance to the method that does the real CallMethod work. - # Making sure to use exact argument names from the abstract interface in - # service.py to match the type signature - def _WrapCallMethod(self, method_descriptor, rpc_controller, request, done): - return builder._CallMethod(self, method_descriptor, rpc_controller, - request, done) - - def _WrapGetRequestClass(self, method_descriptor): - return builder._GetRequestClass(method_descriptor) - - def _WrapGetResponseClass(self, method_descriptor): - return builder._GetResponseClass(method_descriptor) - - builder.cls = cls - cls.CallMethod = _WrapCallMethod - cls.GetDescriptor = staticmethod(lambda: builder.descriptor) - cls.GetDescriptor.__doc__ = 'Returns the service descriptor.' - cls.GetRequestClass = _WrapGetRequestClass - cls.GetResponseClass = _WrapGetResponseClass - for method in builder.descriptor.methods: - setattr(cls, method.name, builder._GenerateNonImplementedMethod(method)) - - def _CallMethod(self, srvc, method_descriptor, - rpc_controller, request, callback): - """Calls the method described by a given method descriptor. - - Args: - srvc: Instance of the service for which this method is called. - method_descriptor: Descriptor that represent the method to call. - rpc_controller: RPC controller to use for this method's execution. - request: Request protocol message. - callback: A callback to invoke after the method has completed. - """ - if method_descriptor.containing_service != self.descriptor: - raise RuntimeError( - 'CallMethod() given method descriptor for wrong service type.') - method = getattr(srvc, method_descriptor.name) - return method(rpc_controller, request, callback) - - def _GetRequestClass(self, method_descriptor): - """Returns the class of the request protocol message. - - Args: - method_descriptor: Descriptor of the method for which to return the - request protocol message class. - - Returns: - A class that represents the input protocol message of the specified - method. - """ - if method_descriptor.containing_service != self.descriptor: - raise RuntimeError( - 'GetRequestClass() given method descriptor for wrong service type.') - return method_descriptor.input_type._concrete_class - - def _GetResponseClass(self, method_descriptor): - """Returns the class of the response protocol message. - - Args: - method_descriptor: Descriptor of the method for which to return the - response protocol message class. - - Returns: - A class that represents the output protocol message of the specified - method. - """ - if method_descriptor.containing_service != self.descriptor: - raise RuntimeError( - 'GetResponseClass() given method descriptor for wrong service type.') - return method_descriptor.output_type._concrete_class - - def _GenerateNonImplementedMethod(self, method): - """Generates and returns a method that can be set for a service methods. - - Args: - method: Descriptor of the service method for which a method is to be - generated. - - Returns: - A method that can be added to the service class. - """ - return lambda inst, rpc_controller, request, callback: ( - self._NonImplementedMethod(method.name, rpc_controller, callback)) - - def _NonImplementedMethod(self, method_name, rpc_controller, callback): - """The body of all methods in the generated service class. - - Args: - method_name: Name of the method being executed. - rpc_controller: RPC controller used to execute this method. - callback: A callback which will be invoked when the method finishes. - """ - rpc_controller.SetFailed('Method %s not implemented.' % method_name) - callback(None) - - -class _ServiceStubBuilder(object): - - """Constructs a protocol service stub class using a service descriptor. - - Given a service descriptor, this class constructs a suitable stub class. - A stub is just a type-safe wrapper around an RpcChannel which emulates a - local implementation of the service. - - One service stub builder instance constructs exactly one class. It means all - instances of that class share the same service stub builder. - """ - - def __init__(self, service_descriptor): - """Initializes an instance of the service stub class builder. - - Args: - service_descriptor: ServiceDescriptor to use when constructing the - stub class. - """ - self.descriptor = service_descriptor - - def BuildServiceStub(self, cls): - """Constructs the stub class. - - Args: - cls: The class that will be constructed. - """ - - def _ServiceStubInit(stub, rpc_channel): - stub.rpc_channel = rpc_channel - self.cls = cls - cls.__init__ = _ServiceStubInit - for method in self.descriptor.methods: - setattr(cls, method.name, self._GenerateStubMethod(method)) - - def _GenerateStubMethod(self, method): - return (lambda inst, rpc_controller, request, callback=None: - self._StubMethod(inst, method, rpc_controller, request, callback)) - - def _StubMethod(self, stub, method_descriptor, - rpc_controller, request, callback): - """The body of all service methods in the generated stub class. - - Args: - stub: Stub instance. - method_descriptor: Descriptor of the invoked method. - rpc_controller: Rpc controller to execute the method. - request: Request protocol message. - callback: A callback to execute when the method finishes. - Returns: - Response message (in case of blocking call). - """ - return stub.rpc_channel.CallMethod( - method_descriptor, rpc_controller, request, - method_descriptor.output_type._concrete_class, callback) diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/source_context_pb2.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/source_context_pb2.py deleted file mode 100644 index 30cca2e06e..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/source_context_pb2.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/source_context.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$google/protobuf/source_context.proto\x12\x0fgoogle.protobuf\"\"\n\rSourceContext\x12\x11\n\tfile_name\x18\x01 \x01(\tB\x8a\x01\n\x13\x63om.google.protobufB\x12SourceContextProtoP\x01Z6google.golang.org/protobuf/types/known/sourcecontextpb\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.source_context_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.google.protobufB\022SourceContextProtoP\001Z6google.golang.org/protobuf/types/known/sourcecontextpb\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' - _SOURCECONTEXT._serialized_start=57 - _SOURCECONTEXT._serialized_end=91 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/struct_pb2.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/struct_pb2.py deleted file mode 100644 index 149728ca08..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/struct_pb2.py +++ /dev/null @@ -1,36 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/struct.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1cgoogle/protobuf/struct.proto\x12\x0fgoogle.protobuf\"\x84\x01\n\x06Struct\x12\x33\n\x06\x66ields\x18\x01 \x03(\x0b\x32#.google.protobuf.Struct.FieldsEntry\x1a\x45\n\x0b\x46ieldsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12%\n\x05value\x18\x02 \x01(\x0b\x32\x16.google.protobuf.Value:\x02\x38\x01\"\xea\x01\n\x05Value\x12\x30\n\nnull_value\x18\x01 \x01(\x0e\x32\x1a.google.protobuf.NullValueH\x00\x12\x16\n\x0cnumber_value\x18\x02 \x01(\x01H\x00\x12\x16\n\x0cstring_value\x18\x03 \x01(\tH\x00\x12\x14\n\nbool_value\x18\x04 \x01(\x08H\x00\x12/\n\x0cstruct_value\x18\x05 \x01(\x0b\x32\x17.google.protobuf.StructH\x00\x12\x30\n\nlist_value\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.ListValueH\x00\x42\x06\n\x04kind\"3\n\tListValue\x12&\n\x06values\x18\x01 \x03(\x0b\x32\x16.google.protobuf.Value*\x1b\n\tNullValue\x12\x0e\n\nNULL_VALUE\x10\x00\x42\x7f\n\x13\x63om.google.protobufB\x0bStructProtoP\x01Z/google.golang.org/protobuf/types/known/structpb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.struct_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.google.protobufB\013StructProtoP\001Z/google.golang.org/protobuf/types/known/structpb\370\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' - _STRUCT_FIELDSENTRY._options = None - _STRUCT_FIELDSENTRY._serialized_options = b'8\001' - _NULLVALUE._serialized_start=474 - _NULLVALUE._serialized_end=501 - _STRUCT._serialized_start=50 - _STRUCT._serialized_end=182 - _STRUCT_FIELDSENTRY._serialized_start=113 - _STRUCT_FIELDSENTRY._serialized_end=182 - _VALUE._serialized_start=185 - _VALUE._serialized_end=419 - _LISTVALUE._serialized_start=421 - _LISTVALUE._serialized_end=472 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/symbol_database.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/symbol_database.py deleted file mode 100644 index fdcf8cf06c..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/symbol_database.py +++ /dev/null @@ -1,194 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""A database of Python protocol buffer generated symbols. - -SymbolDatabase is the MessageFactory for messages generated at compile time, -and makes it easy to create new instances of a registered type, given only the -type's protocol buffer symbol name. - -Example usage:: - - db = symbol_database.SymbolDatabase() - - # Register symbols of interest, from one or multiple files. - db.RegisterFileDescriptor(my_proto_pb2.DESCRIPTOR) - db.RegisterMessage(my_proto_pb2.MyMessage) - db.RegisterEnumDescriptor(my_proto_pb2.MyEnum.DESCRIPTOR) - - # The database can be used as a MessageFactory, to generate types based on - # their name: - types = db.GetMessages(['my_proto.proto']) - my_message_instance = types['MyMessage']() - - # The database's underlying descriptor pool can be queried, so it's not - # necessary to know a type's filename to be able to generate it: - filename = db.pool.FindFileContainingSymbol('MyMessage') - my_message_instance = db.GetMessages([filename])['MyMessage']() - - # This functionality is also provided directly via a convenience method: - my_message_instance = db.GetSymbol('MyMessage')() -""" - - -from google.protobuf.internal import api_implementation -from google.protobuf import descriptor_pool -from google.protobuf import message_factory - - -class SymbolDatabase(message_factory.MessageFactory): - """A database of Python generated symbols.""" - - def RegisterMessage(self, message): - """Registers the given message type in the local database. - - Calls to GetSymbol() and GetMessages() will return messages registered here. - - Args: - message: A :class:`google.protobuf.message.Message` subclass (or - instance); its descriptor will be registered. - - Returns: - The provided message. - """ - - desc = message.DESCRIPTOR - self._classes[desc] = message - self.RegisterMessageDescriptor(desc) - return message - - def RegisterMessageDescriptor(self, message_descriptor): - """Registers the given message descriptor in the local database. - - Args: - message_descriptor (Descriptor): the message descriptor to add. - """ - if api_implementation.Type() == 'python': - # pylint: disable=protected-access - self.pool._AddDescriptor(message_descriptor) - - def RegisterEnumDescriptor(self, enum_descriptor): - """Registers the given enum descriptor in the local database. - - Args: - enum_descriptor (EnumDescriptor): The enum descriptor to register. - - Returns: - EnumDescriptor: The provided descriptor. - """ - if api_implementation.Type() == 'python': - # pylint: disable=protected-access - self.pool._AddEnumDescriptor(enum_descriptor) - return enum_descriptor - - def RegisterServiceDescriptor(self, service_descriptor): - """Registers the given service descriptor in the local database. - - Args: - service_descriptor (ServiceDescriptor): the service descriptor to - register. - """ - if api_implementation.Type() == 'python': - # pylint: disable=protected-access - self.pool._AddServiceDescriptor(service_descriptor) - - def RegisterFileDescriptor(self, file_descriptor): - """Registers the given file descriptor in the local database. - - Args: - file_descriptor (FileDescriptor): The file descriptor to register. - """ - if api_implementation.Type() == 'python': - # pylint: disable=protected-access - self.pool._InternalAddFileDescriptor(file_descriptor) - - def GetSymbol(self, symbol): - """Tries to find a symbol in the local database. - - Currently, this method only returns message.Message instances, however, if - may be extended in future to support other symbol types. - - Args: - symbol (str): a protocol buffer symbol. - - Returns: - A Python class corresponding to the symbol. - - Raises: - KeyError: if the symbol could not be found. - """ - - return self._classes[self.pool.FindMessageTypeByName(symbol)] - - def GetMessages(self, files): - # TODO(amauryfa): Fix the differences with MessageFactory. - """Gets all registered messages from a specified file. - - Only messages already created and registered will be returned; (this is the - case for imported _pb2 modules) - But unlike MessageFactory, this version also returns already defined nested - messages, but does not register any message extensions. - - Args: - files (list[str]): The file names to extract messages from. - - Returns: - A dictionary mapping proto names to the message classes. - - Raises: - KeyError: if a file could not be found. - """ - - def _GetAllMessages(desc): - """Walk a message Descriptor and recursively yields all message names.""" - yield desc - for msg_desc in desc.nested_types: - for nested_desc in _GetAllMessages(msg_desc): - yield nested_desc - - result = {} - for file_name in files: - file_desc = self.pool.FindFileByName(file_name) - for msg_desc in file_desc.message_types_by_name.values(): - for desc in _GetAllMessages(msg_desc): - try: - result[desc.full_name] = self._classes[desc] - except KeyError: - # This descriptor has no registered class, skip it. - pass - return result - - -_DEFAULT = SymbolDatabase(pool=descriptor_pool.Default()) - - -def Default(): - """Returns the default SymbolDatabase.""" - return _DEFAULT diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/text_encoding.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/text_encoding.py deleted file mode 100644 index 759cf11f62..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/text_encoding.py +++ /dev/null @@ -1,110 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Encoding related utilities.""" -import re - -_cescape_chr_to_symbol_map = {} -_cescape_chr_to_symbol_map[9] = r'\t' # optional escape -_cescape_chr_to_symbol_map[10] = r'\n' # optional escape -_cescape_chr_to_symbol_map[13] = r'\r' # optional escape -_cescape_chr_to_symbol_map[34] = r'\"' # necessary escape -_cescape_chr_to_symbol_map[39] = r"\'" # optional escape -_cescape_chr_to_symbol_map[92] = r'\\' # necessary escape - -# Lookup table for unicode -_cescape_unicode_to_str = [chr(i) for i in range(0, 256)] -for byte, string in _cescape_chr_to_symbol_map.items(): - _cescape_unicode_to_str[byte] = string - -# Lookup table for non-utf8, with necessary escapes at (o >= 127 or o < 32) -_cescape_byte_to_str = ([r'\%03o' % i for i in range(0, 32)] + - [chr(i) for i in range(32, 127)] + - [r'\%03o' % i for i in range(127, 256)]) -for byte, string in _cescape_chr_to_symbol_map.items(): - _cescape_byte_to_str[byte] = string -del byte, string - - -def CEscape(text, as_utf8): - # type: (...) -> str - """Escape a bytes string for use in an text protocol buffer. - - Args: - text: A byte string to be escaped. - as_utf8: Specifies if result may contain non-ASCII characters. - In Python 3 this allows unescaped non-ASCII Unicode characters. - In Python 2 the return value will be valid UTF-8 rather than only ASCII. - Returns: - Escaped string (str). - """ - # Python's text.encode() 'string_escape' or 'unicode_escape' codecs do not - # satisfy our needs; they encodes unprintable characters using two-digit hex - # escapes whereas our C++ unescaping function allows hex escapes to be any - # length. So, "\0011".encode('string_escape') ends up being "\\x011", which - # will be decoded in C++ as a single-character string with char code 0x11. - text_is_unicode = isinstance(text, str) - if as_utf8 and text_is_unicode: - # We're already unicode, no processing beyond control char escapes. - return text.translate(_cescape_chr_to_symbol_map) - ord_ = ord if text_is_unicode else lambda x: x # bytes iterate as ints. - if as_utf8: - return ''.join(_cescape_unicode_to_str[ord_(c)] for c in text) - return ''.join(_cescape_byte_to_str[ord_(c)] for c in text) - - -_CUNESCAPE_HEX = re.compile(r'(\\+)x([0-9a-fA-F])(?![0-9a-fA-F])') - - -def CUnescape(text): - # type: (str) -> bytes - """Unescape a text string with C-style escape sequences to UTF-8 bytes. - - Args: - text: The data to parse in a str. - Returns: - A byte string. - """ - - def ReplaceHex(m): - # Only replace the match if the number of leading back slashes is odd. i.e. - # the slash itself is not escaped. - if len(m.group(1)) & 1: - return m.group(1) + 'x0' + m.group(2) - return m.group(0) - - # This is required because the 'string_escape' encoding doesn't - # allow single-digit hex escapes (like '\xf'). - result = _CUNESCAPE_HEX.sub(ReplaceHex, text) - - return (result.encode('utf-8') # Make it bytes to allow decode. - .decode('unicode_escape') - # Make it bytes again to return the proper type. - .encode('raw_unicode_escape')) diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/text_format.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/text_format.py deleted file mode 100644 index 412385c26f..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/text_format.py +++ /dev/null @@ -1,1795 +0,0 @@ -# Protocol Buffers - Google's data interchange format -# Copyright 2008 Google Inc. All rights reserved. -# https://developers.google.com/protocol-buffers/ -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Contains routines for printing protocol messages in text format. - -Simple usage example:: - - # Create a proto object and serialize it to a text proto string. - message = my_proto_pb2.MyMessage(foo='bar') - text_proto = text_format.MessageToString(message) - - # Parse a text proto string. - message = text_format.Parse(text_proto, my_proto_pb2.MyMessage()) -""" - -__author__ = 'kenton@google.com (Kenton Varda)' - -# TODO(b/129989314) Import thread contention leads to test failures. -import encodings.raw_unicode_escape # pylint: disable=unused-import -import encodings.unicode_escape # pylint: disable=unused-import -import io -import math -import re - -from google.protobuf.internal import decoder -from google.protobuf.internal import type_checkers -from google.protobuf import descriptor -from google.protobuf import text_encoding - -# pylint: disable=g-import-not-at-top -__all__ = ['MessageToString', 'Parse', 'PrintMessage', 'PrintField', - 'PrintFieldValue', 'Merge', 'MessageToBytes'] - -_INTEGER_CHECKERS = (type_checkers.Uint32ValueChecker(), - type_checkers.Int32ValueChecker(), - type_checkers.Uint64ValueChecker(), - type_checkers.Int64ValueChecker()) -_FLOAT_INFINITY = re.compile('-?inf(?:inity)?f?$', re.IGNORECASE) -_FLOAT_NAN = re.compile('nanf?$', re.IGNORECASE) -_QUOTES = frozenset(("'", '"')) -_ANY_FULL_TYPE_NAME = 'google.protobuf.Any' - - -class Error(Exception): - """Top-level module error for text_format.""" - - -class ParseError(Error): - """Thrown in case of text parsing or tokenizing error.""" - - def __init__(self, message=None, line=None, column=None): - if message is not None and line is not None: - loc = str(line) - if column is not None: - loc += ':{0}'.format(column) - message = '{0} : {1}'.format(loc, message) - if message is not None: - super(ParseError, self).__init__(message) - else: - super(ParseError, self).__init__() - self._line = line - self._column = column - - def GetLine(self): - return self._line - - def GetColumn(self): - return self._column - - -class TextWriter(object): - - def __init__(self, as_utf8): - self._writer = io.StringIO() - - def write(self, val): - return self._writer.write(val) - - def close(self): - return self._writer.close() - - def getvalue(self): - return self._writer.getvalue() - - -def MessageToString( - message, - as_utf8=False, - as_one_line=False, - use_short_repeated_primitives=False, - pointy_brackets=False, - use_index_order=False, - float_format=None, - double_format=None, - use_field_number=False, - descriptor_pool=None, - indent=0, - message_formatter=None, - print_unknown_fields=False, - force_colon=False): - # type: (...) -> str - """Convert protobuf message to text format. - - Double values can be formatted compactly with 15 digits of - precision (which is the most that IEEE 754 "double" can guarantee) - using double_format='.15g'. To ensure that converting to text and back to a - proto will result in an identical value, double_format='.17g' should be used. - - Args: - message: The protocol buffers message. - as_utf8: Return unescaped Unicode for non-ASCII characters. - In Python 3 actual Unicode characters may appear as is in strings. - In Python 2 the return value will be valid UTF-8 rather than only ASCII. - as_one_line: Don't introduce newlines between fields. - use_short_repeated_primitives: Use short repeated format for primitives. - pointy_brackets: If True, use angle brackets instead of curly braces for - nesting. - use_index_order: If True, fields of a proto message will be printed using - the order defined in source code instead of the field number, extensions - will be printed at the end of the message and their relative order is - determined by the extension number. By default, use the field number - order. - float_format (str): If set, use this to specify float field formatting - (per the "Format Specification Mini-Language"); otherwise, shortest float - that has same value in wire will be printed. Also affect double field - if double_format is not set but float_format is set. - double_format (str): If set, use this to specify double field formatting - (per the "Format Specification Mini-Language"); if it is not set but - float_format is set, use float_format. Otherwise, use ``str()`` - use_field_number: If True, print field numbers instead of names. - descriptor_pool (DescriptorPool): Descriptor pool used to resolve Any types. - indent (int): The initial indent level, in terms of spaces, for pretty - print. - message_formatter (function(message, indent, as_one_line) -> unicode|None): - Custom formatter for selected sub-messages (usually based on message - type). Use to pretty print parts of the protobuf for easier diffing. - print_unknown_fields: If True, unknown fields will be printed. - force_colon: If set, a colon will be added after the field name even if the - field is a proto message. - - Returns: - str: A string of the text formatted protocol buffer message. - """ - out = TextWriter(as_utf8) - printer = _Printer( - out, - indent, - as_utf8, - as_one_line, - use_short_repeated_primitives, - pointy_brackets, - use_index_order, - float_format, - double_format, - use_field_number, - descriptor_pool, - message_formatter, - print_unknown_fields=print_unknown_fields, - force_colon=force_colon) - printer.PrintMessage(message) - result = out.getvalue() - out.close() - if as_one_line: - return result.rstrip() - return result - - -def MessageToBytes(message, **kwargs): - # type: (...) -> bytes - """Convert protobuf message to encoded text format. See MessageToString.""" - text = MessageToString(message, **kwargs) - if isinstance(text, bytes): - return text - codec = 'utf-8' if kwargs.get('as_utf8') else 'ascii' - return text.encode(codec) - - -def _IsMapEntry(field): - return (field.type == descriptor.FieldDescriptor.TYPE_MESSAGE and - field.message_type.has_options and - field.message_type.GetOptions().map_entry) - - -def PrintMessage(message, - out, - indent=0, - as_utf8=False, - as_one_line=False, - use_short_repeated_primitives=False, - pointy_brackets=False, - use_index_order=False, - float_format=None, - double_format=None, - use_field_number=False, - descriptor_pool=None, - message_formatter=None, - print_unknown_fields=False, - force_colon=False): - printer = _Printer( - out=out, indent=indent, as_utf8=as_utf8, - as_one_line=as_one_line, - use_short_repeated_primitives=use_short_repeated_primitives, - pointy_brackets=pointy_brackets, - use_index_order=use_index_order, - float_format=float_format, - double_format=double_format, - use_field_number=use_field_number, - descriptor_pool=descriptor_pool, - message_formatter=message_formatter, - print_unknown_fields=print_unknown_fields, - force_colon=force_colon) - printer.PrintMessage(message) - - -def PrintField(field, - value, - out, - indent=0, - as_utf8=False, - as_one_line=False, - use_short_repeated_primitives=False, - pointy_brackets=False, - use_index_order=False, - float_format=None, - double_format=None, - message_formatter=None, - print_unknown_fields=False, - force_colon=False): - """Print a single field name/value pair.""" - printer = _Printer(out, indent, as_utf8, as_one_line, - use_short_repeated_primitives, pointy_brackets, - use_index_order, float_format, double_format, - message_formatter=message_formatter, - print_unknown_fields=print_unknown_fields, - force_colon=force_colon) - printer.PrintField(field, value) - - -def PrintFieldValue(field, - value, - out, - indent=0, - as_utf8=False, - as_one_line=False, - use_short_repeated_primitives=False, - pointy_brackets=False, - use_index_order=False, - float_format=None, - double_format=None, - message_formatter=None, - print_unknown_fields=False, - force_colon=False): - """Print a single field value (not including name).""" - printer = _Printer(out, indent, as_utf8, as_one_line, - use_short_repeated_primitives, pointy_brackets, - use_index_order, float_format, double_format, - message_formatter=message_formatter, - print_unknown_fields=print_unknown_fields, - force_colon=force_colon) - printer.PrintFieldValue(field, value) - - -def _BuildMessageFromTypeName(type_name, descriptor_pool): - """Returns a protobuf message instance. - - Args: - type_name: Fully-qualified protobuf message type name string. - descriptor_pool: DescriptorPool instance. - - Returns: - A Message instance of type matching type_name, or None if the a Descriptor - wasn't found matching type_name. - """ - # pylint: disable=g-import-not-at-top - if descriptor_pool is None: - from google.protobuf import descriptor_pool as pool_mod - descriptor_pool = pool_mod.Default() - from google.protobuf import symbol_database - database = symbol_database.Default() - try: - message_descriptor = descriptor_pool.FindMessageTypeByName(type_name) - except KeyError: - return None - message_type = database.GetPrototype(message_descriptor) - return message_type() - - -# These values must match WireType enum in google/protobuf/wire_format.h. -WIRETYPE_LENGTH_DELIMITED = 2 -WIRETYPE_START_GROUP = 3 - - -class _Printer(object): - """Text format printer for protocol message.""" - - def __init__( - self, - out, - indent=0, - as_utf8=False, - as_one_line=False, - use_short_repeated_primitives=False, - pointy_brackets=False, - use_index_order=False, - float_format=None, - double_format=None, - use_field_number=False, - descriptor_pool=None, - message_formatter=None, - print_unknown_fields=False, - force_colon=False): - """Initialize the Printer. - - Double values can be formatted compactly with 15 digits of precision - (which is the most that IEEE 754 "double" can guarantee) using - double_format='.15g'. To ensure that converting to text and back to a proto - will result in an identical value, double_format='.17g' should be used. - - Args: - out: To record the text format result. - indent: The initial indent level for pretty print. - as_utf8: Return unescaped Unicode for non-ASCII characters. - In Python 3 actual Unicode characters may appear as is in strings. - In Python 2 the return value will be valid UTF-8 rather than ASCII. - as_one_line: Don't introduce newlines between fields. - use_short_repeated_primitives: Use short repeated format for primitives. - pointy_brackets: If True, use angle brackets instead of curly braces for - nesting. - use_index_order: If True, print fields of a proto message using the order - defined in source code instead of the field number. By default, use the - field number order. - float_format: If set, use this to specify float field formatting - (per the "Format Specification Mini-Language"); otherwise, shortest - float that has same value in wire will be printed. Also affect double - field if double_format is not set but float_format is set. - double_format: If set, use this to specify double field formatting - (per the "Format Specification Mini-Language"); if it is not set but - float_format is set, use float_format. Otherwise, str() is used. - use_field_number: If True, print field numbers instead of names. - descriptor_pool: A DescriptorPool used to resolve Any types. - message_formatter: A function(message, indent, as_one_line): unicode|None - to custom format selected sub-messages (usually based on message type). - Use to pretty print parts of the protobuf for easier diffing. - print_unknown_fields: If True, unknown fields will be printed. - force_colon: If set, a colon will be added after the field name even if - the field is a proto message. - """ - self.out = out - self.indent = indent - self.as_utf8 = as_utf8 - self.as_one_line = as_one_line - self.use_short_repeated_primitives = use_short_repeated_primitives - self.pointy_brackets = pointy_brackets - self.use_index_order = use_index_order - self.float_format = float_format - if double_format is not None: - self.double_format = double_format - else: - self.double_format = float_format - self.use_field_number = use_field_number - self.descriptor_pool = descriptor_pool - self.message_formatter = message_formatter - self.print_unknown_fields = print_unknown_fields - self.force_colon = force_colon - - def _TryPrintAsAnyMessage(self, message): - """Serializes if message is a google.protobuf.Any field.""" - if '/' not in message.type_url: - return False - packed_message = _BuildMessageFromTypeName(message.TypeName(), - self.descriptor_pool) - if packed_message: - packed_message.MergeFromString(message.value) - colon = ':' if self.force_colon else '' - self.out.write('%s[%s]%s ' % (self.indent * ' ', message.type_url, colon)) - self._PrintMessageFieldValue(packed_message) - self.out.write(' ' if self.as_one_line else '\n') - return True - else: - return False - - def _TryCustomFormatMessage(self, message): - formatted = self.message_formatter(message, self.indent, self.as_one_line) - if formatted is None: - return False - - out = self.out - out.write(' ' * self.indent) - out.write(formatted) - out.write(' ' if self.as_one_line else '\n') - return True - - def PrintMessage(self, message): - """Convert protobuf message to text format. - - Args: - message: The protocol buffers message. - """ - if self.message_formatter and self._TryCustomFormatMessage(message): - return - if (message.DESCRIPTOR.full_name == _ANY_FULL_TYPE_NAME and - self._TryPrintAsAnyMessage(message)): - return - fields = message.ListFields() - if self.use_index_order: - fields.sort( - key=lambda x: x[0].number if x[0].is_extension else x[0].index) - for field, value in fields: - if _IsMapEntry(field): - for key in sorted(value): - # This is slow for maps with submessage entries because it copies the - # entire tree. Unfortunately this would take significant refactoring - # of this file to work around. - # - # TODO(haberman): refactor and optimize if this becomes an issue. - entry_submsg = value.GetEntryClass()(key=key, value=value[key]) - self.PrintField(field, entry_submsg) - elif field.label == descriptor.FieldDescriptor.LABEL_REPEATED: - if (self.use_short_repeated_primitives - and field.cpp_type != descriptor.FieldDescriptor.CPPTYPE_MESSAGE - and field.cpp_type != descriptor.FieldDescriptor.CPPTYPE_STRING): - self._PrintShortRepeatedPrimitivesValue(field, value) - else: - for element in value: - self.PrintField(field, element) - else: - self.PrintField(field, value) - - if self.print_unknown_fields: - self._PrintUnknownFields(message.UnknownFields()) - - def _PrintUnknownFields(self, unknown_fields): - """Print unknown fields.""" - out = self.out - for field in unknown_fields: - out.write(' ' * self.indent) - out.write(str(field.field_number)) - if field.wire_type == WIRETYPE_START_GROUP: - if self.as_one_line: - out.write(' { ') - else: - out.write(' {\n') - self.indent += 2 - - self._PrintUnknownFields(field.data) - - if self.as_one_line: - out.write('} ') - else: - self.indent -= 2 - out.write(' ' * self.indent + '}\n') - elif field.wire_type == WIRETYPE_LENGTH_DELIMITED: - try: - # If this field is parseable as a Message, it is probably - # an embedded message. - # pylint: disable=protected-access - (embedded_unknown_message, pos) = decoder._DecodeUnknownFieldSet( - memoryview(field.data), 0, len(field.data)) - except Exception: # pylint: disable=broad-except - pos = 0 - - if pos == len(field.data): - if self.as_one_line: - out.write(' { ') - else: - out.write(' {\n') - self.indent += 2 - - self._PrintUnknownFields(embedded_unknown_message) - - if self.as_one_line: - out.write('} ') - else: - self.indent -= 2 - out.write(' ' * self.indent + '}\n') - else: - # A string or bytes field. self.as_utf8 may not work. - out.write(': \"') - out.write(text_encoding.CEscape(field.data, False)) - out.write('\" ' if self.as_one_line else '\"\n') - else: - # varint, fixed32, fixed64 - out.write(': ') - out.write(str(field.data)) - out.write(' ' if self.as_one_line else '\n') - - def _PrintFieldName(self, field): - """Print field name.""" - out = self.out - out.write(' ' * self.indent) - if self.use_field_number: - out.write(str(field.number)) - else: - if field.is_extension: - out.write('[') - if (field.containing_type.GetOptions().message_set_wire_format and - field.type == descriptor.FieldDescriptor.TYPE_MESSAGE and - field.label == descriptor.FieldDescriptor.LABEL_OPTIONAL): - out.write(field.message_type.full_name) - else: - out.write(field.full_name) - out.write(']') - elif field.type == descriptor.FieldDescriptor.TYPE_GROUP: - # For groups, use the capitalized name. - out.write(field.message_type.name) - else: - out.write(field.name) - - if (self.force_colon or - field.cpp_type != descriptor.FieldDescriptor.CPPTYPE_MESSAGE): - # The colon is optional in this case, but our cross-language golden files - # don't include it. Here, the colon is only included if force_colon is - # set to True - out.write(':') - - def PrintField(self, field, value): - """Print a single field name/value pair.""" - self._PrintFieldName(field) - self.out.write(' ') - self.PrintFieldValue(field, value) - self.out.write(' ' if self.as_one_line else '\n') - - def _PrintShortRepeatedPrimitivesValue(self, field, value): - """"Prints short repeated primitives value.""" - # Note: this is called only when value has at least one element. - self._PrintFieldName(field) - self.out.write(' [') - for i in range(len(value) - 1): - self.PrintFieldValue(field, value[i]) - self.out.write(', ') - self.PrintFieldValue(field, value[-1]) - self.out.write(']') - self.out.write(' ' if self.as_one_line else '\n') - - def _PrintMessageFieldValue(self, value): - if self.pointy_brackets: - openb = '<' - closeb = '>' - else: - openb = '{' - closeb = '}' - - if self.as_one_line: - self.out.write('%s ' % openb) - self.PrintMessage(value) - self.out.write(closeb) - else: - self.out.write('%s\n' % openb) - self.indent += 2 - self.PrintMessage(value) - self.indent -= 2 - self.out.write(' ' * self.indent + closeb) - - def PrintFieldValue(self, field, value): - """Print a single field value (not including name). - - For repeated fields, the value should be a single element. - - Args: - field: The descriptor of the field to be printed. - value: The value of the field. - """ - out = self.out - if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: - self._PrintMessageFieldValue(value) - elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_ENUM: - enum_value = field.enum_type.values_by_number.get(value, None) - if enum_value is not None: - out.write(enum_value.name) - else: - out.write(str(value)) - elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_STRING: - out.write('\"') - if isinstance(value, str) and not self.as_utf8: - out_value = value.encode('utf-8') - else: - out_value = value - if field.type == descriptor.FieldDescriptor.TYPE_BYTES: - # We always need to escape all binary data in TYPE_BYTES fields. - out_as_utf8 = False - else: - out_as_utf8 = self.as_utf8 - out.write(text_encoding.CEscape(out_value, out_as_utf8)) - out.write('\"') - elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_BOOL: - if value: - out.write('true') - else: - out.write('false') - elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_FLOAT: - if self.float_format is not None: - out.write('{1:{0}}'.format(self.float_format, value)) - else: - if math.isnan(value): - out.write(str(value)) - else: - out.write(str(type_checkers.ToShortestFloat(value))) - elif (field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_DOUBLE and - self.double_format is not None): - out.write('{1:{0}}'.format(self.double_format, value)) - else: - out.write(str(value)) - - -def Parse(text, - message, - allow_unknown_extension=False, - allow_field_number=False, - descriptor_pool=None, - allow_unknown_field=False): - """Parses a text representation of a protocol message into a message. - - NOTE: for historical reasons this function does not clear the input - message. This is different from what the binary msg.ParseFrom(...) does. - If text contains a field already set in message, the value is appended if the - field is repeated. Otherwise, an error is raised. - - Example:: - - a = MyProto() - a.repeated_field.append('test') - b = MyProto() - - # Repeated fields are combined - text_format.Parse(repr(a), b) - text_format.Parse(repr(a), b) # repeated_field contains ["test", "test"] - - # Non-repeated fields cannot be overwritten - a.singular_field = 1 - b.singular_field = 2 - text_format.Parse(repr(a), b) # ParseError - - # Binary version: - b.ParseFromString(a.SerializeToString()) # repeated_field is now "test" - - Caller is responsible for clearing the message as needed. - - Args: - text (str): Message text representation. - message (Message): A protocol buffer message to merge into. - allow_unknown_extension: if True, skip over missing extensions and keep - parsing - allow_field_number: if True, both field number and field name are allowed. - descriptor_pool (DescriptorPool): Descriptor pool used to resolve Any types. - allow_unknown_field: if True, skip over unknown field and keep - parsing. Avoid to use this option if possible. It may hide some - errors (e.g. spelling error on field name) - - Returns: - Message: The same message passed as argument. - - Raises: - ParseError: On text parsing problems. - """ - return ParseLines(text.split(b'\n' if isinstance(text, bytes) else u'\n'), - message, - allow_unknown_extension, - allow_field_number, - descriptor_pool=descriptor_pool, - allow_unknown_field=allow_unknown_field) - - -def Merge(text, - message, - allow_unknown_extension=False, - allow_field_number=False, - descriptor_pool=None, - allow_unknown_field=False): - """Parses a text representation of a protocol message into a message. - - Like Parse(), but allows repeated values for a non-repeated field, and uses - the last one. This means any non-repeated, top-level fields specified in text - replace those in the message. - - Args: - text (str): Message text representation. - message (Message): A protocol buffer message to merge into. - allow_unknown_extension: if True, skip over missing extensions and keep - parsing - allow_field_number: if True, both field number and field name are allowed. - descriptor_pool (DescriptorPool): Descriptor pool used to resolve Any types. - allow_unknown_field: if True, skip over unknown field and keep - parsing. Avoid to use this option if possible. It may hide some - errors (e.g. spelling error on field name) - - Returns: - Message: The same message passed as argument. - - Raises: - ParseError: On text parsing problems. - """ - return MergeLines( - text.split(b'\n' if isinstance(text, bytes) else u'\n'), - message, - allow_unknown_extension, - allow_field_number, - descriptor_pool=descriptor_pool, - allow_unknown_field=allow_unknown_field) - - -def ParseLines(lines, - message, - allow_unknown_extension=False, - allow_field_number=False, - descriptor_pool=None, - allow_unknown_field=False): - """Parses a text representation of a protocol message into a message. - - See Parse() for caveats. - - Args: - lines: An iterable of lines of a message's text representation. - message: A protocol buffer message to merge into. - allow_unknown_extension: if True, skip over missing extensions and keep - parsing - allow_field_number: if True, both field number and field name are allowed. - descriptor_pool: A DescriptorPool used to resolve Any types. - allow_unknown_field: if True, skip over unknown field and keep - parsing. Avoid to use this option if possible. It may hide some - errors (e.g. spelling error on field name) - - Returns: - The same message passed as argument. - - Raises: - ParseError: On text parsing problems. - """ - parser = _Parser(allow_unknown_extension, - allow_field_number, - descriptor_pool=descriptor_pool, - allow_unknown_field=allow_unknown_field) - return parser.ParseLines(lines, message) - - -def MergeLines(lines, - message, - allow_unknown_extension=False, - allow_field_number=False, - descriptor_pool=None, - allow_unknown_field=False): - """Parses a text representation of a protocol message into a message. - - See Merge() for more details. - - Args: - lines: An iterable of lines of a message's text representation. - message: A protocol buffer message to merge into. - allow_unknown_extension: if True, skip over missing extensions and keep - parsing - allow_field_number: if True, both field number and field name are allowed. - descriptor_pool: A DescriptorPool used to resolve Any types. - allow_unknown_field: if True, skip over unknown field and keep - parsing. Avoid to use this option if possible. It may hide some - errors (e.g. spelling error on field name) - - Returns: - The same message passed as argument. - - Raises: - ParseError: On text parsing problems. - """ - parser = _Parser(allow_unknown_extension, - allow_field_number, - descriptor_pool=descriptor_pool, - allow_unknown_field=allow_unknown_field) - return parser.MergeLines(lines, message) - - -class _Parser(object): - """Text format parser for protocol message.""" - - def __init__(self, - allow_unknown_extension=False, - allow_field_number=False, - descriptor_pool=None, - allow_unknown_field=False): - self.allow_unknown_extension = allow_unknown_extension - self.allow_field_number = allow_field_number - self.descriptor_pool = descriptor_pool - self.allow_unknown_field = allow_unknown_field - - def ParseLines(self, lines, message): - """Parses a text representation of a protocol message into a message.""" - self._allow_multiple_scalars = False - self._ParseOrMerge(lines, message) - return message - - def MergeLines(self, lines, message): - """Merges a text representation of a protocol message into a message.""" - self._allow_multiple_scalars = True - self._ParseOrMerge(lines, message) - return message - - def _ParseOrMerge(self, lines, message): - """Converts a text representation of a protocol message into a message. - - Args: - lines: Lines of a message's text representation. - message: A protocol buffer message to merge into. - - Raises: - ParseError: On text parsing problems. - """ - # Tokenize expects native str lines. - str_lines = ( - line if isinstance(line, str) else line.decode('utf-8') - for line in lines) - tokenizer = Tokenizer(str_lines) - while not tokenizer.AtEnd(): - self._MergeField(tokenizer, message) - - def _MergeField(self, tokenizer, message): - """Merges a single protocol message field into a message. - - Args: - tokenizer: A tokenizer to parse the field name and values. - message: A protocol message to record the data. - - Raises: - ParseError: In case of text parsing problems. - """ - message_descriptor = message.DESCRIPTOR - if (message_descriptor.full_name == _ANY_FULL_TYPE_NAME and - tokenizer.TryConsume('[')): - type_url_prefix, packed_type_name = self._ConsumeAnyTypeUrl(tokenizer) - tokenizer.Consume(']') - tokenizer.TryConsume(':') - if tokenizer.TryConsume('<'): - expanded_any_end_token = '>' - else: - tokenizer.Consume('{') - expanded_any_end_token = '}' - expanded_any_sub_message = _BuildMessageFromTypeName(packed_type_name, - self.descriptor_pool) - if not expanded_any_sub_message: - raise ParseError('Type %s not found in descriptor pool' % - packed_type_name) - while not tokenizer.TryConsume(expanded_any_end_token): - if tokenizer.AtEnd(): - raise tokenizer.ParseErrorPreviousToken('Expected "%s".' % - (expanded_any_end_token,)) - self._MergeField(tokenizer, expanded_any_sub_message) - deterministic = False - - message.Pack(expanded_any_sub_message, - type_url_prefix=type_url_prefix, - deterministic=deterministic) - return - - if tokenizer.TryConsume('['): - name = [tokenizer.ConsumeIdentifier()] - while tokenizer.TryConsume('.'): - name.append(tokenizer.ConsumeIdentifier()) - name = '.'.join(name) - - if not message_descriptor.is_extendable: - raise tokenizer.ParseErrorPreviousToken( - 'Message type "%s" does not have extensions.' % - message_descriptor.full_name) - # pylint: disable=protected-access - field = message.Extensions._FindExtensionByName(name) - # pylint: enable=protected-access - - - if not field: - if self.allow_unknown_extension: - field = None - else: - raise tokenizer.ParseErrorPreviousToken( - 'Extension "%s" not registered. ' - 'Did you import the _pb2 module which defines it? ' - 'If you are trying to place the extension in the MessageSet ' - 'field of another message that is in an Any or MessageSet field, ' - 'that message\'s _pb2 module must be imported as well' % name) - elif message_descriptor != field.containing_type: - raise tokenizer.ParseErrorPreviousToken( - 'Extension "%s" does not extend message type "%s".' % - (name, message_descriptor.full_name)) - - tokenizer.Consume(']') - - else: - name = tokenizer.ConsumeIdentifierOrNumber() - if self.allow_field_number and name.isdigit(): - number = ParseInteger(name, True, True) - field = message_descriptor.fields_by_number.get(number, None) - if not field and message_descriptor.is_extendable: - field = message.Extensions._FindExtensionByNumber(number) - else: - field = message_descriptor.fields_by_name.get(name, None) - - # Group names are expected to be capitalized as they appear in the - # .proto file, which actually matches their type names, not their field - # names. - if not field: - field = message_descriptor.fields_by_name.get(name.lower(), None) - if field and field.type != descriptor.FieldDescriptor.TYPE_GROUP: - field = None - - if (field and field.type == descriptor.FieldDescriptor.TYPE_GROUP and - field.message_type.name != name): - field = None - - if not field and not self.allow_unknown_field: - raise tokenizer.ParseErrorPreviousToken( - 'Message type "%s" has no field named "%s".' % - (message_descriptor.full_name, name)) - - if field: - if not self._allow_multiple_scalars and field.containing_oneof: - # Check if there's a different field set in this oneof. - # Note that we ignore the case if the same field was set before, and we - # apply _allow_multiple_scalars to non-scalar fields as well. - which_oneof = message.WhichOneof(field.containing_oneof.name) - if which_oneof is not None and which_oneof != field.name: - raise tokenizer.ParseErrorPreviousToken( - 'Field "%s" is specified along with field "%s", another member ' - 'of oneof "%s" for message type "%s".' % - (field.name, which_oneof, field.containing_oneof.name, - message_descriptor.full_name)) - - if field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: - tokenizer.TryConsume(':') - merger = self._MergeMessageField - else: - tokenizer.Consume(':') - merger = self._MergeScalarField - - if (field.label == descriptor.FieldDescriptor.LABEL_REPEATED and - tokenizer.TryConsume('[')): - # Short repeated format, e.g. "foo: [1, 2, 3]" - if not tokenizer.TryConsume(']'): - while True: - merger(tokenizer, message, field) - if tokenizer.TryConsume(']'): - break - tokenizer.Consume(',') - - else: - merger(tokenizer, message, field) - - else: # Proto field is unknown. - assert (self.allow_unknown_extension or self.allow_unknown_field) - _SkipFieldContents(tokenizer) - - # For historical reasons, fields may optionally be separated by commas or - # semicolons. - if not tokenizer.TryConsume(','): - tokenizer.TryConsume(';') - - - def _ConsumeAnyTypeUrl(self, tokenizer): - """Consumes a google.protobuf.Any type URL and returns the type name.""" - # Consume "type.googleapis.com/". - prefix = [tokenizer.ConsumeIdentifier()] - tokenizer.Consume('.') - prefix.append(tokenizer.ConsumeIdentifier()) - tokenizer.Consume('.') - prefix.append(tokenizer.ConsumeIdentifier()) - tokenizer.Consume('/') - # Consume the fully-qualified type name. - name = [tokenizer.ConsumeIdentifier()] - while tokenizer.TryConsume('.'): - name.append(tokenizer.ConsumeIdentifier()) - return '.'.join(prefix), '.'.join(name) - - def _MergeMessageField(self, tokenizer, message, field): - """Merges a single scalar field into a message. - - Args: - tokenizer: A tokenizer to parse the field value. - message: The message of which field is a member. - field: The descriptor of the field to be merged. - - Raises: - ParseError: In case of text parsing problems. - """ - is_map_entry = _IsMapEntry(field) - - if tokenizer.TryConsume('<'): - end_token = '>' - else: - tokenizer.Consume('{') - end_token = '}' - - if field.label == descriptor.FieldDescriptor.LABEL_REPEATED: - if field.is_extension: - sub_message = message.Extensions[field].add() - elif is_map_entry: - sub_message = getattr(message, field.name).GetEntryClass()() - else: - sub_message = getattr(message, field.name).add() - else: - if field.is_extension: - if (not self._allow_multiple_scalars and - message.HasExtension(field)): - raise tokenizer.ParseErrorPreviousToken( - 'Message type "%s" should not have multiple "%s" extensions.' % - (message.DESCRIPTOR.full_name, field.full_name)) - sub_message = message.Extensions[field] - else: - # Also apply _allow_multiple_scalars to message field. - # TODO(jieluo): Change to _allow_singular_overwrites. - if (not self._allow_multiple_scalars and - message.HasField(field.name)): - raise tokenizer.ParseErrorPreviousToken( - 'Message type "%s" should not have multiple "%s" fields.' % - (message.DESCRIPTOR.full_name, field.name)) - sub_message = getattr(message, field.name) - sub_message.SetInParent() - - while not tokenizer.TryConsume(end_token): - if tokenizer.AtEnd(): - raise tokenizer.ParseErrorPreviousToken('Expected "%s".' % (end_token,)) - self._MergeField(tokenizer, sub_message) - - if is_map_entry: - value_cpptype = field.message_type.fields_by_name['value'].cpp_type - if value_cpptype == descriptor.FieldDescriptor.CPPTYPE_MESSAGE: - value = getattr(message, field.name)[sub_message.key] - value.CopyFrom(sub_message.value) - else: - getattr(message, field.name)[sub_message.key] = sub_message.value - - @staticmethod - def _IsProto3Syntax(message): - message_descriptor = message.DESCRIPTOR - return (hasattr(message_descriptor, 'syntax') and - message_descriptor.syntax == 'proto3') - - def _MergeScalarField(self, tokenizer, message, field): - """Merges a single scalar field into a message. - - Args: - tokenizer: A tokenizer to parse the field value. - message: A protocol message to record the data. - field: The descriptor of the field to be merged. - - Raises: - ParseError: In case of text parsing problems. - RuntimeError: On runtime errors. - """ - _ = self.allow_unknown_extension - value = None - - if field.type in (descriptor.FieldDescriptor.TYPE_INT32, - descriptor.FieldDescriptor.TYPE_SINT32, - descriptor.FieldDescriptor.TYPE_SFIXED32): - value = _ConsumeInt32(tokenizer) - elif field.type in (descriptor.FieldDescriptor.TYPE_INT64, - descriptor.FieldDescriptor.TYPE_SINT64, - descriptor.FieldDescriptor.TYPE_SFIXED64): - value = _ConsumeInt64(tokenizer) - elif field.type in (descriptor.FieldDescriptor.TYPE_UINT32, - descriptor.FieldDescriptor.TYPE_FIXED32): - value = _ConsumeUint32(tokenizer) - elif field.type in (descriptor.FieldDescriptor.TYPE_UINT64, - descriptor.FieldDescriptor.TYPE_FIXED64): - value = _ConsumeUint64(tokenizer) - elif field.type in (descriptor.FieldDescriptor.TYPE_FLOAT, - descriptor.FieldDescriptor.TYPE_DOUBLE): - value = tokenizer.ConsumeFloat() - elif field.type == descriptor.FieldDescriptor.TYPE_BOOL: - value = tokenizer.ConsumeBool() - elif field.type == descriptor.FieldDescriptor.TYPE_STRING: - value = tokenizer.ConsumeString() - elif field.type == descriptor.FieldDescriptor.TYPE_BYTES: - value = tokenizer.ConsumeByteString() - elif field.type == descriptor.FieldDescriptor.TYPE_ENUM: - value = tokenizer.ConsumeEnum(field) - else: - raise RuntimeError('Unknown field type %d' % field.type) - - if field.label == descriptor.FieldDescriptor.LABEL_REPEATED: - if field.is_extension: - message.Extensions[field].append(value) - else: - getattr(message, field.name).append(value) - else: - if field.is_extension: - if (not self._allow_multiple_scalars and - not self._IsProto3Syntax(message) and - message.HasExtension(field)): - raise tokenizer.ParseErrorPreviousToken( - 'Message type "%s" should not have multiple "%s" extensions.' % - (message.DESCRIPTOR.full_name, field.full_name)) - else: - message.Extensions[field] = value - else: - duplicate_error = False - if not self._allow_multiple_scalars: - if self._IsProto3Syntax(message): - # Proto3 doesn't represent presence so we try best effort to check - # multiple scalars by compare to default values. - duplicate_error = bool(getattr(message, field.name)) - else: - duplicate_error = message.HasField(field.name) - - if duplicate_error: - raise tokenizer.ParseErrorPreviousToken( - 'Message type "%s" should not have multiple "%s" fields.' % - (message.DESCRIPTOR.full_name, field.name)) - else: - setattr(message, field.name, value) - - -def _SkipFieldContents(tokenizer): - """Skips over contents (value or message) of a field. - - Args: - tokenizer: A tokenizer to parse the field name and values. - """ - # Try to guess the type of this field. - # If this field is not a message, there should be a ":" between the - # field name and the field value and also the field value should not - # start with "{" or "<" which indicates the beginning of a message body. - # If there is no ":" or there is a "{" or "<" after ":", this field has - # to be a message or the input is ill-formed. - if tokenizer.TryConsume(':') and not tokenizer.LookingAt( - '{') and not tokenizer.LookingAt('<'): - _SkipFieldValue(tokenizer) - else: - _SkipFieldMessage(tokenizer) - - -def _SkipField(tokenizer): - """Skips over a complete field (name and value/message). - - Args: - tokenizer: A tokenizer to parse the field name and values. - """ - if tokenizer.TryConsume('['): - # Consume extension name. - tokenizer.ConsumeIdentifier() - while tokenizer.TryConsume('.'): - tokenizer.ConsumeIdentifier() - tokenizer.Consume(']') - else: - tokenizer.ConsumeIdentifierOrNumber() - - _SkipFieldContents(tokenizer) - - # For historical reasons, fields may optionally be separated by commas or - # semicolons. - if not tokenizer.TryConsume(','): - tokenizer.TryConsume(';') - - -def _SkipFieldMessage(tokenizer): - """Skips over a field message. - - Args: - tokenizer: A tokenizer to parse the field name and values. - """ - - if tokenizer.TryConsume('<'): - delimiter = '>' - else: - tokenizer.Consume('{') - delimiter = '}' - - while not tokenizer.LookingAt('>') and not tokenizer.LookingAt('}'): - _SkipField(tokenizer) - - tokenizer.Consume(delimiter) - - -def _SkipFieldValue(tokenizer): - """Skips over a field value. - - Args: - tokenizer: A tokenizer to parse the field name and values. - - Raises: - ParseError: In case an invalid field value is found. - """ - # String/bytes tokens can come in multiple adjacent string literals. - # If we can consume one, consume as many as we can. - if tokenizer.TryConsumeByteString(): - while tokenizer.TryConsumeByteString(): - pass - return - - if (not tokenizer.TryConsumeIdentifier() and - not _TryConsumeInt64(tokenizer) and not _TryConsumeUint64(tokenizer) and - not tokenizer.TryConsumeFloat()): - raise ParseError('Invalid field value: ' + tokenizer.token) - - -class Tokenizer(object): - """Protocol buffer text representation tokenizer. - - This class handles the lower level string parsing by splitting it into - meaningful tokens. - - It was directly ported from the Java protocol buffer API. - """ - - _WHITESPACE = re.compile(r'\s+') - _COMMENT = re.compile(r'(\s*#.*$)', re.MULTILINE) - _WHITESPACE_OR_COMMENT = re.compile(r'(\s|(#.*$))+', re.MULTILINE) - _TOKEN = re.compile('|'.join([ - r'[a-zA-Z_][0-9a-zA-Z_+-]*', # an identifier - r'([0-9+-]|(\.[0-9]))[0-9a-zA-Z_.+-]*', # a number - ] + [ # quoted str for each quote mark - # Avoid backtracking! https://stackoverflow.com/a/844267 - r'{qt}[^{qt}\n\\]*((\\.)+[^{qt}\n\\]*)*({qt}|\\?$)'.format(qt=mark) - for mark in _QUOTES - ])) - - _IDENTIFIER = re.compile(r'[^\d\W]\w*') - _IDENTIFIER_OR_NUMBER = re.compile(r'\w+') - - def __init__(self, lines, skip_comments=True): - self._position = 0 - self._line = -1 - self._column = 0 - self._token_start = None - self.token = '' - self._lines = iter(lines) - self._current_line = '' - self._previous_line = 0 - self._previous_column = 0 - self._more_lines = True - self._skip_comments = skip_comments - self._whitespace_pattern = (skip_comments and self._WHITESPACE_OR_COMMENT - or self._WHITESPACE) - self._SkipWhitespace() - self.NextToken() - - def LookingAt(self, token): - return self.token == token - - def AtEnd(self): - """Checks the end of the text was reached. - - Returns: - True iff the end was reached. - """ - return not self.token - - def _PopLine(self): - while len(self._current_line) <= self._column: - try: - self._current_line = next(self._lines) - except StopIteration: - self._current_line = '' - self._more_lines = False - return - else: - self._line += 1 - self._column = 0 - - def _SkipWhitespace(self): - while True: - self._PopLine() - match = self._whitespace_pattern.match(self._current_line, self._column) - if not match: - break - length = len(match.group(0)) - self._column += length - - def TryConsume(self, token): - """Tries to consume a given piece of text. - - Args: - token: Text to consume. - - Returns: - True iff the text was consumed. - """ - if self.token == token: - self.NextToken() - return True - return False - - def Consume(self, token): - """Consumes a piece of text. - - Args: - token: Text to consume. - - Raises: - ParseError: If the text couldn't be consumed. - """ - if not self.TryConsume(token): - raise self.ParseError('Expected "%s".' % token) - - def ConsumeComment(self): - result = self.token - if not self._COMMENT.match(result): - raise self.ParseError('Expected comment.') - self.NextToken() - return result - - def ConsumeCommentOrTrailingComment(self): - """Consumes a comment, returns a 2-tuple (trailing bool, comment str).""" - - # Tokenizer initializes _previous_line and _previous_column to 0. As the - # tokenizer starts, it looks like there is a previous token on the line. - just_started = self._line == 0 and self._column == 0 - - before_parsing = self._previous_line - comment = self.ConsumeComment() - - # A trailing comment is a comment on the same line than the previous token. - trailing = (self._previous_line == before_parsing - and not just_started) - - return trailing, comment - - def TryConsumeIdentifier(self): - try: - self.ConsumeIdentifier() - return True - except ParseError: - return False - - def ConsumeIdentifier(self): - """Consumes protocol message field identifier. - - Returns: - Identifier string. - - Raises: - ParseError: If an identifier couldn't be consumed. - """ - result = self.token - if not self._IDENTIFIER.match(result): - raise self.ParseError('Expected identifier.') - self.NextToken() - return result - - def TryConsumeIdentifierOrNumber(self): - try: - self.ConsumeIdentifierOrNumber() - return True - except ParseError: - return False - - def ConsumeIdentifierOrNumber(self): - """Consumes protocol message field identifier. - - Returns: - Identifier string. - - Raises: - ParseError: If an identifier couldn't be consumed. - """ - result = self.token - if not self._IDENTIFIER_OR_NUMBER.match(result): - raise self.ParseError('Expected identifier or number, got %s.' % result) - self.NextToken() - return result - - def TryConsumeInteger(self): - try: - self.ConsumeInteger() - return True - except ParseError: - return False - - def ConsumeInteger(self): - """Consumes an integer number. - - Returns: - The integer parsed. - - Raises: - ParseError: If an integer couldn't be consumed. - """ - try: - result = _ParseAbstractInteger(self.token) - except ValueError as e: - raise self.ParseError(str(e)) - self.NextToken() - return result - - def TryConsumeFloat(self): - try: - self.ConsumeFloat() - return True - except ParseError: - return False - - def ConsumeFloat(self): - """Consumes an floating point number. - - Returns: - The number parsed. - - Raises: - ParseError: If a floating point number couldn't be consumed. - """ - try: - result = ParseFloat(self.token) - except ValueError as e: - raise self.ParseError(str(e)) - self.NextToken() - return result - - def ConsumeBool(self): - """Consumes a boolean value. - - Returns: - The bool parsed. - - Raises: - ParseError: If a boolean value couldn't be consumed. - """ - try: - result = ParseBool(self.token) - except ValueError as e: - raise self.ParseError(str(e)) - self.NextToken() - return result - - def TryConsumeByteString(self): - try: - self.ConsumeByteString() - return True - except ParseError: - return False - - def ConsumeString(self): - """Consumes a string value. - - Returns: - The string parsed. - - Raises: - ParseError: If a string value couldn't be consumed. - """ - the_bytes = self.ConsumeByteString() - try: - return str(the_bytes, 'utf-8') - except UnicodeDecodeError as e: - raise self._StringParseError(e) - - def ConsumeByteString(self): - """Consumes a byte array value. - - Returns: - The array parsed (as a string). - - Raises: - ParseError: If a byte array value couldn't be consumed. - """ - the_list = [self._ConsumeSingleByteString()] - while self.token and self.token[0] in _QUOTES: - the_list.append(self._ConsumeSingleByteString()) - return b''.join(the_list) - - def _ConsumeSingleByteString(self): - """Consume one token of a string literal. - - String literals (whether bytes or text) can come in multiple adjacent - tokens which are automatically concatenated, like in C or Python. This - method only consumes one token. - - Returns: - The token parsed. - Raises: - ParseError: When the wrong format data is found. - """ - text = self.token - if len(text) < 1 or text[0] not in _QUOTES: - raise self.ParseError('Expected string but found: %r' % (text,)) - - if len(text) < 2 or text[-1] != text[0]: - raise self.ParseError('String missing ending quote: %r' % (text,)) - - try: - result = text_encoding.CUnescape(text[1:-1]) - except ValueError as e: - raise self.ParseError(str(e)) - self.NextToken() - return result - - def ConsumeEnum(self, field): - try: - result = ParseEnum(field, self.token) - except ValueError as e: - raise self.ParseError(str(e)) - self.NextToken() - return result - - def ParseErrorPreviousToken(self, message): - """Creates and *returns* a ParseError for the previously read token. - - Args: - message: A message to set for the exception. - - Returns: - A ParseError instance. - """ - return ParseError(message, self._previous_line + 1, - self._previous_column + 1) - - def ParseError(self, message): - """Creates and *returns* a ParseError for the current token.""" - return ParseError('\'' + self._current_line + '\': ' + message, - self._line + 1, self._column + 1) - - def _StringParseError(self, e): - return self.ParseError('Couldn\'t parse string: ' + str(e)) - - def NextToken(self): - """Reads the next meaningful token.""" - self._previous_line = self._line - self._previous_column = self._column - - self._column += len(self.token) - self._SkipWhitespace() - - if not self._more_lines: - self.token = '' - return - - match = self._TOKEN.match(self._current_line, self._column) - if not match and not self._skip_comments: - match = self._COMMENT.match(self._current_line, self._column) - if match: - token = match.group(0) - self.token = token - else: - self.token = self._current_line[self._column] - -# Aliased so it can still be accessed by current visibility violators. -# TODO(dbarnett): Migrate violators to textformat_tokenizer. -_Tokenizer = Tokenizer # pylint: disable=invalid-name - - -def _ConsumeInt32(tokenizer): - """Consumes a signed 32bit integer number from tokenizer. - - Args: - tokenizer: A tokenizer used to parse the number. - - Returns: - The integer parsed. - - Raises: - ParseError: If a signed 32bit integer couldn't be consumed. - """ - return _ConsumeInteger(tokenizer, is_signed=True, is_long=False) - - -def _ConsumeUint32(tokenizer): - """Consumes an unsigned 32bit integer number from tokenizer. - - Args: - tokenizer: A tokenizer used to parse the number. - - Returns: - The integer parsed. - - Raises: - ParseError: If an unsigned 32bit integer couldn't be consumed. - """ - return _ConsumeInteger(tokenizer, is_signed=False, is_long=False) - - -def _TryConsumeInt64(tokenizer): - try: - _ConsumeInt64(tokenizer) - return True - except ParseError: - return False - - -def _ConsumeInt64(tokenizer): - """Consumes a signed 32bit integer number from tokenizer. - - Args: - tokenizer: A tokenizer used to parse the number. - - Returns: - The integer parsed. - - Raises: - ParseError: If a signed 32bit integer couldn't be consumed. - """ - return _ConsumeInteger(tokenizer, is_signed=True, is_long=True) - - -def _TryConsumeUint64(tokenizer): - try: - _ConsumeUint64(tokenizer) - return True - except ParseError: - return False - - -def _ConsumeUint64(tokenizer): - """Consumes an unsigned 64bit integer number from tokenizer. - - Args: - tokenizer: A tokenizer used to parse the number. - - Returns: - The integer parsed. - - Raises: - ParseError: If an unsigned 64bit integer couldn't be consumed. - """ - return _ConsumeInteger(tokenizer, is_signed=False, is_long=True) - - -def _ConsumeInteger(tokenizer, is_signed=False, is_long=False): - """Consumes an integer number from tokenizer. - - Args: - tokenizer: A tokenizer used to parse the number. - is_signed: True if a signed integer must be parsed. - is_long: True if a long integer must be parsed. - - Returns: - The integer parsed. - - Raises: - ParseError: If an integer with given characteristics couldn't be consumed. - """ - try: - result = ParseInteger(tokenizer.token, is_signed=is_signed, is_long=is_long) - except ValueError as e: - raise tokenizer.ParseError(str(e)) - tokenizer.NextToken() - return result - - -def ParseInteger(text, is_signed=False, is_long=False): - """Parses an integer. - - Args: - text: The text to parse. - is_signed: True if a signed integer must be parsed. - is_long: True if a long integer must be parsed. - - Returns: - The integer value. - - Raises: - ValueError: Thrown Iff the text is not a valid integer. - """ - # Do the actual parsing. Exception handling is propagated to caller. - result = _ParseAbstractInteger(text) - - # Check if the integer is sane. Exceptions handled by callers. - checker = _INTEGER_CHECKERS[2 * int(is_long) + int(is_signed)] - checker.CheckValue(result) - return result - - -def _ParseAbstractInteger(text): - """Parses an integer without checking size/signedness. - - Args: - text: The text to parse. - - Returns: - The integer value. - - Raises: - ValueError: Thrown Iff the text is not a valid integer. - """ - # Do the actual parsing. Exception handling is propagated to caller. - orig_text = text - c_octal_match = re.match(r'(-?)0(\d+)$', text) - if c_octal_match: - # Python 3 no longer supports 0755 octal syntax without the 'o', so - # we always use the '0o' prefix for multi-digit numbers starting with 0. - text = c_octal_match.group(1) + '0o' + c_octal_match.group(2) - try: - return int(text, 0) - except ValueError: - raise ValueError('Couldn\'t parse integer: %s' % orig_text) - - -def ParseFloat(text): - """Parse a floating point number. - - Args: - text: Text to parse. - - Returns: - The number parsed. - - Raises: - ValueError: If a floating point number couldn't be parsed. - """ - try: - # Assume Python compatible syntax. - return float(text) - except ValueError: - # Check alternative spellings. - if _FLOAT_INFINITY.match(text): - if text[0] == '-': - return float('-inf') - else: - return float('inf') - elif _FLOAT_NAN.match(text): - return float('nan') - else: - # assume '1.0f' format - try: - return float(text.rstrip('f')) - except ValueError: - raise ValueError('Couldn\'t parse float: %s' % text) - - -def ParseBool(text): - """Parse a boolean value. - - Args: - text: Text to parse. - - Returns: - Boolean values parsed - - Raises: - ValueError: If text is not a valid boolean. - """ - if text in ('true', 't', '1', 'True'): - return True - elif text in ('false', 'f', '0', 'False'): - return False - else: - raise ValueError('Expected "true" or "false".') - - -def ParseEnum(field, value): - """Parse an enum value. - - The value can be specified by a number (the enum value), or by - a string literal (the enum name). - - Args: - field: Enum field descriptor. - value: String value. - - Returns: - Enum value number. - - Raises: - ValueError: If the enum value could not be parsed. - """ - enum_descriptor = field.enum_type - try: - number = int(value, 0) - except ValueError: - # Identifier. - enum_value = enum_descriptor.values_by_name.get(value, None) - if enum_value is None: - raise ValueError('Enum type "%s" has no value named %s.' % - (enum_descriptor.full_name, value)) - else: - # Numeric value. - if hasattr(field.file, 'syntax'): - # Attribute is checked for compatibility. - if field.file.syntax == 'proto3': - # Proto3 accept numeric unknown enums. - return number - enum_value = enum_descriptor.values_by_number.get(number, None) - if enum_value is None: - raise ValueError('Enum type "%s" has no value with number %d.' % - (enum_descriptor.full_name, number)) - return enum_value.number diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/timestamp_pb2.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/timestamp_pb2.py deleted file mode 100644 index 558d496941..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/timestamp_pb2.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/timestamp.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1fgoogle/protobuf/timestamp.proto\x12\x0fgoogle.protobuf\"+\n\tTimestamp\x12\x0f\n\x07seconds\x18\x01 \x01(\x03\x12\r\n\x05nanos\x18\x02 \x01(\x05\x42\x85\x01\n\x13\x63om.google.protobufB\x0eTimestampProtoP\x01Z2google.golang.org/protobuf/types/known/timestamppb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.timestamp_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.google.protobufB\016TimestampProtoP\001Z2google.golang.org/protobuf/types/known/timestamppb\370\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' - _TIMESTAMP._serialized_start=52 - _TIMESTAMP._serialized_end=95 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/type_pb2.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/type_pb2.py deleted file mode 100644 index 19903fb6b4..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/type_pb2.py +++ /dev/null @@ -1,42 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/type.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2 -from google.protobuf import source_context_pb2 as google_dot_protobuf_dot_source__context__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1agoogle/protobuf/type.proto\x12\x0fgoogle.protobuf\x1a\x19google/protobuf/any.proto\x1a$google/protobuf/source_context.proto\"\xd7\x01\n\x04Type\x12\x0c\n\x04name\x18\x01 \x01(\t\x12&\n\x06\x66ields\x18\x02 \x03(\x0b\x32\x16.google.protobuf.Field\x12\x0e\n\x06oneofs\x18\x03 \x03(\t\x12(\n\x07options\x18\x04 \x03(\x0b\x32\x17.google.protobuf.Option\x12\x36\n\x0esource_context\x18\x05 \x01(\x0b\x32\x1e.google.protobuf.SourceContext\x12\'\n\x06syntax\x18\x06 \x01(\x0e\x32\x17.google.protobuf.Syntax\"\xd5\x05\n\x05\x46ield\x12)\n\x04kind\x18\x01 \x01(\x0e\x32\x1b.google.protobuf.Field.Kind\x12\x37\n\x0b\x63\x61rdinality\x18\x02 \x01(\x0e\x32\".google.protobuf.Field.Cardinality\x12\x0e\n\x06number\x18\x03 \x01(\x05\x12\x0c\n\x04name\x18\x04 \x01(\t\x12\x10\n\x08type_url\x18\x06 \x01(\t\x12\x13\n\x0boneof_index\x18\x07 \x01(\x05\x12\x0e\n\x06packed\x18\x08 \x01(\x08\x12(\n\x07options\x18\t \x03(\x0b\x32\x17.google.protobuf.Option\x12\x11\n\tjson_name\x18\n \x01(\t\x12\x15\n\rdefault_value\x18\x0b \x01(\t\"\xc8\x02\n\x04Kind\x12\x10\n\x0cTYPE_UNKNOWN\x10\x00\x12\x0f\n\x0bTYPE_DOUBLE\x10\x01\x12\x0e\n\nTYPE_FLOAT\x10\x02\x12\x0e\n\nTYPE_INT64\x10\x03\x12\x0f\n\x0bTYPE_UINT64\x10\x04\x12\x0e\n\nTYPE_INT32\x10\x05\x12\x10\n\x0cTYPE_FIXED64\x10\x06\x12\x10\n\x0cTYPE_FIXED32\x10\x07\x12\r\n\tTYPE_BOOL\x10\x08\x12\x0f\n\x0bTYPE_STRING\x10\t\x12\x0e\n\nTYPE_GROUP\x10\n\x12\x10\n\x0cTYPE_MESSAGE\x10\x0b\x12\x0e\n\nTYPE_BYTES\x10\x0c\x12\x0f\n\x0bTYPE_UINT32\x10\r\x12\r\n\tTYPE_ENUM\x10\x0e\x12\x11\n\rTYPE_SFIXED32\x10\x0f\x12\x11\n\rTYPE_SFIXED64\x10\x10\x12\x0f\n\x0bTYPE_SINT32\x10\x11\x12\x0f\n\x0bTYPE_SINT64\x10\x12\"t\n\x0b\x43\x61rdinality\x12\x17\n\x13\x43\x41RDINALITY_UNKNOWN\x10\x00\x12\x18\n\x14\x43\x41RDINALITY_OPTIONAL\x10\x01\x12\x18\n\x14\x43\x41RDINALITY_REQUIRED\x10\x02\x12\x18\n\x14\x43\x41RDINALITY_REPEATED\x10\x03\"\xce\x01\n\x04\x45num\x12\x0c\n\x04name\x18\x01 \x01(\t\x12-\n\tenumvalue\x18\x02 \x03(\x0b\x32\x1a.google.protobuf.EnumValue\x12(\n\x07options\x18\x03 \x03(\x0b\x32\x17.google.protobuf.Option\x12\x36\n\x0esource_context\x18\x04 \x01(\x0b\x32\x1e.google.protobuf.SourceContext\x12\'\n\x06syntax\x18\x05 \x01(\x0e\x32\x17.google.protobuf.Syntax\"S\n\tEnumValue\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06number\x18\x02 \x01(\x05\x12(\n\x07options\x18\x03 \x03(\x0b\x32\x17.google.protobuf.Option\";\n\x06Option\x12\x0c\n\x04name\x18\x01 \x01(\t\x12#\n\x05value\x18\x02 \x01(\x0b\x32\x14.google.protobuf.Any*.\n\x06Syntax\x12\x11\n\rSYNTAX_PROTO2\x10\x00\x12\x11\n\rSYNTAX_PROTO3\x10\x01\x42{\n\x13\x63om.google.protobufB\tTypeProtoP\x01Z-google.golang.org/protobuf/types/known/typepb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.type_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.google.protobufB\tTypeProtoP\001Z-google.golang.org/protobuf/types/known/typepb\370\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' - _SYNTAX._serialized_start=1413 - _SYNTAX._serialized_end=1459 - _TYPE._serialized_start=113 - _TYPE._serialized_end=328 - _FIELD._serialized_start=331 - _FIELD._serialized_end=1056 - _FIELD_KIND._serialized_start=610 - _FIELD_KIND._serialized_end=938 - _FIELD_CARDINALITY._serialized_start=940 - _FIELD_CARDINALITY._serialized_end=1056 - _ENUM._serialized_start=1059 - _ENUM._serialized_end=1265 - _ENUMVALUE._serialized_start=1267 - _ENUMVALUE._serialized_end=1350 - _OPTION._serialized_start=1352 - _OPTION._serialized_end=1411 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/util/__init__.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/util/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/util/json_format_pb2.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/util/json_format_pb2.py deleted file mode 100644 index 66a5836c82..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/util/json_format_pb2.py +++ /dev/null @@ -1,72 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/util/json_format.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n&google/protobuf/util/json_format.proto\x12\x11protobuf_unittest\"\x89\x01\n\x13TestFlagsAndStrings\x12\t\n\x01\x41\x18\x01 \x02(\x05\x12K\n\rrepeatedgroup\x18\x02 \x03(\n24.protobuf_unittest.TestFlagsAndStrings.RepeatedGroup\x1a\x1a\n\rRepeatedGroup\x12\t\n\x01\x66\x18\x03 \x02(\t\"!\n\x14TestBase64ByteArrays\x12\t\n\x01\x61\x18\x01 \x02(\x0c\"G\n\x12TestJavaScriptJSON\x12\t\n\x01\x61\x18\x01 \x01(\x05\x12\r\n\x05\x66inal\x18\x02 \x01(\x02\x12\n\n\x02in\x18\x03 \x01(\t\x12\x0b\n\x03Var\x18\x04 \x01(\t\"Q\n\x18TestJavaScriptOrderJSON1\x12\t\n\x01\x64\x18\x01 \x01(\x05\x12\t\n\x01\x63\x18\x02 \x01(\x05\x12\t\n\x01x\x18\x03 \x01(\x08\x12\t\n\x01\x62\x18\x04 \x01(\x05\x12\t\n\x01\x61\x18\x05 \x01(\x05\"\x89\x01\n\x18TestJavaScriptOrderJSON2\x12\t\n\x01\x64\x18\x01 \x01(\x05\x12\t\n\x01\x63\x18\x02 \x01(\x05\x12\t\n\x01x\x18\x03 \x01(\x08\x12\t\n\x01\x62\x18\x04 \x01(\x05\x12\t\n\x01\x61\x18\x05 \x01(\x05\x12\x36\n\x01z\x18\x06 \x03(\x0b\x32+.protobuf_unittest.TestJavaScriptOrderJSON1\"$\n\x0cTestLargeInt\x12\t\n\x01\x61\x18\x01 \x02(\x03\x12\t\n\x01\x62\x18\x02 \x02(\x04\"\xa0\x01\n\x0bTestNumbers\x12\x30\n\x01\x61\x18\x01 \x01(\x0e\x32%.protobuf_unittest.TestNumbers.MyType\x12\t\n\x01\x62\x18\x02 \x01(\x05\x12\t\n\x01\x63\x18\x03 \x01(\x02\x12\t\n\x01\x64\x18\x04 \x01(\x08\x12\t\n\x01\x65\x18\x05 \x01(\x01\x12\t\n\x01\x66\x18\x06 \x01(\r\"(\n\x06MyType\x12\x06\n\x02OK\x10\x00\x12\x0b\n\x07WARNING\x10\x01\x12\t\n\x05\x45RROR\x10\x02\"T\n\rTestCamelCase\x12\x14\n\x0cnormal_field\x18\x01 \x01(\t\x12\x15\n\rCAPITAL_FIELD\x18\x02 \x01(\x05\x12\x16\n\x0e\x43\x61melCaseField\x18\x03 \x01(\x05\"|\n\x0bTestBoolMap\x12=\n\x08\x62ool_map\x18\x01 \x03(\x0b\x32+.protobuf_unittest.TestBoolMap.BoolMapEntry\x1a.\n\x0c\x42oolMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\x08\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\"O\n\rTestRecursion\x12\r\n\x05value\x18\x01 \x01(\x05\x12/\n\x05\x63hild\x18\x02 \x01(\x0b\x32 .protobuf_unittest.TestRecursion\"\x86\x01\n\rTestStringMap\x12\x43\n\nstring_map\x18\x01 \x03(\x0b\x32/.protobuf_unittest.TestStringMap.StringMapEntry\x1a\x30\n\x0eStringMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xc4\x01\n\x14TestStringSerializer\x12\x15\n\rscalar_string\x18\x01 \x01(\t\x12\x17\n\x0frepeated_string\x18\x02 \x03(\t\x12J\n\nstring_map\x18\x03 \x03(\x0b\x32\x36.protobuf_unittest.TestStringSerializer.StringMapEntry\x1a\x30\n\x0eStringMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"$\n\x18TestMessageWithExtension*\x08\x08\x64\x10\x80\x80\x80\x80\x02\"z\n\rTestExtension\x12\r\n\x05value\x18\x01 \x01(\t2Z\n\x03\x65xt\x12+.protobuf_unittest.TestMessageWithExtension\x18\x64 \x01(\x0b\x32 .protobuf_unittest.TestExtension\"Q\n\x14TestDefaultEnumValue\x12\x39\n\nenum_value\x18\x01 \x01(\x0e\x32\x1c.protobuf_unittest.EnumValue:\x07\x44\x45\x46\x41ULT*2\n\tEnumValue\x12\x0c\n\x08PROTOCOL\x10\x00\x12\n\n\x06\x42UFFER\x10\x01\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x02') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.util.json_format_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - TestMessageWithExtension.RegisterExtension(_TESTEXTENSION.extensions_by_name['ext']) - - DESCRIPTOR._options = None - _TESTBOOLMAP_BOOLMAPENTRY._options = None - _TESTBOOLMAP_BOOLMAPENTRY._serialized_options = b'8\001' - _TESTSTRINGMAP_STRINGMAPENTRY._options = None - _TESTSTRINGMAP_STRINGMAPENTRY._serialized_options = b'8\001' - _TESTSTRINGSERIALIZER_STRINGMAPENTRY._options = None - _TESTSTRINGSERIALIZER_STRINGMAPENTRY._serialized_options = b'8\001' - _ENUMVALUE._serialized_start=1607 - _ENUMVALUE._serialized_end=1657 - _TESTFLAGSANDSTRINGS._serialized_start=62 - _TESTFLAGSANDSTRINGS._serialized_end=199 - _TESTFLAGSANDSTRINGS_REPEATEDGROUP._serialized_start=173 - _TESTFLAGSANDSTRINGS_REPEATEDGROUP._serialized_end=199 - _TESTBASE64BYTEARRAYS._serialized_start=201 - _TESTBASE64BYTEARRAYS._serialized_end=234 - _TESTJAVASCRIPTJSON._serialized_start=236 - _TESTJAVASCRIPTJSON._serialized_end=307 - _TESTJAVASCRIPTORDERJSON1._serialized_start=309 - _TESTJAVASCRIPTORDERJSON1._serialized_end=390 - _TESTJAVASCRIPTORDERJSON2._serialized_start=393 - _TESTJAVASCRIPTORDERJSON2._serialized_end=530 - _TESTLARGEINT._serialized_start=532 - _TESTLARGEINT._serialized_end=568 - _TESTNUMBERS._serialized_start=571 - _TESTNUMBERS._serialized_end=731 - _TESTNUMBERS_MYTYPE._serialized_start=691 - _TESTNUMBERS_MYTYPE._serialized_end=731 - _TESTCAMELCASE._serialized_start=733 - _TESTCAMELCASE._serialized_end=817 - _TESTBOOLMAP._serialized_start=819 - _TESTBOOLMAP._serialized_end=943 - _TESTBOOLMAP_BOOLMAPENTRY._serialized_start=897 - _TESTBOOLMAP_BOOLMAPENTRY._serialized_end=943 - _TESTRECURSION._serialized_start=945 - _TESTRECURSION._serialized_end=1024 - _TESTSTRINGMAP._serialized_start=1027 - _TESTSTRINGMAP._serialized_end=1161 - _TESTSTRINGMAP_STRINGMAPENTRY._serialized_start=1113 - _TESTSTRINGMAP_STRINGMAPENTRY._serialized_end=1161 - _TESTSTRINGSERIALIZER._serialized_start=1164 - _TESTSTRINGSERIALIZER._serialized_end=1360 - _TESTSTRINGSERIALIZER_STRINGMAPENTRY._serialized_start=1113 - _TESTSTRINGSERIALIZER_STRINGMAPENTRY._serialized_end=1161 - _TESTMESSAGEWITHEXTENSION._serialized_start=1362 - _TESTMESSAGEWITHEXTENSION._serialized_end=1398 - _TESTEXTENSION._serialized_start=1400 - _TESTEXTENSION._serialized_end=1522 - _TESTDEFAULTENUMVALUE._serialized_start=1524 - _TESTDEFAULTENUMVALUE._serialized_end=1605 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/util/json_format_proto3_pb2.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/util/json_format_proto3_pb2.py deleted file mode 100644 index 5498deafa9..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/util/json_format_proto3_pb2.py +++ /dev/null @@ -1,129 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/util/json_format_proto3.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2 -from google.protobuf import duration_pb2 as google_dot_protobuf_dot_duration__pb2 -from google.protobuf import field_mask_pb2 as google_dot_protobuf_dot_field__mask__pb2 -from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2 -from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 -from google.protobuf import wrappers_pb2 as google_dot_protobuf_dot_wrappers__pb2 -from google.protobuf import unittest_pb2 as google_dot_protobuf_dot_unittest__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n-google/protobuf/util/json_format_proto3.proto\x12\x06proto3\x1a\x19google/protobuf/any.proto\x1a\x1egoogle/protobuf/duration.proto\x1a google/protobuf/field_mask.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1egoogle/protobuf/wrappers.proto\x1a\x1egoogle/protobuf/unittest.proto\"\x1c\n\x0bMessageType\x12\r\n\x05value\x18\x01 \x01(\x05\"\x94\x05\n\x0bTestMessage\x12\x12\n\nbool_value\x18\x01 \x01(\x08\x12\x13\n\x0bint32_value\x18\x02 \x01(\x05\x12\x13\n\x0bint64_value\x18\x03 \x01(\x03\x12\x14\n\x0cuint32_value\x18\x04 \x01(\r\x12\x14\n\x0cuint64_value\x18\x05 \x01(\x04\x12\x13\n\x0b\x66loat_value\x18\x06 \x01(\x02\x12\x14\n\x0c\x64ouble_value\x18\x07 \x01(\x01\x12\x14\n\x0cstring_value\x18\x08 \x01(\t\x12\x13\n\x0b\x62ytes_value\x18\t \x01(\x0c\x12$\n\nenum_value\x18\n \x01(\x0e\x32\x10.proto3.EnumType\x12*\n\rmessage_value\x18\x0b \x01(\x0b\x32\x13.proto3.MessageType\x12\x1b\n\x13repeated_bool_value\x18\x15 \x03(\x08\x12\x1c\n\x14repeated_int32_value\x18\x16 \x03(\x05\x12\x1c\n\x14repeated_int64_value\x18\x17 \x03(\x03\x12\x1d\n\x15repeated_uint32_value\x18\x18 \x03(\r\x12\x1d\n\x15repeated_uint64_value\x18\x19 \x03(\x04\x12\x1c\n\x14repeated_float_value\x18\x1a \x03(\x02\x12\x1d\n\x15repeated_double_value\x18\x1b \x03(\x01\x12\x1d\n\x15repeated_string_value\x18\x1c \x03(\t\x12\x1c\n\x14repeated_bytes_value\x18\x1d \x03(\x0c\x12-\n\x13repeated_enum_value\x18\x1e \x03(\x0e\x32\x10.proto3.EnumType\x12\x33\n\x16repeated_message_value\x18\x1f \x03(\x0b\x32\x13.proto3.MessageType\"\x8c\x02\n\tTestOneof\x12\x1b\n\x11oneof_int32_value\x18\x01 \x01(\x05H\x00\x12\x1c\n\x12oneof_string_value\x18\x02 \x01(\tH\x00\x12\x1b\n\x11oneof_bytes_value\x18\x03 \x01(\x0cH\x00\x12,\n\x10oneof_enum_value\x18\x04 \x01(\x0e\x32\x10.proto3.EnumTypeH\x00\x12\x32\n\x13oneof_message_value\x18\x05 \x01(\x0b\x32\x13.proto3.MessageTypeH\x00\x12\x36\n\x10oneof_null_value\x18\x06 \x01(\x0e\x32\x1a.google.protobuf.NullValueH\x00\x42\r\n\x0boneof_value\"\xe1\x04\n\x07TestMap\x12.\n\x08\x62ool_map\x18\x01 \x03(\x0b\x32\x1c.proto3.TestMap.BoolMapEntry\x12\x30\n\tint32_map\x18\x02 \x03(\x0b\x32\x1d.proto3.TestMap.Int32MapEntry\x12\x30\n\tint64_map\x18\x03 \x03(\x0b\x32\x1d.proto3.TestMap.Int64MapEntry\x12\x32\n\nuint32_map\x18\x04 \x03(\x0b\x32\x1e.proto3.TestMap.Uint32MapEntry\x12\x32\n\nuint64_map\x18\x05 \x03(\x0b\x32\x1e.proto3.TestMap.Uint64MapEntry\x12\x32\n\nstring_map\x18\x06 \x03(\x0b\x32\x1e.proto3.TestMap.StringMapEntry\x1a.\n\x0c\x42oolMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\x08\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a/\n\rInt32MapEntry\x12\x0b\n\x03key\x18\x01 \x01(\x05\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a/\n\rInt64MapEntry\x12\x0b\n\x03key\x18\x01 \x01(\x03\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a\x30\n\x0eUint32MapEntry\x12\x0b\n\x03key\x18\x01 \x01(\r\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a\x30\n\x0eUint64MapEntry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a\x30\n\x0eStringMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\"\x85\x06\n\rTestNestedMap\x12\x34\n\x08\x62ool_map\x18\x01 \x03(\x0b\x32\".proto3.TestNestedMap.BoolMapEntry\x12\x36\n\tint32_map\x18\x02 \x03(\x0b\x32#.proto3.TestNestedMap.Int32MapEntry\x12\x36\n\tint64_map\x18\x03 \x03(\x0b\x32#.proto3.TestNestedMap.Int64MapEntry\x12\x38\n\nuint32_map\x18\x04 \x03(\x0b\x32$.proto3.TestNestedMap.Uint32MapEntry\x12\x38\n\nuint64_map\x18\x05 \x03(\x0b\x32$.proto3.TestNestedMap.Uint64MapEntry\x12\x38\n\nstring_map\x18\x06 \x03(\x0b\x32$.proto3.TestNestedMap.StringMapEntry\x12\x32\n\x07map_map\x18\x07 \x03(\x0b\x32!.proto3.TestNestedMap.MapMapEntry\x1a.\n\x0c\x42oolMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\x08\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a/\n\rInt32MapEntry\x12\x0b\n\x03key\x18\x01 \x01(\x05\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a/\n\rInt64MapEntry\x12\x0b\n\x03key\x18\x01 \x01(\x03\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a\x30\n\x0eUint32MapEntry\x12\x0b\n\x03key\x18\x01 \x01(\r\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a\x30\n\x0eUint64MapEntry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a\x30\n\x0eStringMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\x1a\x44\n\x0bMapMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12$\n\x05value\x18\x02 \x01(\x0b\x32\x15.proto3.TestNestedMap:\x02\x38\x01\"{\n\rTestStringMap\x12\x38\n\nstring_map\x18\x01 \x03(\x0b\x32$.proto3.TestStringMap.StringMapEntry\x1a\x30\n\x0eStringMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xee\x07\n\x0bTestWrapper\x12.\n\nbool_value\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x30\n\x0bint32_value\x18\x02 \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12\x30\n\x0bint64_value\x18\x03 \x01(\x0b\x32\x1b.google.protobuf.Int64Value\x12\x32\n\x0cuint32_value\x18\x04 \x01(\x0b\x32\x1c.google.protobuf.UInt32Value\x12\x32\n\x0cuint64_value\x18\x05 \x01(\x0b\x32\x1c.google.protobuf.UInt64Value\x12\x30\n\x0b\x66loat_value\x18\x06 \x01(\x0b\x32\x1b.google.protobuf.FloatValue\x12\x32\n\x0c\x64ouble_value\x18\x07 \x01(\x0b\x32\x1c.google.protobuf.DoubleValue\x12\x32\n\x0cstring_value\x18\x08 \x01(\x0b\x32\x1c.google.protobuf.StringValue\x12\x30\n\x0b\x62ytes_value\x18\t \x01(\x0b\x32\x1b.google.protobuf.BytesValue\x12\x37\n\x13repeated_bool_value\x18\x0b \x03(\x0b\x32\x1a.google.protobuf.BoolValue\x12\x39\n\x14repeated_int32_value\x18\x0c \x03(\x0b\x32\x1b.google.protobuf.Int32Value\x12\x39\n\x14repeated_int64_value\x18\r \x03(\x0b\x32\x1b.google.protobuf.Int64Value\x12;\n\x15repeated_uint32_value\x18\x0e \x03(\x0b\x32\x1c.google.protobuf.UInt32Value\x12;\n\x15repeated_uint64_value\x18\x0f \x03(\x0b\x32\x1c.google.protobuf.UInt64Value\x12\x39\n\x14repeated_float_value\x18\x10 \x03(\x0b\x32\x1b.google.protobuf.FloatValue\x12;\n\x15repeated_double_value\x18\x11 \x03(\x0b\x32\x1c.google.protobuf.DoubleValue\x12;\n\x15repeated_string_value\x18\x12 \x03(\x0b\x32\x1c.google.protobuf.StringValue\x12\x39\n\x14repeated_bytes_value\x18\x13 \x03(\x0b\x32\x1b.google.protobuf.BytesValue\"n\n\rTestTimestamp\x12)\n\x05value\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x32\n\x0erepeated_value\x18\x02 \x03(\x0b\x32\x1a.google.protobuf.Timestamp\"k\n\x0cTestDuration\x12(\n\x05value\x18\x01 \x01(\x0b\x32\x19.google.protobuf.Duration\x12\x31\n\x0erepeated_value\x18\x02 \x03(\x0b\x32\x19.google.protobuf.Duration\":\n\rTestFieldMask\x12)\n\x05value\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.FieldMask\"e\n\nTestStruct\x12&\n\x05value\x18\x01 \x01(\x0b\x32\x17.google.protobuf.Struct\x12/\n\x0erepeated_value\x18\x02 \x03(\x0b\x32\x17.google.protobuf.Struct\"\\\n\x07TestAny\x12#\n\x05value\x18\x01 \x01(\x0b\x32\x14.google.protobuf.Any\x12,\n\x0erepeated_value\x18\x02 \x03(\x0b\x32\x14.google.protobuf.Any\"b\n\tTestValue\x12%\n\x05value\x18\x01 \x01(\x0b\x32\x16.google.protobuf.Value\x12.\n\x0erepeated_value\x18\x02 \x03(\x0b\x32\x16.google.protobuf.Value\"n\n\rTestListValue\x12)\n\x05value\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.ListValue\x12\x32\n\x0erepeated_value\x18\x02 \x03(\x0b\x32\x1a.google.protobuf.ListValue\"\x89\x01\n\rTestBoolValue\x12\x12\n\nbool_value\x18\x01 \x01(\x08\x12\x34\n\x08\x62ool_map\x18\x02 \x03(\x0b\x32\".proto3.TestBoolValue.BoolMapEntry\x1a.\n\x0c\x42oolMapEntry\x12\x0b\n\x03key\x18\x01 \x01(\x08\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\"+\n\x12TestCustomJsonName\x12\x15\n\x05value\x18\x01 \x01(\x05R\x06@value\"J\n\x0eTestExtensions\x12\x38\n\nextensions\x18\x01 \x01(\x0b\x32$.protobuf_unittest.TestAllExtensions\"\x84\x01\n\rTestEnumValue\x12%\n\x0b\x65num_value1\x18\x01 \x01(\x0e\x32\x10.proto3.EnumType\x12%\n\x0b\x65num_value2\x18\x02 \x01(\x0e\x32\x10.proto3.EnumType\x12%\n\x0b\x65num_value3\x18\x03 \x01(\x0e\x32\x10.proto3.EnumType*\x1c\n\x08\x45numType\x12\x07\n\x03\x46OO\x10\x00\x12\x07\n\x03\x42\x41R\x10\x01\x42,\n\x18\x63om.google.protobuf.utilB\x10JsonFormatProto3b\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.util.json_format_proto3_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\030com.google.protobuf.utilB\020JsonFormatProto3' - _TESTMAP_BOOLMAPENTRY._options = None - _TESTMAP_BOOLMAPENTRY._serialized_options = b'8\001' - _TESTMAP_INT32MAPENTRY._options = None - _TESTMAP_INT32MAPENTRY._serialized_options = b'8\001' - _TESTMAP_INT64MAPENTRY._options = None - _TESTMAP_INT64MAPENTRY._serialized_options = b'8\001' - _TESTMAP_UINT32MAPENTRY._options = None - _TESTMAP_UINT32MAPENTRY._serialized_options = b'8\001' - _TESTMAP_UINT64MAPENTRY._options = None - _TESTMAP_UINT64MAPENTRY._serialized_options = b'8\001' - _TESTMAP_STRINGMAPENTRY._options = None - _TESTMAP_STRINGMAPENTRY._serialized_options = b'8\001' - _TESTNESTEDMAP_BOOLMAPENTRY._options = None - _TESTNESTEDMAP_BOOLMAPENTRY._serialized_options = b'8\001' - _TESTNESTEDMAP_INT32MAPENTRY._options = None - _TESTNESTEDMAP_INT32MAPENTRY._serialized_options = b'8\001' - _TESTNESTEDMAP_INT64MAPENTRY._options = None - _TESTNESTEDMAP_INT64MAPENTRY._serialized_options = b'8\001' - _TESTNESTEDMAP_UINT32MAPENTRY._options = None - _TESTNESTEDMAP_UINT32MAPENTRY._serialized_options = b'8\001' - _TESTNESTEDMAP_UINT64MAPENTRY._options = None - _TESTNESTEDMAP_UINT64MAPENTRY._serialized_options = b'8\001' - _TESTNESTEDMAP_STRINGMAPENTRY._options = None - _TESTNESTEDMAP_STRINGMAPENTRY._serialized_options = b'8\001' - _TESTNESTEDMAP_MAPMAPENTRY._options = None - _TESTNESTEDMAP_MAPMAPENTRY._serialized_options = b'8\001' - _TESTSTRINGMAP_STRINGMAPENTRY._options = None - _TESTSTRINGMAP_STRINGMAPENTRY._serialized_options = b'8\001' - _TESTBOOLVALUE_BOOLMAPENTRY._options = None - _TESTBOOLVALUE_BOOLMAPENTRY._serialized_options = b'8\001' - _ENUMTYPE._serialized_start=4849 - _ENUMTYPE._serialized_end=4877 - _MESSAGETYPE._serialized_start=277 - _MESSAGETYPE._serialized_end=305 - _TESTMESSAGE._serialized_start=308 - _TESTMESSAGE._serialized_end=968 - _TESTONEOF._serialized_start=971 - _TESTONEOF._serialized_end=1239 - _TESTMAP._serialized_start=1242 - _TESTMAP._serialized_end=1851 - _TESTMAP_BOOLMAPENTRY._serialized_start=1557 - _TESTMAP_BOOLMAPENTRY._serialized_end=1603 - _TESTMAP_INT32MAPENTRY._serialized_start=1605 - _TESTMAP_INT32MAPENTRY._serialized_end=1652 - _TESTMAP_INT64MAPENTRY._serialized_start=1654 - _TESTMAP_INT64MAPENTRY._serialized_end=1701 - _TESTMAP_UINT32MAPENTRY._serialized_start=1703 - _TESTMAP_UINT32MAPENTRY._serialized_end=1751 - _TESTMAP_UINT64MAPENTRY._serialized_start=1753 - _TESTMAP_UINT64MAPENTRY._serialized_end=1801 - _TESTMAP_STRINGMAPENTRY._serialized_start=1803 - _TESTMAP_STRINGMAPENTRY._serialized_end=1851 - _TESTNESTEDMAP._serialized_start=1854 - _TESTNESTEDMAP._serialized_end=2627 - _TESTNESTEDMAP_BOOLMAPENTRY._serialized_start=1557 - _TESTNESTEDMAP_BOOLMAPENTRY._serialized_end=1603 - _TESTNESTEDMAP_INT32MAPENTRY._serialized_start=1605 - _TESTNESTEDMAP_INT32MAPENTRY._serialized_end=1652 - _TESTNESTEDMAP_INT64MAPENTRY._serialized_start=1654 - _TESTNESTEDMAP_INT64MAPENTRY._serialized_end=1701 - _TESTNESTEDMAP_UINT32MAPENTRY._serialized_start=1703 - _TESTNESTEDMAP_UINT32MAPENTRY._serialized_end=1751 - _TESTNESTEDMAP_UINT64MAPENTRY._serialized_start=1753 - _TESTNESTEDMAP_UINT64MAPENTRY._serialized_end=1801 - _TESTNESTEDMAP_STRINGMAPENTRY._serialized_start=1803 - _TESTNESTEDMAP_STRINGMAPENTRY._serialized_end=1851 - _TESTNESTEDMAP_MAPMAPENTRY._serialized_start=2559 - _TESTNESTEDMAP_MAPMAPENTRY._serialized_end=2627 - _TESTSTRINGMAP._serialized_start=2629 - _TESTSTRINGMAP._serialized_end=2752 - _TESTSTRINGMAP_STRINGMAPENTRY._serialized_start=2704 - _TESTSTRINGMAP_STRINGMAPENTRY._serialized_end=2752 - _TESTWRAPPER._serialized_start=2755 - _TESTWRAPPER._serialized_end=3761 - _TESTTIMESTAMP._serialized_start=3763 - _TESTTIMESTAMP._serialized_end=3873 - _TESTDURATION._serialized_start=3875 - _TESTDURATION._serialized_end=3982 - _TESTFIELDMASK._serialized_start=3984 - _TESTFIELDMASK._serialized_end=4042 - _TESTSTRUCT._serialized_start=4044 - _TESTSTRUCT._serialized_end=4145 - _TESTANY._serialized_start=4147 - _TESTANY._serialized_end=4239 - _TESTVALUE._serialized_start=4241 - _TESTVALUE._serialized_end=4339 - _TESTLISTVALUE._serialized_start=4341 - _TESTLISTVALUE._serialized_end=4451 - _TESTBOOLVALUE._serialized_start=4454 - _TESTBOOLVALUE._serialized_end=4591 - _TESTBOOLVALUE_BOOLMAPENTRY._serialized_start=1557 - _TESTBOOLVALUE_BOOLMAPENTRY._serialized_end=1603 - _TESTCUSTOMJSONNAME._serialized_start=4593 - _TESTCUSTOMJSONNAME._serialized_end=4636 - _TESTEXTENSIONS._serialized_start=4638 - _TESTEXTENSIONS._serialized_end=4712 - _TESTENUMVALUE._serialized_start=4715 - _TESTENUMVALUE._serialized_end=4847 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/wrappers_pb2.py b/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/wrappers_pb2.py deleted file mode 100644 index e49eb4c15d..0000000000 --- a/server_addon/nuke/client/ayon_nuke/vendor/google/protobuf/wrappers_pb2.py +++ /dev/null @@ -1,42 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: google/protobuf/wrappers.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1egoogle/protobuf/wrappers.proto\x12\x0fgoogle.protobuf\"\x1c\n\x0b\x44oubleValue\x12\r\n\x05value\x18\x01 \x01(\x01\"\x1b\n\nFloatValue\x12\r\n\x05value\x18\x01 \x01(\x02\"\x1b\n\nInt64Value\x12\r\n\x05value\x18\x01 \x01(\x03\"\x1c\n\x0bUInt64Value\x12\r\n\x05value\x18\x01 \x01(\x04\"\x1b\n\nInt32Value\x12\r\n\x05value\x18\x01 \x01(\x05\"\x1c\n\x0bUInt32Value\x12\r\n\x05value\x18\x01 \x01(\r\"\x1a\n\tBoolValue\x12\r\n\x05value\x18\x01 \x01(\x08\"\x1c\n\x0bStringValue\x12\r\n\x05value\x18\x01 \x01(\t\"\x1b\n\nBytesValue\x12\r\n\x05value\x18\x01 \x01(\x0c\x42\x83\x01\n\x13\x63om.google.protobufB\rWrappersProtoP\x01Z1google.golang.org/protobuf/types/known/wrapperspb\xf8\x01\x01\xa2\x02\x03GPB\xaa\x02\x1eGoogle.Protobuf.WellKnownTypesb\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.protobuf.wrappers_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'\n\023com.google.protobufB\rWrappersProtoP\001Z1google.golang.org/protobuf/types/known/wrapperspb\370\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypes' - _DOUBLEVALUE._serialized_start=51 - _DOUBLEVALUE._serialized_end=79 - _FLOATVALUE._serialized_start=81 - _FLOATVALUE._serialized_end=108 - _INT64VALUE._serialized_start=110 - _INT64VALUE._serialized_end=137 - _UINT64VALUE._serialized_start=139 - _UINT64VALUE._serialized_end=167 - _INT32VALUE._serialized_start=169 - _INT32VALUE._serialized_end=196 - _UINT32VALUE._serialized_start=198 - _UINT32VALUE._serialized_end=226 - _BOOLVALUE._serialized_start=228 - _BOOLVALUE._serialized_end=254 - _STRINGVALUE._serialized_start=256 - _STRINGVALUE._serialized_end=284 - _BYTESVALUE._serialized_start=286 - _BYTESVALUE._serialized_end=313 -# @@protoc_insertion_point(module_scope) diff --git a/server_addon/nuke/client/ayon_nuke/version.py b/server_addon/nuke/client/ayon_nuke/version.py deleted file mode 100644 index 2262afb410..0000000000 --- a/server_addon/nuke/client/ayon_nuke/version.py +++ /dev/null @@ -1,3 +0,0 @@ -# -*- coding: utf-8 -*- -"""Package declaring AYON addon 'nuke' version.""" -__version__ = "0.2.3" diff --git a/server_addon/nuke/package.py b/server_addon/nuke/package.py deleted file mode 100644 index 7347d21b35..0000000000 --- a/server_addon/nuke/package.py +++ /dev/null @@ -1,10 +0,0 @@ -name = "nuke" -title = "Nuke" -version = "0.2.3" - -client_dir = "ayon_nuke" - -ayon_required_addons = { - "core": ">0.3.2", -} -ayon_compatible_addons = {} diff --git a/server_addon/nuke/server/__init__.py b/server_addon/nuke/server/__init__.py deleted file mode 100644 index 0806ea8e87..0000000000 --- a/server_addon/nuke/server/__init__.py +++ /dev/null @@ -1,27 +0,0 @@ -from typing import Type, Any - -from ayon_server.addons import BaseServerAddon - -from .settings import ( - NukeSettings, - DEFAULT_VALUES, - convert_settings_overrides -) - - -class NukeAddon(BaseServerAddon): - settings_model: Type[NukeSettings] = NukeSettings - - async def get_default_settings(self): - settings_model_cls = self.get_settings_model() - return settings_model_cls(**DEFAULT_VALUES) - - async def convert_settings_overrides( - self, - source_version: str, - overrides: dict[str, Any], - ) -> dict[str, Any]: - convert_settings_overrides(source_version, overrides) - # Use super conversion - return await super().convert_settings_overrides( - source_version, overrides) diff --git a/server_addon/nuke/server/settings/__init__.py b/server_addon/nuke/server/settings/__init__.py deleted file mode 100644 index da79b947f7..0000000000 --- a/server_addon/nuke/server/settings/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -from .main import ( - NukeSettings, - DEFAULT_VALUES, -) -from .conversion import convert_settings_overrides - - -__all__ = ( - "NukeSettings", - "DEFAULT_VALUES", - - "convert_settings_overrides", -) diff --git a/server_addon/nuke/server/settings/common.py b/server_addon/nuke/server/settings/common.py deleted file mode 100644 index 2ddbc3ca26..0000000000 --- a/server_addon/nuke/server/settings/common.py +++ /dev/null @@ -1,195 +0,0 @@ -import json -from ayon_server.exceptions import BadRequestException -from ayon_server.settings import BaseSettingsModel, SettingsField -from ayon_server.types import ( - ColorRGBA_float, - ColorRGB_uint8 -) - - -def validate_json_dict(value): - if not value.strip(): - return "{}" - try: - converted_value = json.loads(value) - success = isinstance(converted_value, dict) - except json.JSONDecodeError: - success = False - - if not success: - raise BadRequestException( - "Environment's can't be parsed as json object" - ) - return value - - -class Vector2d(BaseSettingsModel): - _layout = "compact" - - x: float = SettingsField(1.0, title="X") - y: float = SettingsField(1.0, title="Y") - - -class Vector3d(BaseSettingsModel): - _layout = "compact" - - x: float = SettingsField(1.0, title="X") - y: float = SettingsField(1.0, title="Y") - z: float = SettingsField(1.0, title="Z") - - -class Box(BaseSettingsModel): - _layout = "compact" - - x: float = SettingsField(1.0, title="X") - y: float = SettingsField(1.0, title="Y") - r: float = SettingsField(1.0, title="R") - t: float = SettingsField(1.0, title="T") - - -def formatable_knob_type_enum(): - return [ - {"value": "text", "label": "Text"}, - {"value": "number", "label": "Number"}, - {"value": "decimal_number", "label": "Decimal number"}, - {"value": "2d_vector", "label": "2D vector"}, - # "3D vector" - ] - - -class Formatable(BaseSettingsModel): - _layout = "compact" - - template: str = SettingsField( - "", - placeholder="""{{key}} or {{key}};{{key}}""", - title="Template" - ) - to_type: str = SettingsField( - "Text", - title="To Knob type", - enum_resolver=formatable_knob_type_enum, - ) - - -knob_types_enum = [ - {"value": "text", "label": "Text"}, - {"value": "formatable", "label": "Formate from template"}, - {"value": "color_gui", "label": "Color GUI"}, - {"value": "boolean", "label": "Boolean"}, - {"value": "number", "label": "Number"}, - {"value": "decimal_number", "label": "Decimal number"}, - {"value": "vector_2d", "label": "2D vector"}, - {"value": "vector_3d", "label": "3D vector"}, - {"value": "color", "label": "Color"}, - {"value": "box", "label": "Box"}, - {"value": "expression", "label": "Expression"} -] - - -class KnobModel(BaseSettingsModel): - _layout = "expanded" - - type: str = SettingsField( - title="Type", - description="Switch between different knob types", - enum_resolver=lambda: knob_types_enum, - conditionalEnum=True - ) - - name: str = SettingsField( - title="Name", - placeholder="Name" - ) - text: str = SettingsField("", title="Value") - color_gui: ColorRGB_uint8 = SettingsField( - (0, 0, 255), - title="RGB Uint8", - ) - boolean: bool = SettingsField(False, title="Value") - number: int = SettingsField(0, title="Value") - decimal_number: float = SettingsField(0.0, title="Value") - vector_2d: Vector2d = SettingsField( - default_factory=Vector2d, - title="Value" - ) - vector_3d: Vector3d = SettingsField( - default_factory=Vector3d, - title="Value" - ) - color: ColorRGBA_float = SettingsField( - (0.0, 0.0, 1.0, 1.0), - title="RGBA Float" - ) - box: Box = SettingsField( - default_factory=Box, - title="Value" - ) - formatable: Formatable = SettingsField( - default_factory=Formatable, - title="Formatable" - ) - expression: str = SettingsField( - "", - title="Expression" - ) - - -colorspace_types_enum = [ - {"value": "colorspace", "label": "Use Colorspace"}, - {"value": "display_view", "label": "Use Display & View"}, -] - - -class DisplayAndViewProfileModel(BaseSettingsModel): - _layout = "expanded" - - display: str = SettingsField( - "", - title="Display", - description="What display to use", - ) - - view: str = SettingsField( - "", - title="View", - description=( - "What view to use. Anatomy context tokens can " - "be used to dynamically set the value." - ), - ) - - -class ColorspaceConfigurationModel(BaseSettingsModel): - _isGroup: bool = True - - enabled: bool = SettingsField( - False, - title="Enabled", - description=( - "Enable baking target (colorspace or display/view)." - ), - ) - - type: str = SettingsField( - "colorspace", - title="Target baking type", - description="Switch between different knob types", - enum_resolver=lambda: colorspace_types_enum, - conditionalEnum=True, - ) - - colorspace: str = SettingsField( - "", - title="Colorspace", - description=( - "What colorspace name to use. Anatomy context tokens can " - "be used to dynamically set the value." - ), - ) - - display_view: DisplayAndViewProfileModel = SettingsField( - title="Display & View", - description="What display & view to use", - default_factory=DisplayAndViewProfileModel, - ) diff --git a/server_addon/nuke/server/settings/conversion.py b/server_addon/nuke/server/settings/conversion.py deleted file mode 100644 index 2e9e07e354..0000000000 --- a/server_addon/nuke/server/settings/conversion.py +++ /dev/null @@ -1,143 +0,0 @@ -import re -from typing import Any - - -def _get_viewer_config_from_string(input_string): - """Convert string to display and viewer string - - Args: - input_string (str): string with viewer - - Raises: - IndexError: if more then one slash in input string - IndexError: if missing closing bracket - - Returns: - tuple[str]: display, viewer - """ - display = None - viewer = input_string - # check if () or / or \ in name - if "/" in viewer: - split = viewer.split("/") - - # rise if more then one column - if len(split) > 2: - raise IndexError( - "Viewer Input string is not correct. " - f"More then two `/` slashes! {input_string}" - ) - - viewer = split[1] - display = split[0] - elif "(" in viewer: - pattern = r"([\w\d\s\.\-]+).*[(](.*)[)]" - result_ = re.findall(pattern, viewer) - try: - result_ = result_.pop() - display = str(result_[1]).rstrip() - viewer = str(result_[0]).rstrip() - except IndexError as e: - raise IndexError( - "Viewer Input string is not correct. " - f"Missing bracket! {input_string}" - ) from e - - return (display, viewer) - - -def _convert_imageio_baking_0_2_3(overrides): - if "baking" not in overrides: - return - - baking_view_process = overrides["baking"].get("viewerProcess") - - if baking_view_process is None: - return - - display, view = _get_viewer_config_from_string(baking_view_process) - - overrides["baking_target"] = { - "enabled": True, - "type": "display_view", - "display_view": { - "display": display, - "view": view, - }, - } - - -def _convert_viewers_0_2_3(overrides): - if "viewer" not in overrides: - return - - viewer = overrides["viewer"] - - if "viewerProcess" in viewer: - viewer_process = viewer["viewerProcess"] - display, view = _get_viewer_config_from_string(viewer_process) - viewer.update({ - "display": display, - "view": view, - }) - if "output_transform" in viewer: - output_transform = viewer["output_transform"] - display, view = _get_viewer_config_from_string(output_transform) - overrides["monitor"] = { - "display": display, - "view": view, - } - - -def _convert_imageio_configs_0_2_3(overrides): - """Image IO settings had changed. - - 0.2.2. is the latest version using the old way. - """ - if "imageio" not in overrides: - return - - imageio_overrides = overrides["imageio"] - - _convert_imageio_baking_0_2_3(imageio_overrides) - _convert_viewers_0_2_3(imageio_overrides) - - -def _convert_extract_intermediate_files_0_2_3(publish_overrides): - """Extract intermediate files settings had changed. - - 0.2.2. is the latest version using the old way. - """ - # override can be either `display/view` or `view (display)` - if "ExtractReviewIntermediates" in publish_overrides: - extract_review_intermediates = publish_overrides[ - "ExtractReviewIntermediates"] - - for output in extract_review_intermediates.get("outputs", []): - if viewer_process_override := output.get("viewer_process_override"): - display, view = _get_viewer_config_from_string( - viewer_process_override) - - output["colorspace_override"] = { - "enabled": True, - "type": "display_view", - "display_view": { - "display": display, - "view": view, - }, - } - - -def _convert_publish_plugins(overrides): - if "publish" not in overrides: - return - _convert_extract_intermediate_files_0_2_3(overrides["publish"]) - - -def convert_settings_overrides( - source_version: str, - overrides: dict[str, Any], -) -> dict[str, Any]: - _convert_imageio_configs_0_2_3(overrides) - _convert_publish_plugins(overrides) - return overrides diff --git a/server_addon/nuke/server/settings/create_plugins.py b/server_addon/nuke/server/settings/create_plugins.py deleted file mode 100644 index e4a0f9c938..0000000000 --- a/server_addon/nuke/server/settings/create_plugins.py +++ /dev/null @@ -1,225 +0,0 @@ -from pydantic import validator -from ayon_server.settings import ( - BaseSettingsModel, - SettingsField, - ensure_unique_names -) -from .common import KnobModel - - -def instance_attributes_enum(): - """Return create write instance attributes.""" - return [ - {"value": "reviewable", "label": "Reviewable"}, - {"value": "farm_rendering", "label": "Farm rendering"}, - {"value": "use_range_limit", "label": "Use range limit"}, - { - "value": "render_on_farm", - "label": "Render On Farm" - } - ] - - -class PrenodeModel(BaseSettingsModel): - name: str = SettingsField( - title="Node name" - ) - - nodeclass: str = SettingsField( - "", - title="Node class" - ) - dependent: str = SettingsField( - "", - title="Incoming dependency" - ) - - knobs: list[KnobModel] = SettingsField( - default_factory=list, - title="Knobs", - ) - - @validator("knobs") - def ensure_unique_names(cls, value): - """Ensure name fields within the lists have unique names.""" - ensure_unique_names(value) - return value - - -class CreateWriteRenderModel(BaseSettingsModel): - temp_rendering_path_template: str = SettingsField( - title="Temporary rendering path template" - ) - default_variants: list[str] = SettingsField( - title="Default variants", - default_factory=list - ) - instance_attributes: list[str] = SettingsField( - default_factory=list, - enum_resolver=instance_attributes_enum, - title="Instance attributes" - ) - exposed_knobs: list[str] = SettingsField( - title="Write Node Exposed Knobs", - default_factory=list - ) - prenodes: list[PrenodeModel] = SettingsField( - default_factory=list, - title="Preceding nodes", - ) - - @validator("prenodes") - def ensure_unique_names(cls, value): - """Ensure name fields within the lists have unique names.""" - ensure_unique_names(value) - return value - - -class CreateWritePrerenderModel(BaseSettingsModel): - temp_rendering_path_template: str = SettingsField( - title="Temporary rendering path template" - ) - default_variants: list[str] = SettingsField( - title="Default variants", - default_factory=list - ) - instance_attributes: list[str] = SettingsField( - default_factory=list, - enum_resolver=instance_attributes_enum, - title="Instance attributes" - ) - exposed_knobs: list[str] = SettingsField( - title="Write Node Exposed Knobs", - default_factory=list - ) - prenodes: list[PrenodeModel] = SettingsField( - default_factory=list, - title="Preceding nodes", - ) - - @validator("prenodes") - def ensure_unique_names(cls, value): - """Ensure name fields within the lists have unique names.""" - ensure_unique_names(value) - return value - - -class CreateWriteImageModel(BaseSettingsModel): - temp_rendering_path_template: str = SettingsField( - title="Temporary rendering path template" - ) - default_variants: list[str] = SettingsField( - title="Default variants", - default_factory=list - ) - instance_attributes: list[str] = SettingsField( - default_factory=list, - enum_resolver=instance_attributes_enum, - title="Instance attributes" - ) - exposed_knobs: list[str] = SettingsField( - title="Write Node Exposed Knobs", - default_factory=list - ) - prenodes: list[PrenodeModel] = SettingsField( - default_factory=list, - title="Preceding nodes", - ) - - @validator("prenodes") - def ensure_unique_names(cls, value): - """Ensure name fields within the lists have unique names.""" - ensure_unique_names(value) - return value - - -class CreatorPluginsSettings(BaseSettingsModel): - CreateWriteRender: CreateWriteRenderModel = SettingsField( - default_factory=CreateWriteRenderModel, - title="Create Write Render" - ) - CreateWritePrerender: CreateWritePrerenderModel = SettingsField( - default_factory=CreateWritePrerenderModel, - title="Create Write Prerender" - ) - CreateWriteImage: CreateWriteImageModel = SettingsField( - default_factory=CreateWriteImageModel, - title="Create Write Image" - ) - - -DEFAULT_CREATE_SETTINGS = { - "CreateWriteRender": { - "temp_rendering_path_template": "{work}/renders/nuke/{product[name]}/{product[name]}.{frame}.{ext}", - "default_variants": [ - "Main", - "Mask" - ], - "instance_attributes": [ - "reviewable", - "farm_rendering" - ], - "exposed_knobs": [], - "prenodes": [ - { - "name": "Reformat01", - "nodeclass": "Reformat", - "dependent": "", - "knobs": [ - { - "type": "text", - "name": "resize", - "text": "none" - }, - { - "type": "boolean", - "name": "black_outside", - "boolean": True - } - ] - } - ] - }, - "CreateWritePrerender": { - "temp_rendering_path_template": "{work}/renders/nuke/{product[name]}/{product[name]}.{frame}.{ext}", - "default_variants": [ - "Key01", - "Bg01", - "Fg01", - "Branch01", - "Part01" - ], - "instance_attributes": [ - "farm_rendering", - "use_range_limit" - ], - "exposed_knobs": [], - "prenodes": [] - }, - "CreateWriteImage": { - "temp_rendering_path_template": "{work}/renders/nuke/{product[name]}/{product[name]}.{ext}", - "default_variants": [ - "StillFrame", - "MPFrame", - "LayoutFrame" - ], - "instance_attributes": [ - "use_range_limit" - ], - "exposed_knobs": [], - "prenodes": [ - { - "name": "FrameHold01", - "nodeclass": "FrameHold", - "dependent": "", - "knobs": [ - { - "type": "expression", - "name": "first_frame", - "expression": "parent.first" - } - ] - } - ] - } -} diff --git a/server_addon/nuke/server/settings/dirmap.py b/server_addon/nuke/server/settings/dirmap.py deleted file mode 100644 index 3e1bac0739..0000000000 --- a/server_addon/nuke/server/settings/dirmap.py +++ /dev/null @@ -1,33 +0,0 @@ -from ayon_server.settings import BaseSettingsModel, SettingsField - - -class DirmapPathsSubmodel(BaseSettingsModel): - _layout = "compact" - source_path: list[str] = SettingsField( - default_factory=list, - title="Source Paths" - ) - destination_path: list[str] = SettingsField( - default_factory=list, - title="Destination Paths" - ) - - -class DirmapSettings(BaseSettingsModel): - """Nuke color management project settings.""" - _isGroup: bool = True - - enabled: bool = SettingsField(title="enabled") - paths: DirmapPathsSubmodel = SettingsField( - default_factory=DirmapPathsSubmodel, - title="Dirmap Paths" - ) - - -DEFAULT_DIRMAP_SETTINGS = { - "enabled": False, - "paths": { - "source_path": [], - "destination_path": [] - } -} diff --git a/server_addon/nuke/server/settings/general.py b/server_addon/nuke/server/settings/general.py deleted file mode 100644 index d54c725dc1..0000000000 --- a/server_addon/nuke/server/settings/general.py +++ /dev/null @@ -1,41 +0,0 @@ -from ayon_server.settings import BaseSettingsModel, SettingsField - - -class MenuShortcut(BaseSettingsModel): - """Nuke general project settings.""" - - create: str = SettingsField( - title="Create..." - ) - publish: str = SettingsField( - title="Publish..." - ) - load: str = SettingsField( - title="Load..." - ) - manage: str = SettingsField( - title="Manage..." - ) - build_workfile: str = SettingsField( - title="Build Workfile..." - ) - - -class GeneralSettings(BaseSettingsModel): - """Nuke general project settings.""" - - menu: MenuShortcut = SettingsField( - default_factory=MenuShortcut, - title="Menu Shortcuts", - ) - - -DEFAULT_GENERAL_SETTINGS = { - "menu": { - "create": "ctrl+alt+c", - "publish": "ctrl+alt+p", - "load": "ctrl+alt+l", - "manage": "ctrl+alt+m", - "build_workfile": "ctrl+alt+b" - } -} diff --git a/server_addon/nuke/server/settings/gizmo.py b/server_addon/nuke/server/settings/gizmo.py deleted file mode 100644 index ddb56f891c..0000000000 --- a/server_addon/nuke/server/settings/gizmo.py +++ /dev/null @@ -1,79 +0,0 @@ -from ayon_server.settings import ( - BaseSettingsModel, - SettingsField, - MultiplatformPathModel, - MultiplatformPathListModel, -) - - -class SubGizmoItem(BaseSettingsModel): - title: str = SettingsField( - title="Label" - ) - sourcetype: str = SettingsField( - title="Type of usage" - ) - command: str = SettingsField( - title="Python command" - ) - icon: str = SettingsField( - title="Icon Path" - ) - shortcut: str = SettingsField( - title="Hotkey" - ) - - -class GizmoDefinitionItem(BaseSettingsModel): - gizmo_toolbar_path: str = SettingsField( - title="Gizmo Menu" - ) - sub_gizmo_list: list[SubGizmoItem] = SettingsField( - default_factory=list, title="Sub Gizmo List") - - -class GizmoItem(BaseSettingsModel): - """Nuke gizmo item """ - - toolbar_menu_name: str = SettingsField( - title="Toolbar Menu Name" - ) - gizmo_source_dir: MultiplatformPathListModel = SettingsField( - default_factory=MultiplatformPathListModel, - title="Gizmo Directory Path" - ) - toolbar_icon_path: MultiplatformPathModel = SettingsField( - default_factory=MultiplatformPathModel, - title="Toolbar Icon Path" - ) - gizmo_definition: list[GizmoDefinitionItem] = SettingsField( - default_factory=list, title="Gizmo Definition") - - -DEFAULT_GIZMO_ITEM = { - "toolbar_menu_name": "OpenPype Gizmo", - "gizmo_source_dir": { - "windows": [], - "darwin": [], - "linux": [] - }, - "toolbar_icon_path": { - "windows": "", - "darwin": "", - "linux": "" - }, - "gizmo_definition": [ - { - "gizmo_toolbar_path": "/path/to/menu", - "sub_gizmo_list": [ - { - "sourcetype": "python", - "title": "Gizmo Note", - "command": "nuke.nodes.StickyNote(label='You can create your own toolbar menu in the Nuke GizmoMenu of OpenPype')", - "icon": "", - "shortcut": "" - } - ] - } - ] -} diff --git a/server_addon/nuke/server/settings/imageio.py b/server_addon/nuke/server/settings/imageio.py deleted file mode 100644 index a34cb4ab05..0000000000 --- a/server_addon/nuke/server/settings/imageio.py +++ /dev/null @@ -1,354 +0,0 @@ -from typing import Literal -from pydantic import validator -from ayon_server.settings import ( - BaseSettingsModel, - SettingsField, - ensure_unique_names, -) - -from .common import ( - KnobModel, - ColorspaceConfigurationModel, -) - - -class NodesModel(BaseSettingsModel): - _layout = "expanded" - plugins: list[str] = SettingsField( - default_factory=list, - title="Used in plugins" - ) - nuke_node_class: str = SettingsField( - title="Nuke Node Class", - ) - - -class RequiredNodesModel(NodesModel): - knobs: list[KnobModel] = SettingsField( - default_factory=list, - title="Knobs", - ) - - @validator("knobs") - def ensure_unique_names(cls, value): - """Ensure name fields within the lists have unique names.""" - ensure_unique_names(value) - return value - - -class OverrideNodesModel(NodesModel): - subsets: list[str] = SettingsField( - default_factory=list, - title="Subsets" - ) - - knobs: list[KnobModel] = SettingsField( - default_factory=list, - title="Knobs", - ) - - @validator("knobs") - def ensure_unique_names(cls, value): - """Ensure name fields within the lists have unique names.""" - ensure_unique_names(value) - return value - - -class NodesSetting(BaseSettingsModel): - _isGroup: bool = True - - required_nodes: list[RequiredNodesModel] = SettingsField( - title="Plugin required", - default_factory=list - ) - override_nodes: list[OverrideNodesModel] = SettingsField( - title="Plugin's node overrides", - default_factory=list - ) - - -def ocio_configs_switcher_enum(): - return [ - {"value": "nuke-default", "label": "nuke-default"}, - {"value": "spi-vfx", "label": "spi-vfx (11)"}, - {"value": "spi-anim", "label": "spi-anim (11)"}, - {"value": "aces_0.1.1", "label": "aces_0.1.1 (11)"}, - {"value": "aces_0.7.1", "label": "aces_0.7.1 (11)"}, - {"value": "aces_1.0.1", "label": "aces_1.0.1 (11)"}, - {"value": "aces_1.0.3", "label": "aces_1.0.3 (11, 12)"}, - {"value": "aces_1.1", "label": "aces_1.1 (12, 13)"}, - {"value": "aces_1.2", "label": "aces_1.2 (13, 14)"}, - {"value": "studio-config-v1.0.0_aces-v1.3_ocio-v2.1", - "label": "studio-config-v1.0.0_aces-v1.3_ocio-v2.1 (14)"}, - {"value": "cg-config-v1.0.0_aces-v1.3_ocio-v2.1", - "label": "cg-config-v1.0.0_aces-v1.3_ocio-v2.1 (14)"}, - ] - - -class WorkfileColorspaceSettings(BaseSettingsModel): - """Nuke workfile colorspace preset. """ - - _isGroup: bool = True - - color_management: Literal["Nuke", "OCIO"] = SettingsField( - title="Color Management Workflow" - ) - - native_ocio_config: str = SettingsField( - title="Native OpenColorIO Config", - description="Switch between native OCIO configs", - enum_resolver=ocio_configs_switcher_enum, - conditionalEnum=True - ) - - working_space: str = SettingsField( - title="Working Space" - ) - monitor_lut: str = SettingsField( - title="Thumbnails" - ) - monitor_out_lut: str = SettingsField( - title="Monitor Out" - ) - int_8_lut: str = SettingsField( - title="8-bit Files" - ) - int_16_lut: str = SettingsField( - title="16-bit Files" - ) - log_lut: str = SettingsField( - title="Log Files" - ) - float_lut: str = SettingsField( - title="Float Files" - ) - - -class ReadColorspaceRulesItems(BaseSettingsModel): - _layout = "expanded" - - regex: str = SettingsField("", title="Regex expression") - colorspace: str = SettingsField("", title="Colorspace") - - -class RegexInputsModel(BaseSettingsModel): - _isGroup: bool = True - - inputs: list[ReadColorspaceRulesItems] = SettingsField( - default_factory=list, - title="Inputs" - ) - - -class ViewProcessModel(BaseSettingsModel): - _isGroup: bool = True - - display: str = SettingsField( - "", - title="Display", - description="What display to use", - ) - view: str = SettingsField( - "", - title="View", - description=( - "What view to use. Anatomy context tokens can " - "be used to dynamically set the value." - ), - ) - - -class MonitorProcessModel(BaseSettingsModel): - _isGroup: bool = True - - display: str = SettingsField( - "", - title="Display", - description="What display to use", - ) - view: str = SettingsField( - "", - title="View", - description=( - "What view to use. Anatomy context tokens can " - "be used to dynamically set the value." - ), - ) - - -class ImageIOConfigModel(BaseSettingsModel): - """[DEPRECATED] Addon OCIO config settings. Please set the OCIO config - path in the Core addon profiles here - (ayon+settings://core/imageio/ocio_config_profiles). - """ - - override_global_config: bool = SettingsField( - False, - title="Override global OCIO config", - description=( - "DEPRECATED functionality. Please set the OCIO config path in the " - "Core addon profiles here (ayon+settings://core/imageio/" - "ocio_config_profiles)." - ), - ) - filepath: list[str] = SettingsField( - default_factory=list, - title="Config path", - description=( - "DEPRECATED functionality. Please set the OCIO config path in the " - "Core addon profiles here (ayon+settings://core/imageio/" - "ocio_config_profiles)." - ), - ) - - -class ImageIOFileRuleModel(BaseSettingsModel): - name: str = SettingsField("", title="Rule name") - pattern: str = SettingsField("", title="Regex pattern") - colorspace: str = SettingsField("", title="Colorspace name") - ext: str = SettingsField("", title="File extension") - - -class ImageIOFileRulesModel(BaseSettingsModel): - _isGroup: bool = True - - activate_host_rules: bool = SettingsField(False) - rules: list[ImageIOFileRuleModel] = SettingsField( - default_factory=list, - title="Rules" - ) - - @validator("rules") - def validate_unique_outputs(cls, value): - ensure_unique_names(value) - return value - - -class ImageIOSettings(BaseSettingsModel): - """Nuke color management project settings. """ - - activate_host_color_management: bool = SettingsField( - True, title="Enable Color Management") - ocio_config: ImageIOConfigModel = SettingsField( - default_factory=ImageIOConfigModel, - title="OCIO config" - ) - file_rules: ImageIOFileRulesModel = SettingsField( - default_factory=ImageIOFileRulesModel, - title="File Rules" - ) - viewer: ViewProcessModel = SettingsField( - default_factory=ViewProcessModel, - title="Viewer", - description="""Viewer profile is used during - Creation of new viewer node at knob viewerProcess""" - ) - monitor: MonitorProcessModel = SettingsField( - default_factory=MonitorProcessModel, - title="Monitor OUT" - ) - baking_target: ColorspaceConfigurationModel = SettingsField( - default_factory=ColorspaceConfigurationModel, - title="Baking Target Colorspace" - ) - - workfile: WorkfileColorspaceSettings = SettingsField( - default_factory=WorkfileColorspaceSettings, - title="Workfile" - ) - - nodes: NodesSetting = SettingsField( - default_factory=NodesSetting, - title="Nodes" - ) - """# TODO: enhance settings with host api: - - [ ] no need for `inputs` middle part. It can stay - directly on `regex_inputs` - """ - regex_inputs: RegexInputsModel = SettingsField( - default_factory=RegexInputsModel, - title="Assign colorspace to read nodes via rules" - ) - - -DEFAULT_IMAGEIO_SETTINGS = { - "viewer": {"display": "ACES", "view": "sRGB"}, - "monitor": {"display": "ACES", "view": "Rec.709"}, - "baking_target": { - "enabled": True, - "type": "colorspace", - "colorspace": "Output - Rec.709", - }, - "workfile": { - "color_management": "OCIO", - "native_ocio_config": "aces_1.2", - "working_space": "role_scene_linear", - "monitor_lut": "ACES/sRGB", - "monitor_out_lut": "ACES/sRGB", - "int_8_lut": "role_matte_paint", - "int_16_lut": "role_texture_paint", - "log_lut": "role_compositing_log", - "float_lut": "role_scene_linear", - }, - "nodes": { - "required_nodes": [ - { - "plugins": ["CreateWriteRender"], - "nuke_node_class": "Write", - "knobs": [ - {"type": "text", "name": "file_type", "text": "exr"}, - {"type": "text", "name": "datatype", "text": "16 bit half"}, - {"type": "text", "name": "compression", "text": "Zip (1 scanline)"}, - {"type": "boolean", "name": "autocrop", "boolean": True}, - { - "type": "color_gui", - "name": "tile_color", - "color_gui": [186, 35, 35], - }, - {"type": "text", "name": "channels", "text": "rgb"}, - {"type": "text", "name": "colorspace", "text": "scene_linear"}, - {"type": "boolean", "name": "create_directories", "boolean": True}, - ], - }, - { - "plugins": ["CreateWritePrerender"], - "nuke_node_class": "Write", - "knobs": [ - {"type": "text", "name": "file_type", "text": "exr"}, - {"type": "text", "name": "datatype", "text": "16 bit half"}, - {"type": "text", "name": "compression", "text": "Zip (1 scanline)"}, - {"type": "boolean", "name": "autocrop", "boolean": True}, - { - "type": "color_gui", - "name": "tile_color", - "color_gui": [171, 171, 10], - }, - {"type": "text", "name": "channels", "text": "rgb"}, - {"type": "text", "name": "colorspace", "text": "scene_linear"}, - {"type": "boolean", "name": "create_directories", "boolean": True}, - ], - }, - { - "plugins": ["CreateWriteImage"], - "nuke_node_class": "Write", - "knobs": [ - {"type": "text", "name": "file_type", "text": "tiff"}, - {"type": "text", "name": "datatype", "text": "16 bit"}, - {"type": "text", "name": "compression", "text": "Deflate"}, - { - "type": "color_gui", - "name": "tile_color", - "color_gui": [56, 162, 7], - }, - {"type": "text", "name": "channels", "text": "rgb"}, - {"type": "text", "name": "colorspace", "text": "texture_paint"}, - {"type": "boolean", "name": "create_directories", "boolean": True}, - ], - }, - ], - "override_nodes": [], - }, - "regex_inputs": { - "inputs": [{"regex": "(beauty).*(?=.exr)", "colorspace": "linear"}] - }, -} diff --git a/server_addon/nuke/server/settings/loader_plugins.py b/server_addon/nuke/server/settings/loader_plugins.py deleted file mode 100644 index 22cb469e8d..0000000000 --- a/server_addon/nuke/server/settings/loader_plugins.py +++ /dev/null @@ -1,74 +0,0 @@ -from ayon_server.settings import BaseSettingsModel, SettingsField - - -class LoadImageModel(BaseSettingsModel): - enabled: bool = SettingsField( - title="Enabled" - ) - representations_include: list[str] = SettingsField( - default_factory=list, - title="Include representations" - ) - - node_name_template: str = SettingsField( - title="Read node name template" - ) - - -class LoadClipOptionsModel(BaseSettingsModel): - start_at_workfile: bool = SettingsField( - title="Start at workfile's start frame" - ) - add_retime: bool = SettingsField( - title="Add retime" - ) - deep_exr: bool = SettingsField( - title="Deep Exr Read Node" - ) - -class LoadClipModel(BaseSettingsModel): - enabled: bool = SettingsField( - title="Enabled" - ) - representations_include: list[str] = SettingsField( - default_factory=list, - title="Include representations" - ) - - node_name_template: str = SettingsField( - title="Read node name template" - ) - options_defaults: LoadClipOptionsModel = SettingsField( - default_factory=LoadClipOptionsModel, - title="Loader option defaults" - ) - - -class LoaderPluginsModel(BaseSettingsModel): - LoadImage: LoadImageModel = SettingsField( - default_factory=LoadImageModel, - title="Load Image" - ) - LoadClip: LoadClipModel = SettingsField( - default_factory=LoadClipModel, - title="Load Clip" - ) - - -DEFAULT_LOADER_PLUGINS_SETTINGS = { - "LoadImage": { - "enabled": True, - "representations_include": [], - "node_name_template": "{class_name}_{ext}" - }, - "LoadClip": { - "enabled": True, - "representations_include": [], - "node_name_template": "{class_name}_{ext}", - "options_defaults": { - "start_at_workfile": True, - "add_retime": True, - "deep_exr": False - } - } -} diff --git a/server_addon/nuke/server/settings/main.py b/server_addon/nuke/server/settings/main.py deleted file mode 100644 index 1fd347cc21..0000000000 --- a/server_addon/nuke/server/settings/main.py +++ /dev/null @@ -1,112 +0,0 @@ -from ayon_server.settings import ( - BaseSettingsModel, - SettingsField, -) - -from .general import ( - GeneralSettings, - DEFAULT_GENERAL_SETTINGS -) -from .imageio import ( - ImageIOSettings, - DEFAULT_IMAGEIO_SETTINGS -) -from .dirmap import ( - DirmapSettings, - DEFAULT_DIRMAP_SETTINGS -) -from .scriptsmenu import ( - ScriptsmenuSettings, - DEFAULT_SCRIPTSMENU_SETTINGS -) -from .gizmo import ( - GizmoItem, - DEFAULT_GIZMO_ITEM -) -from .create_plugins import ( - CreatorPluginsSettings, - DEFAULT_CREATE_SETTINGS -) -from .publish_plugins import ( - PublishPluginsModel, - DEFAULT_PUBLISH_PLUGIN_SETTINGS -) -from .loader_plugins import ( - LoaderPluginsModel, - DEFAULT_LOADER_PLUGINS_SETTINGS -) -from .workfile_builder import ( - WorkfileBuilderModel, - DEFAULT_WORKFILE_BUILDER_SETTINGS -) -from .templated_workfile_build import ( - TemplatedWorkfileBuildModel -) - - -class NukeSettings(BaseSettingsModel): - """Nuke addon settings.""" - - general: GeneralSettings = SettingsField( - default_factory=GeneralSettings, - title="General", - ) - - imageio: ImageIOSettings = SettingsField( - default_factory=ImageIOSettings, - title="Color Management (imageio)", - ) - - dirmap: DirmapSettings = SettingsField( - default_factory=DirmapSettings, - title="Nuke Directory Mapping", - ) - - scriptsmenu: ScriptsmenuSettings = SettingsField( - default_factory=ScriptsmenuSettings, - title="Scripts Menu Definition", - ) - - gizmo: list[GizmoItem] = SettingsField( - default_factory=list, title="Gizmo Menu") - - create: CreatorPluginsSettings = SettingsField( - default_factory=CreatorPluginsSettings, - title="Creator Plugins", - ) - - publish: PublishPluginsModel = SettingsField( - default_factory=PublishPluginsModel, - title="Publish Plugins", - ) - - load: LoaderPluginsModel = SettingsField( - default_factory=LoaderPluginsModel, - title="Loader Plugins", - ) - - workfile_builder: WorkfileBuilderModel = SettingsField( - default_factory=WorkfileBuilderModel, - title="Workfile Builder", - ) - - templated_workfile_build: TemplatedWorkfileBuildModel = SettingsField( - title="Templated Workfile Build", - default_factory=TemplatedWorkfileBuildModel - ) - - -DEFAULT_VALUES = { - "general": DEFAULT_GENERAL_SETTINGS, - "imageio": DEFAULT_IMAGEIO_SETTINGS, - "dirmap": DEFAULT_DIRMAP_SETTINGS, - "scriptsmenu": DEFAULT_SCRIPTSMENU_SETTINGS, - "gizmo": [DEFAULT_GIZMO_ITEM], - "create": DEFAULT_CREATE_SETTINGS, - "publish": DEFAULT_PUBLISH_PLUGIN_SETTINGS, - "load": DEFAULT_LOADER_PLUGINS_SETTINGS, - "workfile_builder": DEFAULT_WORKFILE_BUILDER_SETTINGS, - "templated_workfile_build": { - "profiles": [] - } -} diff --git a/server_addon/nuke/server/settings/publish_plugins.py b/server_addon/nuke/server/settings/publish_plugins.py deleted file mode 100644 index c52c9e9c84..0000000000 --- a/server_addon/nuke/server/settings/publish_plugins.py +++ /dev/null @@ -1,412 +0,0 @@ -from pydantic import validator -from ayon_server.settings import ( - BaseSettingsModel, - SettingsField, - ensure_unique_names, - task_types_enum -) -from .common import ( - KnobModel, - ColorspaceConfigurationModel, - validate_json_dict, -) - - -def nuke_render_publish_types_enum(): - """Return all nuke render families available in creators.""" - return [ - {"value": "render", "label": "Render"}, - {"value": "prerender", "label": "Prerender"}, - {"value": "image", "label": "Image"} - ] - - -def nuke_product_types_enum(): - """Return all nuke families available in creators.""" - return [ - {"value": "nukenodes", "label": "Nukenodes"}, - {"value": "model", "label": "Model"}, - {"value": "camera", "label": "Camera"}, - {"value": "gizmo", "label": "Gizmo"}, - {"value": "source", "label": "Source"} - ] + nuke_render_publish_types_enum() - - -class NodeModel(BaseSettingsModel): - name: str = SettingsField( - title="Node name" - ) - nodeclass: str = SettingsField( - "", - title="Node class" - ) - dependent: str = SettingsField( - "", - title="Incoming dependency" - ) - knobs: list[KnobModel] = SettingsField( - default_factory=list, - title="Knobs", - ) - - @validator("knobs") - def ensure_unique_names(cls, value): - """Ensure name fields within the lists have unique names.""" - ensure_unique_names(value) - return value - - -class CollectInstanceDataModel(BaseSettingsModel): - sync_workfile_version_on_product_types: list[str] = SettingsField( - default_factory=list, - enum_resolver=nuke_product_types_enum, - title="Product types" - ) - - -class OptionalPluginModel(BaseSettingsModel): - enabled: bool = SettingsField(True) - optional: bool = SettingsField(title="Optional") - active: bool = SettingsField(title="Active") - - -class ValidateKnobsModel(BaseSettingsModel): - enabled: bool = SettingsField(title="Enabled") - knobs: str = SettingsField( - "{}", - title="Knobs", - widget="textarea", - ) - - @validator("knobs") - def validate_json(cls, value): - return validate_json_dict(value) - - -class ExtractReviewDataModel(BaseSettingsModel): - enabled: bool = SettingsField(title="Enabled") - - -class ExtractReviewDataLutModel(BaseSettingsModel): - enabled: bool = SettingsField(title="Enabled") - - -class BakingStreamFilterModel(BaseSettingsModel): - task_types: list[str] = SettingsField( - default_factory=list, - title="Task types", - enum_resolver=task_types_enum - ) - product_types: list[str] = SettingsField( - default_factory=list, - enum_resolver=nuke_render_publish_types_enum, - title="Sync workfile versions for familes" - ) - product_names: list[str] = SettingsField( - default_factory=list, title="Product names") - - -class ReformatNodesRepositionNodes(BaseSettingsModel): - node_class: str = SettingsField(title="Node class") - knobs: list[KnobModel] = SettingsField( - default_factory=list, - title="Node knobs") - - -class ReformatNodesConfigModel(BaseSettingsModel): - """Only reposition nodes supported. - - You can add multiple reformat nodes and set their knobs. - Order of reformat nodes is important. First reformat node will - be applied first and last reformat node will be applied last. - """ - enabled: bool = SettingsField(False) - reposition_nodes: list[ReformatNodesRepositionNodes] = SettingsField( - default_factory=list, - title="Reposition knobs" - ) - - -class IntermediateOutputModel(BaseSettingsModel): - name: str = SettingsField(title="Output name") - publish: bool = SettingsField(title="Publish") - filter: BakingStreamFilterModel = SettingsField( - title="Filter", default_factory=BakingStreamFilterModel) - read_raw: bool = SettingsField( - False, - title="Input read node RAW switch" - ) - bake_viewer_process: bool = SettingsField( - True, - title="Bake viewer process", - section="Baking target", - ) - colorspace_override: ColorspaceConfigurationModel = SettingsField( - title="Target baking colorspace override", - description="Override Baking target with colorspace or display/view", - default_factory=ColorspaceConfigurationModel - ) - bake_viewer_input_process: bool = SettingsField( - True, - title="Bake viewer input process node (LUT)", - section="Baking additional", - ) - reformat_nodes_config: ReformatNodesConfigModel = SettingsField( - default_factory=ReformatNodesConfigModel, - title="Reformat Nodes") - extension: str = SettingsField( - "mov", - title="File extension" - ) - add_custom_tags: list[str] = SettingsField( - title="Custom tags", default_factory=list) - - -class ExtractReviewIntermediatesModel(BaseSettingsModel): - enabled: bool = SettingsField(title="Enabled") - viewer_lut_raw: bool = SettingsField(title="Viewer lut raw") - outputs: list[IntermediateOutputModel] = SettingsField( - default_factory=list, - title="Baking streams" - ) - - -class FSubmissionNoteModel(BaseSettingsModel): - enabled: bool = SettingsField(title="enabled") - template: str = SettingsField(title="Template") - - -class FSubmistingForModel(BaseSettingsModel): - enabled: bool = SettingsField(title="enabled") - template: str = SettingsField(title="Template") - - -class FVFXScopeOfWorkModel(BaseSettingsModel): - enabled: bool = SettingsField(title="enabled") - template: str = SettingsField(title="Template") - - -class ExctractSlateFrameParamModel(BaseSettingsModel): - f_submission_note: FSubmissionNoteModel = SettingsField( - title="f_submission_note", - default_factory=FSubmissionNoteModel - ) - f_submitting_for: FSubmistingForModel = SettingsField( - title="f_submitting_for", - default_factory=FSubmistingForModel - ) - f_vfx_scope_of_work: FVFXScopeOfWorkModel = SettingsField( - title="f_vfx_scope_of_work", - default_factory=FVFXScopeOfWorkModel - ) - - -class ExtractSlateFrameModel(BaseSettingsModel): - viewer_lut_raw: bool = SettingsField(title="Viewer lut raw") - key_value_mapping: ExctractSlateFrameParamModel = SettingsField( - title="Key value mapping", - default_factory=ExctractSlateFrameParamModel - ) - - -class IncrementScriptVersionModel(BaseSettingsModel): - enabled: bool = SettingsField(title="Enabled") - optional: bool = SettingsField(title="Optional") - active: bool = SettingsField(title="Active") - - -class PublishPluginsModel(BaseSettingsModel): - CollectInstanceData: CollectInstanceDataModel = SettingsField( - title="Collect Instance Version", - default_factory=CollectInstanceDataModel, - section="Collectors" - ) - ValidateCorrectAssetContext: OptionalPluginModel = SettingsField( - title="Validate Correct Folder Name", - default_factory=OptionalPluginModel, - section="Validators" - ) - ValidateKnobs: ValidateKnobsModel = SettingsField( - title="Validate Knobs", - default_factory=ValidateKnobsModel - ) - ValidateOutputResolution: OptionalPluginModel = SettingsField( - title="Validate Output Resolution", - default_factory=OptionalPluginModel - ) - ValidateGizmo: OptionalPluginModel = SettingsField( - title="Validate Gizmo", - default_factory=OptionalPluginModel - ) - ValidateBackdrop: OptionalPluginModel = SettingsField( - title="Validate Backdrop", - default_factory=OptionalPluginModel - ) - ValidateScriptAttributes: OptionalPluginModel = SettingsField( - title="Validate workfile attributes", - default_factory=OptionalPluginModel - ) - ExtractReviewData: ExtractReviewDataModel = SettingsField( - title="Extract Review Data", - default_factory=ExtractReviewDataModel - ) - ExtractReviewDataLut: ExtractReviewDataLutModel = SettingsField( - title="Extract Review Data Lut", - default_factory=ExtractReviewDataLutModel - ) - ExtractReviewIntermediates: ExtractReviewIntermediatesModel = ( - SettingsField( - title="Extract Review Intermediates", - default_factory=ExtractReviewIntermediatesModel - ) - ) - ExtractSlateFrame: ExtractSlateFrameModel = SettingsField( - title="Extract Slate Frame", - default_factory=ExtractSlateFrameModel - ) - IncrementScriptVersion: IncrementScriptVersionModel = SettingsField( - title="Increment Workfile Version", - default_factory=IncrementScriptVersionModel, - section="Integrators" - ) - - -DEFAULT_PUBLISH_PLUGIN_SETTINGS = { - "CollectInstanceData": { - "sync_workfile_version_on_product_types": [ - "nukenodes", - "camera", - "gizmo", - "source", - "render", - "write" - ] - }, - "ValidateCorrectAssetContext": { - "enabled": True, - "optional": True, - "active": True - }, - "ValidateKnobs": { - "enabled": False, - "knobs": "\n".join([ - '{', - ' "render": {', - ' "review": true', - ' }', - '}' - ]) - }, - "ValidateOutputResolution": { - "enabled": True, - "optional": True, - "active": True - }, - "ValidateGizmo": { - "enabled": True, - "optional": True, - "active": True - }, - "ValidateBackdrop": { - "enabled": True, - "optional": True, - "active": True - }, - "ValidateScriptAttributes": { - "enabled": True, - "optional": True, - "active": True - }, - "ExtractReviewData": { - "enabled": False - }, - "ExtractReviewDataLut": { - "enabled": False - }, - "ExtractReviewIntermediates": { - "enabled": True, - "viewer_lut_raw": False, - "outputs": [ - { - "name": "baking", - "publish": False, - "filter": { - "task_types": [], - "product_types": [], - "product_names": [] - }, - "read_raw": False, - "colorspace_override": { - "enabled": False, - "type": "colorspace", - "colorspace": "", - "display_view": { - "display": "", - "view": "" - } - }, - "bake_viewer_process": True, - "bake_viewer_input_process": True, - "reformat_nodes_config": { - "enabled": False, - "reposition_nodes": [ - { - "node_class": "Reformat", - "knobs": [ - { - "type": "text", - "name": "type", - "text": "to format" - }, - { - "type": "text", - "name": "format", - "text": "HD_1080" - }, - { - "type": "text", - "name": "filter", - "text": "Lanczos6" - }, - { - "type": "boolean", - "name": "black_outside", - "boolean": True - }, - { - "type": "boolean", - "name": "pbb", - "boolean": False - } - ] - } - ] - }, - "extension": "mov", - "add_custom_tags": [] - } - ] - }, - "ExtractSlateFrame": { - "viewer_lut_raw": False, - "key_value_mapping": { - "f_submission_note": { - "enabled": True, - "template": "{comment}" - }, - "f_submitting_for": { - "enabled": True, - "template": "{intent[value]}" - }, - "f_vfx_scope_of_work": { - "enabled": False, - "template": "" - } - } - }, - "IncrementScriptVersion": { - "enabled": True, - "optional": True, - "active": True - } -} diff --git a/server_addon/nuke/server/settings/scriptsmenu.py b/server_addon/nuke/server/settings/scriptsmenu.py deleted file mode 100644 index 7ffd6841d5..0000000000 --- a/server_addon/nuke/server/settings/scriptsmenu.py +++ /dev/null @@ -1,52 +0,0 @@ -from ayon_server.settings import BaseSettingsModel, SettingsField - - -class ScriptsmenuSubmodel(BaseSettingsModel): - """Item Definition""" - _isGroup = True - - type: str = SettingsField(title="Type") - command: str = SettingsField(title="Command") - sourcetype: str = SettingsField(title="Source Type") - title: str = SettingsField(title="Title") - tooltip: str = SettingsField(title="Tooltip") - - -class ScriptsmenuSettings(BaseSettingsModel): - """Nuke script menu project settings.""" - _isGroup = True - - name: str = SettingsField(title="Menu Name") - definition: list[ScriptsmenuSubmodel] = SettingsField( - default_factory=list, - title="Definition", - description="Scriptmenu Items Definition" - ) - - -DEFAULT_SCRIPTSMENU_SETTINGS = { - "name": "Custom Tools", - "definition": [ - { - "type": "action", - "sourcetype": "python", - "title": "Ayon Nuke Docs", - "command": "import webbrowser;webbrowser.open(url='https://ayon.ynput.io/docs/addon_nuke_artist')", # noqa - "tooltip": "Open the Ayon Nuke user doc page" - }, - { - "type": "action", - "sourcetype": "python", - "title": "Set Frame Start (Read Node)", - "command": "from openpype.hosts.nuke.startup.frame_setting_for_read_nodes import main;main();", # noqa - "tooltip": "Set frame start for read node(s)" - }, - { - "type": "action", - "sourcetype": "python", - "title": "Set non publish output for Write Node", - "command": "from openpype.hosts.nuke.startup.custom_write_node import main;main();", # noqa - "tooltip": "Open the OpenPype Nuke user doc page" - } - ] -} diff --git a/server_addon/nuke/server/settings/templated_workfile_build.py b/server_addon/nuke/server/settings/templated_workfile_build.py deleted file mode 100644 index 12ebedf570..0000000000 --- a/server_addon/nuke/server/settings/templated_workfile_build.py +++ /dev/null @@ -1,34 +0,0 @@ -from ayon_server.settings import ( - BaseSettingsModel, - SettingsField, - task_types_enum, -) - - -class TemplatedWorkfileProfileModel(BaseSettingsModel): - task_types: list[str] = SettingsField( - default_factory=list, - title="Task types", - enum_resolver=task_types_enum - ) - task_names: list[str] = SettingsField( - default_factory=list, - title="Task names" - ) - path: str = SettingsField( - title="Path to template" - ) - keep_placeholder: bool = SettingsField( - False, - title="Keep placeholders") - create_first_version: bool = SettingsField( - True, - title="Create first version" - ) - - -class TemplatedWorkfileBuildModel(BaseSettingsModel): - """Settings for templated workfile builder.""" - profiles: list[TemplatedWorkfileProfileModel] = SettingsField( - default_factory=list - ) diff --git a/server_addon/nuke/server/settings/workfile_builder.py b/server_addon/nuke/server/settings/workfile_builder.py deleted file mode 100644 index 97961655f3..0000000000 --- a/server_addon/nuke/server/settings/workfile_builder.py +++ /dev/null @@ -1,84 +0,0 @@ -from ayon_server.settings import ( - BaseSettingsModel, - SettingsField, - task_types_enum, - MultiplatformPathModel, -) - - -class CustomTemplateModel(BaseSettingsModel): - task_types: list[str] = SettingsField( - default_factory=list, - title="Task types", - enum_resolver=task_types_enum - ) - path: MultiplatformPathModel = SettingsField( - default_factory=MultiplatformPathModel, - title="Gizmo Directory Path" - ) - - -class BuilderProfileItemModel(BaseSettingsModel): - product_name_filters: list[str] = SettingsField( - default_factory=list, - title="Product name" - ) - product_types: list[str] = SettingsField( - default_factory=list, - title="Product types" - ) - repre_names: list[str] = SettingsField( - default_factory=list, - title="Representations" - ) - loaders: list[str] = SettingsField( - default_factory=list, - title="Loader plugins" - ) - - -class BuilderProfileModel(BaseSettingsModel): - task_types: list[str] = SettingsField( - default_factory=list, - title="Task types", - enum_resolver=task_types_enum - ) - tasks: list[str] = SettingsField( - default_factory=list, - title="Task names" - ) - current_context: list[BuilderProfileItemModel] = SettingsField( - default_factory=list, - title="Current context" - ) - linked_assets: list[BuilderProfileItemModel] = SettingsField( - default_factory=list, - title="Linked assets/shots" - ) - - -class WorkfileBuilderModel(BaseSettingsModel): - """[deprecated] use Template Workfile Build Settings instead. - """ - create_first_version: bool = SettingsField( - title="Create first workfile") - custom_templates: list[CustomTemplateModel] = SettingsField( - default_factory=list, - title="Custom templates" - ) - builder_on_start: bool = SettingsField( - default=False, - title="Run Builder at first workfile" - ) - profiles: list[BuilderProfileModel] = SettingsField( - default_factory=list, - title="Builder profiles" - ) - - -DEFAULT_WORKFILE_BUILDER_SETTINGS = { - "create_first_version": False, - "custom_templates": [], - "builder_on_start": False, - "profiles": [] -} diff --git a/server_addon/timers_manager/client/ayon_timers_manager/__init__.py b/server_addon/timers_manager/client/ayon_timers_manager/__init__.py deleted file mode 100644 index 1ec0d9b74b..0000000000 --- a/server_addon/timers_manager/client/ayon_timers_manager/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -from .version import __version__ -from .timers_manager import ( - TimersManager -) - -__all__ = ( - "__version__", - - "TimersManager", -) diff --git a/server_addon/timers_manager/client/ayon_timers_manager/exceptions.py b/server_addon/timers_manager/client/ayon_timers_manager/exceptions.py deleted file mode 100644 index 5a9e00765d..0000000000 --- a/server_addon/timers_manager/client/ayon_timers_manager/exceptions.py +++ /dev/null @@ -1,3 +0,0 @@ -class InvalidContextError(ValueError): - """Context for which the timer should be started is invalid.""" - pass diff --git a/server_addon/timers_manager/client/ayon_timers_manager/idle_threads.py b/server_addon/timers_manager/client/ayon_timers_manager/idle_threads.py deleted file mode 100644 index d70f7790c4..0000000000 --- a/server_addon/timers_manager/client/ayon_timers_manager/idle_threads.py +++ /dev/null @@ -1,160 +0,0 @@ -import time -from qtpy import QtCore -from pynput import mouse, keyboard - -from ayon_core.lib import Logger - - -class IdleItem: - """Python object holds information if state of idle changed. - - This item is used to be independent from Qt objects. - """ - def __init__(self): - self.changed = False - - def reset(self): - self.changed = False - - def set_changed(self, changed=True): - self.changed = changed - - -class IdleManager(QtCore.QThread): - """ Measure user's idle time in seconds. - Idle time resets on keyboard/mouse input. - Is able to emit signals at specific time idle. - """ - time_signals = {} - idle_time = 0 - signal_reset_timer = QtCore.Signal() - - def __init__(self): - super(IdleManager, self).__init__() - self.log = Logger.get_logger(self.__class__.__name__) - self.signal_reset_timer.connect(self._reset_time) - - self.idle_item = IdleItem() - - self._is_running = False - self._mouse_thread = None - self._keyboard_thread = None - - def add_time_signal(self, emit_time, signal): - """ If any module want to use IdleManager, need to use add_time_signal - - Args: - emit_time(int): Time when signal will be emitted. - signal(QtCore.Signal): Signal that will be emitted - (without objects). - """ - if emit_time not in self.time_signals: - self.time_signals[emit_time] = [] - self.time_signals[emit_time].append(signal) - - @property - def is_running(self): - return self._is_running - - def _reset_time(self): - self.idle_time = 0 - - def stop(self): - self._is_running = False - - def _on_mouse_destroy(self): - self._mouse_thread = None - - def _on_keyboard_destroy(self): - self._keyboard_thread = None - - def run(self): - self.log.info('IdleManager has started') - self._is_running = True - - thread_mouse = MouseThread(self.idle_item) - thread_keyboard = KeyboardThread(self.idle_item) - - thread_mouse.destroyed.connect(self._on_mouse_destroy) - thread_keyboard.destroyed.connect(self._on_keyboard_destroy) - - self._mouse_thread = thread_mouse - self._keyboard_thread = thread_keyboard - - thread_mouse.start() - thread_keyboard.start() - - # Main loop here is each second checked if idle item changed state - while self._is_running: - if self.idle_item.changed: - self.idle_item.reset() - self.signal_reset_timer.emit() - else: - self.idle_time += 1 - - if self.idle_time in self.time_signals: - for signal in self.time_signals[self.idle_time]: - signal.emit() - time.sleep(1) - - self._post_run() - self.log.info('IdleManager has stopped') - - def _post_run(self): - # Stop threads if still exist - if self._mouse_thread is not None: - self._mouse_thread.signal_stop.emit() - self._mouse_thread.terminate() - self._mouse_thread.wait() - - if self._keyboard_thread is not None: - self._keyboard_thread.signal_stop.emit() - self._keyboard_thread.terminate() - self._keyboard_thread.wait() - - -class MouseThread(QtCore.QThread): - """Listens user's mouse movement.""" - signal_stop = QtCore.Signal() - - def __init__(self, idle_item): - super(MouseThread, self).__init__() - self.signal_stop.connect(self.stop) - self.m_listener = None - self.idle_item = idle_item - - def stop(self): - if self.m_listener is not None: - self.m_listener.stop() - - def on_move(self, *args, **kwargs): - self.idle_item.set_changed() - - def run(self): - self.m_listener = mouse.Listener(on_move=self.on_move) - self.m_listener.start() - - -class KeyboardThread(QtCore.QThread): - """Listens user's keyboard input - """ - signal_stop = QtCore.Signal() - - def __init__(self, idle_item): - super(KeyboardThread, self).__init__() - self.signal_stop.connect(self.stop) - self.k_listener = None - self.idle_item = idle_item - - def stop(self): - if self.k_listener is not None: - listener = self.k_listener - self.k_listener = None - listener.stop() - - def on_press(self, *args, **kwargs): - self.idle_item.set_changed() - - def run(self): - self.k_listener = keyboard.Listener(on_press=self.on_press) - self.k_listener.start() diff --git a/server_addon/timers_manager/client/ayon_timers_manager/launch_hooks/post_start_timer.py b/server_addon/timers_manager/client/ayon_timers_manager/launch_hooks/post_start_timer.py deleted file mode 100644 index b402d4034a..0000000000 --- a/server_addon/timers_manager/client/ayon_timers_manager/launch_hooks/post_start_timer.py +++ /dev/null @@ -1,44 +0,0 @@ -from ayon_applications import PostLaunchHook, LaunchTypes - - -class PostStartTimerHook(PostLaunchHook): - """Start timer with TimersManager module. - - This module requires enabled TimerManager module. - """ - order = None - launch_types = {LaunchTypes.local} - - def execute(self): - project_name = self.data.get("project_name") - folder_path = self.data.get("folder_path") - task_name = self.data.get("task_name") - - missing_context_keys = set() - if not project_name: - missing_context_keys.add("project_name") - if not folder_path: - missing_context_keys.add("folder_path") - if not task_name: - missing_context_keys.add("task_name") - - if missing_context_keys: - missing_keys_str = ", ".join([ - "\"{}\"".format(key) for key in missing_context_keys - ]) - self.log.debug("Hook {} skipped. Missing data keys: {}".format( - self.__class__.__name__, missing_keys_str - )) - return - - timers_manager = self.addons_manager.get("timers_manager") - if not timers_manager or not timers_manager.enabled: - self.log.info(( - "Skipping starting timer because" - " TimersManager is not available." - )) - return - - timers_manager.start_timer_with_webserver( - project_name, folder_path, task_name, logger=self.log - ) diff --git a/server_addon/timers_manager/client/ayon_timers_manager/plugins/publish/start_timer.py b/server_addon/timers_manager/client/ayon_timers_manager/plugins/publish/start_timer.py deleted file mode 100644 index 620cdb6e65..0000000000 --- a/server_addon/timers_manager/client/ayon_timers_manager/plugins/publish/start_timer.py +++ /dev/null @@ -1,37 +0,0 @@ -""" -Requires: - context -> project_settings - context -> ayonAddonsManager -""" - -import pyblish.api - - -class StartTimer(pyblish.api.ContextPlugin): - label = "Start Timer" - order = pyblish.api.IntegratorOrder + 1 - hosts = ["*"] - - def process(self, context): - timers_manager = context.data["ayonAddonsManager"]["timers_manager"] - if not timers_manager.enabled: - self.log.debug("TimersManager is disabled") - return - - project_settings = context.data["project_settings"] - if not project_settings["timers_manager"]["disregard_publishing"]: - self.log.debug("Publish is not affecting running timers.") - return - - project_name = context.data["projectName"] - folder_path = context.data.get("folderPath") - task_name = context.data.get("task") - if not project_name or not folder_path or not task_name: - self.log.info(( - "Current context does not contain all" - " required information to start a timer." - )) - return - timers_manager.start_timer_with_webserver( - project_name, folder_path, task_name, self.log - ) diff --git a/server_addon/timers_manager/client/ayon_timers_manager/plugins/publish/stop_timer.py b/server_addon/timers_manager/client/ayon_timers_manager/plugins/publish/stop_timer.py deleted file mode 100644 index eafd8cb450..0000000000 --- a/server_addon/timers_manager/client/ayon_timers_manager/plugins/publish/stop_timer.py +++ /dev/null @@ -1,27 +0,0 @@ -""" -Requires: - context -> project_settings - context -> ayonAddonsManager -""" - - -import pyblish.api - - -class StopTimer(pyblish.api.ContextPlugin): - label = "Stop Timer" - order = pyblish.api.ExtractorOrder - 0.49 - hosts = ["*"] - - def process(self, context): - timers_manager = context.data["ayonAddonsManager"]["timers_manager"] - if not timers_manager.enabled: - self.log.debug("TimersManager is disabled") - return - - project_settings = context.data["project_settings"] - if not project_settings["timers_manager"]["disregard_publishing"]: - self.log.debug("Publish is not affecting running timers.") - return - - timers_manager.stop_timer_with_webserver(self.log) diff --git a/server_addon/timers_manager/client/ayon_timers_manager/rest_api.py b/server_addon/timers_manager/client/ayon_timers_manager/rest_api.py deleted file mode 100644 index 88a6539510..0000000000 --- a/server_addon/timers_manager/client/ayon_timers_manager/rest_api.py +++ /dev/null @@ -1,85 +0,0 @@ -import json - -from aiohttp.web_response import Response -from ayon_core.lib import Logger - - -class TimersManagerModuleRestApi: - """ - REST API endpoint used for calling from hosts when context change - happens in Workfile app. - """ - def __init__(self, user_module, server_manager): - self._log = None - self.module = user_module - self.server_manager = server_manager - - self.prefix = "/timers_manager" - - self.register() - - @property - def log(self): - if self._log is None: - self._log = Logger.get_logger(self.__class__.__name__) - return self._log - - def register(self): - self.server_manager.add_route( - "POST", - self.prefix + "/start_timer", - self.start_timer - ) - self.server_manager.add_route( - "POST", - self.prefix + "/stop_timer", - self.stop_timer - ) - self.server_manager.add_route( - "GET", - self.prefix + "/get_task_time", - self.get_task_time - ) - - async def start_timer(self, request): - data = await request.json() - try: - project_name = data["project_name"] - folder_path = data["folder_path"] - task_name = data["task_name"] - except KeyError: - msg = ( - "Payload must contain fields 'project_name," - " 'folder_path' and 'task_name'" - ) - self.log.error(msg) - return Response(status=400, message=msg) - - self.module.stop_timers() - try: - self.module.start_timer(project_name, folder_path, task_name) - except Exception as exc: - return Response(status=404, message=str(exc)) - - return Response(status=200) - - async def stop_timer(self, request): - self.module.stop_timers() - return Response(status=200) - - async def get_task_time(self, request): - data = await request.json() - try: - project_name = data["project_name"] - folder_path = data["folder_path"] - task_name = data["task_name"] - except KeyError: - message = ( - "Payload must contain fields 'project_name, 'folder_path'," - " 'task_name'" - ) - self.log.warning(message) - return Response(text=message, status=404) - - time = self.module.get_task_time(project_name, folder_path, task_name) - return Response(text=json.dumps(time)) diff --git a/server_addon/timers_manager/client/ayon_timers_manager/timers_manager.py b/server_addon/timers_manager/client/ayon_timers_manager/timers_manager.py deleted file mode 100644 index 2aac7b2a49..0000000000 --- a/server_addon/timers_manager/client/ayon_timers_manager/timers_manager.py +++ /dev/null @@ -1,488 +0,0 @@ -import os -import platform - -import ayon_api - -from ayon_core.addon import ( - AYONAddon, - ITrayService, - IPluginPaths -) -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__)) - - -class ExampleTimersManagerConnector: - """Timers manager can handle timers of multiple modules/addons. - - Module must have object under `timers_manager_connector` attribute with - few methods. This is example class of the object that could be stored under - module. - - Required methods are 'stop_timer' and 'start_timer'. - - Example of `data` that are passed during changing timer: - ``` - data = { - "project_name": project_name, - "folder_id": folder_id, - "folder_path": folder_entity["path"], - "task_name": task_name, - "task_type": task_type, - # Deprecated - "asset_id": folder_id, - "asset_name": folder_entity["name"], - "hierarchy": hierarchy_items, - } - ``` - """ - - # Not needed at all - def __init__(self, module): - # Store timer manager module to be able call it's methods when needed - self._timers_manager_module = None - - # Store module which want to use timers manager to have access - self._module = module - - # Required - def stop_timer(self): - """Called by timers manager when module should stop timer.""" - self._module.stop_timer() - - # Required - def start_timer(self, data): - """Method called by timers manager when should start timer.""" - self._module.start_timer(data) - - # Optional - def register_timers_manager(self, timer_manager_module): - """Method called by timers manager where it's object is passed. - - This is moment when timers manager module can be store to be able - call it's callbacks (e.g. timer started). - """ - self._timers_manager_module = timer_manager_module - - # Custom implementation - def timer_started(self, data): - """This is example of possibility to trigger callbacks on manager.""" - if self._timers_manager_module is not None: - self._timers_manager_module.timer_started(self._module.id, data) - - # Custom implementation - def timer_stopped(self): - if self._timers_manager_module is not None: - self._timers_manager_module.timer_stopped(self._module.id) - - -class TimersManager( - AYONAddon, - ITrayService, - IPluginPaths -): - """ Handles about Timers. - - Should be able to start/stop all timers at once. - - To be able use this advantage module has to have attribute with name - `timers_manager_connector` which has two methods 'stop_timer' - and 'start_timer'. Optionally may have `register_timers_manager` where - object of TimersManager module is passed to be able call it's callbacks. - - See `ExampleTimersManagerConnector`. - """ - name = "timers_manager" - version = __version__ - label = "Timers Service" - - _required_methods = ( - "stop_timer", - "start_timer" - ) - - def initialize(self, studio_settings): - timers_settings = studio_settings.get(self.name) - enabled = timers_settings is not None - - auto_stop = False - full_time = 0 - message_time = 0 - if enabled: - # When timer will stop if idle manager is running (minutes) - full_time = int(timers_settings["full_time"] * 60) - # How many minutes before the timer is stopped will popup the message - message_time = int(timers_settings["message_time"] * 60) - - auto_stop = timers_settings["auto_stop"] - platform_name = platform.system().lower() - # Turn of auto stop on MacOs because pynput requires root permissions - # and on linux can cause thread locks on application close - if full_time <= 0 or platform_name in ("darwin", "linux"): - auto_stop = False - - self.enabled = enabled - self.auto_stop = auto_stop - self.time_show_message = full_time - message_time - self.time_stop_timer = full_time - - self.is_running = False - self.last_task = None - - # Tray attributes - self._signal_handler = None - self._widget_user_idle = None - self._idle_manager = None - - self._connectors_by_module_id = {} - self._modules_by_id = {} - - def tray_init(self): - if not self.auto_stop: - return - - from .idle_threads import IdleManager - from .widget_user_idle import WidgetUserIdle, SignalHandler - - signal_handler = SignalHandler(self) - idle_manager = IdleManager() - widget_user_idle = WidgetUserIdle(self) - widget_user_idle.set_countdown_start( - self.time_stop_timer - self.time_show_message - ) - - idle_manager.signal_reset_timer.connect( - widget_user_idle.reset_countdown - ) - idle_manager.add_time_signal( - self.time_show_message, signal_handler.signal_show_message - ) - idle_manager.add_time_signal( - self.time_stop_timer, signal_handler.signal_stop_timers - ) - - self._signal_handler = signal_handler - self._widget_user_idle = widget_user_idle - self._idle_manager = idle_manager - - def tray_start(self, *_a, **_kw): - if self._idle_manager: - self._idle_manager.start() - - def tray_exit(self): - if self._idle_manager: - self._idle_manager.stop() - self._idle_manager.wait() - - def get_timer_data_for_path(self, task_path): - """Convert string path to a timer data. - - It is expected that first item is project name, last item is task name - and folder path in the middle. - """ - path_items = task_path.split("/") - task_name = path_items.pop(-1) - project_name = path_items.pop(0) - folder_path = "/" + "/".join(path_items) - return self.get_timer_data_for_context( - project_name, folder_path, task_name, self.log - ) - - def get_launch_hook_paths(self): - """Implementation for applications launch hooks.""" - - return [ - os.path.join(TIMER_MODULE_DIR, "launch_hooks") - ] - - def get_plugin_paths(self): - """Implementation of `IPluginPaths`.""" - - return { - "publish": [os.path.join(TIMER_MODULE_DIR, "plugins", "publish")] - } - - @staticmethod - def get_timer_data_for_context( - project_name, folder_path, task_name, logger=None - ): - """Prepare data for timer related callbacks.""" - if not project_name or not folder_path or not task_name: - raise InvalidContextError(( - "Missing context information got" - " Project: \"{}\" Folder: \"{}\" Task: \"{}\"" - ).format(str(project_name), str(folder_path), str(task_name))) - - folder_entity = ayon_api.get_folder_by_path( - project_name, - folder_path, - fields={"id", "name", "path"} - ) - - if not folder_entity: - raise InvalidContextError(( - "Folder \"{}\" not found in project \"{}\"" - ).format(folder_path, project_name)) - - folder_id = folder_entity["id"] - task_entity = ayon_api.get_task_by_name( - project_name, folder_id, task_name - ) - if not task_entity: - raise InvalidContextError(( - "Task \"{}\" not found on folder \"{}\" in project \"{}\"" - ).format(task_name, folder_path, project_name)) - - task_type = "" - try: - task_type = task_entity["taskType"] - except KeyError: - msg = "Couldn't find task_type for {}".format(task_name) - if logger is not None: - logger.warning(msg) - else: - print(msg) - - hierarchy_items = folder_entity["path"].split("/") - hierarchy_items.pop(0) - - return { - "project_name": project_name, - "folder_id": folder_id, - "folder_path": folder_entity["path"], - "task_name": task_name, - "task_type": task_type, - "asset_id": folder_id, - "asset_name": folder_entity["name"], - "hierarchy": hierarchy_items, - } - - def start_timer(self, project_name, folder_path, task_name): - """Start timer for passed context. - - Args: - project_name (str): Project name. - folder_path (str): Folder path. - task_name (str): Task name. - """ - data = self.get_timer_data_for_context( - project_name, folder_path, task_name, self.log - ) - self.timer_started(None, data) - - def get_task_time(self, project_name, folder_path, task_name): - """Get total time for passed context. - - TODO: - - convert context to timer data - """ - times = {} - for module_id, connector in self._connectors_by_module_id.items(): - if hasattr(connector, "get_task_time"): - module = self._modules_by_id[module_id] - times[module.name] = connector.get_task_time( - project_name, folder_path, task_name - ) - return times - - def timer_started(self, source_id, data): - """Connector triggered that timer has started. - - New timer has started for context in data. - """ - for module_id, connector in self._connectors_by_module_id.items(): - if module_id == source_id: - continue - - try: - connector.start_timer(data) - except Exception: - self.log.info( - "Failed to start timer on connector {}".format( - str(connector) - ) - ) - - self.last_task = data - self.is_running = True - - def timer_stopped(self, source_id): - """Connector triggered that hist timer has stopped. - - Should stop all other timers. - - TODO: - - pass context for which timer has stopped to validate if timers are - same and valid - """ - for module_id, connector in self._connectors_by_module_id.items(): - if module_id == source_id: - continue - - try: - connector.stop_timer() - except Exception: - self.log.info( - "Failed to stop timer on connector {}".format( - str(connector) - ) - ) - - def restart_timers(self): - if self.last_task is not None: - self.timer_started(None, self.last_task) - - def stop_timers(self): - """Stop all timers.""" - if self.is_running is False: - return - - if self._widget_user_idle is not None: - self._widget_user_idle.set_timer_stopped() - self.is_running = False - - self.timer_stopped(None) - - def connect_with_addons(self, enabled_modules): - for module in enabled_modules: - connector = getattr(module, "timers_manager_connector", None) - if connector is None: - continue - - missing_methods = set() - for method_name in self._required_methods: - if not hasattr(connector, method_name): - missing_methods.add(method_name) - - if missing_methods: - joined = ", ".join( - ['"{}"'.format(name for name in missing_methods)] - ) - self.log.info(( - "Module \"{}\" has missing required methods {}." - ).format(module.name, joined)) - continue - - self._connectors_by_module_id[module.id] = connector - self._modules_by_id[module.id] = module - - # Optional method - if hasattr(connector, "register_timers_manager"): - try: - connector.register_timers_manager(self) - except Exception: - self.log.info(( - "Failed to register timers manager" - " for connector of module \"{}\"." - ).format(module.name)) - - def show_message(self): - if self.is_running is False: - return - if not self._widget_user_idle.is_showed(): - self._widget_user_idle.reset_countdown() - self._widget_user_idle.show() - - # Webserver module implementation - def webserver_initialization(self, server_manager): - """Add routes for timers to be able start/stop with rest api.""" - if self.tray_initialized: - from .rest_api import TimersManagerModuleRestApi - self.rest_api_obj = TimersManagerModuleRestApi( - self, server_manager - ) - - @staticmethod - def start_timer_with_webserver( - project_name, folder_path, task_name, logger=None - ): - """Prepared method for calling change timers on REST api. - - Webserver must be active. At the moment is Webserver running only when - OpenPype Tray is used. - - Args: - project_name (str): Project name. - folder_path (str): Folder path. - task_name (str): Task name. - logger (logging.Logger): Logger object. Using 'print' if not - passed. - """ - - webserver_url = os.environ.get("AYON_WEBSERVER_URL") - if not webserver_url: - msg = "Couldn't find webserver url" - if logger is not None: - logger.warning(msg) - else: - print(msg) - return - - rest_api_url = "{}/timers_manager/start_timer".format(webserver_url) - try: - import requests - except Exception: - msg = "Couldn't start timer ('requests' is not available)" - if logger is not None: - logger.warning(msg) - else: - print(msg) - return - data = { - "project_name": project_name, - "folder_path": folder_path, - "task_name": task_name - } - - return requests.post(rest_api_url, json=data) - - @staticmethod - def stop_timer_with_webserver(logger=None): - """Prepared method for calling stop timers on REST api. - - Args: - logger (logging.Logger): Logger used for logging messages. - """ - - webserver_url = os.environ.get("AYON_WEBSERVER_URL") - if not webserver_url: - msg = "Couldn't find webserver url" - if logger is not None: - logger.warning(msg) - else: - print(msg) - return - - rest_api_url = "{}/timers_manager/stop_timer".format(webserver_url) - try: - import requests - except Exception: - msg = "Couldn't start timer ('requests' is not available)" - if logger is not None: - logger.warning(msg) - else: - print(msg) - return - - return requests.post(rest_api_url) - - def on_host_install(self, host, host_name, project_name): - self.log.debug("Installing task changed callback") - register_event_callback("taskChanged", self._on_host_task_change) - - def _on_host_task_change(self, event): - project_name = event["project_name"] - folder_path = event["folder_path"] - task_name = event["task_name"] - self.log.debug(( - "Sending message that timer should change to" - " Project: {} Folder: {} Task: {}" - ).format(project_name, folder_path, task_name)) - - self.start_timer_with_webserver( - project_name, folder_path, task_name, self.log - ) diff --git a/server_addon/timers_manager/client/ayon_timers_manager/version.py b/server_addon/timers_manager/client/ayon_timers_manager/version.py deleted file mode 100644 index 95e413aaac..0000000000 --- a/server_addon/timers_manager/client/ayon_timers_manager/version.py +++ /dev/null @@ -1,3 +0,0 @@ -# -*- coding: utf-8 -*- -"""Package declaring AYON addon 'timers_manager' version.""" -__version__ = "0.2.0" diff --git a/server_addon/timers_manager/client/ayon_timers_manager/widget_user_idle.py b/server_addon/timers_manager/client/ayon_timers_manager/widget_user_idle.py deleted file mode 100644 index c59ab15b38..0000000000 --- a/server_addon/timers_manager/client/ayon_timers_manager/widget_user_idle.py +++ /dev/null @@ -1,196 +0,0 @@ -from qtpy import QtCore, QtGui, QtWidgets -from ayon_core import resources, style - - -class WidgetUserIdle(QtWidgets.QWidget): - SIZE_W = 300 - SIZE_H = 160 - - def __init__(self, module): - super(WidgetUserIdle, self).__init__() - - self.setWindowTitle("AYON - Stop timers") - - icon = QtGui.QIcon(resources.get_ayon_icon_filepath()) - self.setWindowIcon(icon) - - self.setWindowFlags( - QtCore.Qt.WindowCloseButtonHint - | QtCore.Qt.WindowMinimizeButtonHint - | QtCore.Qt.WindowStaysOnTopHint - ) - - self._is_showed = False - self._timer_stopped = False - self._countdown = 0 - self._countdown_start = 0 - - self.module = module - - msg_info = "You didn't work for a long time." - msg_question = "Would you like to stop Timers?" - msg_stopped = ( - "Your Timers were stopped. Do you want to start them again?" - ) - - lbl_info = QtWidgets.QLabel(msg_info, self) - lbl_info.setTextFormat(QtCore.Qt.RichText) - lbl_info.setWordWrap(True) - - lbl_question = QtWidgets.QLabel(msg_question, self) - lbl_question.setTextFormat(QtCore.Qt.RichText) - lbl_question.setWordWrap(True) - - lbl_stopped = QtWidgets.QLabel(msg_stopped, self) - lbl_stopped.setTextFormat(QtCore.Qt.RichText) - lbl_stopped.setWordWrap(True) - - lbl_rest_time = QtWidgets.QLabel(self) - lbl_rest_time.setTextFormat(QtCore.Qt.RichText) - lbl_rest_time.setWordWrap(True) - lbl_rest_time.setAlignment(QtCore.Qt.AlignCenter) - - form = QtWidgets.QFormLayout() - form.setContentsMargins(10, 15, 10, 5) - - form.addRow(lbl_info) - form.addRow(lbl_question) - form.addRow(lbl_stopped) - form.addRow(lbl_rest_time) - - btn_stop = QtWidgets.QPushButton("Stop timer", self) - btn_stop.setToolTip("Stop's All timers") - - btn_continue = QtWidgets.QPushButton("Continue", self) - btn_continue.setToolTip("Timer won't stop") - - btn_close = QtWidgets.QPushButton("Close", self) - btn_close.setToolTip("Close window") - - btn_restart = QtWidgets.QPushButton("Start timers", self) - btn_restart.setToolTip("Timer will be started again") - - group_layout = QtWidgets.QHBoxLayout() - group_layout.addStretch(1) - group_layout.addWidget(btn_continue) - group_layout.addWidget(btn_stop) - group_layout.addWidget(btn_restart) - group_layout.addWidget(btn_close) - - layout = QtWidgets.QVBoxLayout(self) - layout.addLayout(form) - layout.addLayout(group_layout) - - count_timer = QtCore.QTimer() - count_timer.setInterval(1000) - - btn_stop.clicked.connect(self._on_stop_clicked) - btn_continue.clicked.connect(self._on_continue_clicked) - btn_close.clicked.connect(self._close_widget) - btn_restart.clicked.connect(self._on_restart_clicked) - count_timer.timeout.connect(self._on_count_timeout) - - self.lbl_info = lbl_info - self.lbl_question = lbl_question - self.lbl_stopped = lbl_stopped - self.lbl_rest_time = lbl_rest_time - - self.btn_stop = btn_stop - self.btn_continue = btn_continue - self.btn_close = btn_close - self.btn_restart = btn_restart - - self._count_timer = count_timer - - self.resize(self.SIZE_W, self.SIZE_H) - self.setMinimumSize(QtCore.QSize(self.SIZE_W, self.SIZE_H)) - self.setMaximumSize(QtCore.QSize(self.SIZE_W+100, self.SIZE_H+100)) - self.setStyleSheet(style.load_stylesheet()) - - def set_countdown_start(self, countdown): - self._countdown_start = countdown - if not self.is_showed(): - self.reset_countdown() - - def reset_countdown(self): - self._countdown = self._countdown_start - self._update_countdown_label() - - def is_showed(self): - return self._is_showed - - def set_timer_stopped(self): - self._timer_stopped = True - self._refresh_context() - - def _update_countdown_label(self): - self.lbl_rest_time.setText(str(self._countdown)) - - def _on_count_timeout(self): - if self._timer_stopped or not self._is_showed: - self._count_timer.stop() - return - - if self._countdown <= 0: - self._stop_timers() - self.set_timer_stopped() - else: - self._countdown -= 1 - self._update_countdown_label() - - def _refresh_context(self): - self.lbl_question.setVisible(not self._timer_stopped) - self.lbl_rest_time.setVisible(not self._timer_stopped) - self.lbl_stopped.setVisible(self._timer_stopped) - - self.btn_continue.setVisible(not self._timer_stopped) - self.btn_stop.setVisible(not self._timer_stopped) - self.btn_restart.setVisible(self._timer_stopped) - self.btn_close.setVisible(self._timer_stopped) - - def _stop_timers(self): - self.module.stop_timers() - - def _on_stop_clicked(self): - self._stop_timers() - self._close_widget() - - def _on_restart_clicked(self): - self.module.restart_timers() - self._close_widget() - - def _on_continue_clicked(self): - self._close_widget() - - def _close_widget(self): - self._is_showed = False - self._timer_stopped = False - self._refresh_context() - self.hide() - - def showEvent(self, event): - if not self._is_showed: - self._is_showed = True - self._refresh_context() - - if not self._count_timer.isActive(): - self._count_timer.start() - super(WidgetUserIdle, self).showEvent(event) - - def closeEvent(self, event): - event.ignore() - if self._timer_stopped: - self._close_widget() - else: - self._on_continue_clicked() - - -class SignalHandler(QtCore.QObject): - signal_show_message = QtCore.Signal() - signal_stop_timers = QtCore.Signal() - - def __init__(self, module): - super(SignalHandler, self).__init__() - self.module = module - self.signal_show_message.connect(module.show_message) - self.signal_stop_timers.connect(module.stop_timers) diff --git a/server_addon/timers_manager/client/pyproject.toml b/server_addon/timers_manager/client/pyproject.toml deleted file mode 100644 index 364fb33712..0000000000 --- a/server_addon/timers_manager/client/pyproject.toml +++ /dev/null @@ -1,6 +0,0 @@ -[project] -name="timers_manager" -description="AYON TimersManager addon." - -[ayon.runtimeDependencies] -pynput = "^1.7.2" \ No newline at end of file diff --git a/server_addon/timers_manager/package.py b/server_addon/timers_manager/package.py deleted file mode 100644 index 32dc7cfbf4..0000000000 --- a/server_addon/timers_manager/package.py +++ /dev/null @@ -1,10 +0,0 @@ -name = "timers_manager" -title = "Timers Manager" -version = "0.2.0" - -client_dir = "ayon_timers_manager" - -ayon_required_addons = { - "core": ">0.3.2", -} -ayon_compatible_addons = {} diff --git a/server_addon/timers_manager/server/__init__.py b/server_addon/timers_manager/server/__init__.py deleted file mode 100644 index 32e83d295c..0000000000 --- a/server_addon/timers_manager/server/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -from typing import Type - -from ayon_server.addons import BaseServerAddon - -from .settings import TimersManagerSettings - - -class TimersManagerAddon(BaseServerAddon): - settings_model: Type[TimersManagerSettings] = TimersManagerSettings diff --git a/server_addon/timers_manager/server/settings.py b/server_addon/timers_manager/server/settings.py deleted file mode 100644 index 774940730c..0000000000 --- a/server_addon/timers_manager/server/settings.py +++ /dev/null @@ -1,24 +0,0 @@ -from ayon_server.settings import BaseSettingsModel, SettingsField - - -class TimersManagerSettings(BaseSettingsModel): - auto_stop: bool = SettingsField( - True, - title="Auto stop timer", - scope=["studio"], - ) - full_time: int = SettingsField( - 15, - title="Max idle time", - scope=["studio"], - ) - message_time: float = SettingsField( - 0.5, - title="When dialog will show", - scope=["studio"], - ) - disregard_publishing: bool = SettingsField( - False, - title="Disregard publishing", - scope=["studio"], - )