From bb95b1a97d7cfbfdf6276177e9e126d80f18fab1 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Thu, 27 Jun 2024 17:36:54 +0200 Subject: [PATCH] removed hiero addon --- .../hiero/client/ayon_hiero/__init__.py | 13 - server_addon/hiero/client/ayon_hiero/addon.py | 67 - .../hiero/client/ayon_hiero/api/__init__.py | 131 -- .../hiero/client/ayon_hiero/api/constants.py | 3 - .../hiero/client/ayon_hiero/api/events.py | 136 -- .../client/ayon_hiero/api/launchforhiero.py | 85 - .../hiero/client/ayon_hiero/api/lib.py | 1381 ------------ .../hiero/client/ayon_hiero/api/menu.py | 175 -- .../client/ayon_hiero/api/otio/__init__.py | 0 .../ayon_hiero/api/otio/hiero_export.py | 443 ---- .../ayon_hiero/api/otio/hiero_import.py | 535 ----- .../hiero/client/ayon_hiero/api/otio/utils.py | 80 - .../hiero/client/ayon_hiero/api/pipeline.py | 340 --- .../hiero/client/ayon_hiero/api/plugin.py | 946 -------- .../startup/HieroPlayer/PlayerPresets.hrox | 1108 ---------- .../api/startup/Icons/1_add_handles_end.png | Bin 6018 -> 0 bytes .../api/startup/Icons/2_add_handles.png | Bin 6244 -> 0 bytes .../ayon_hiero/api/startup/Icons/3D.png | Bin 10768 -> 0 bytes .../api/startup/Icons/3_add_handles_start.png | Bin 5819 -> 0 bytes .../ayon_hiero/api/startup/Icons/4_2D.png | Bin 7938 -> 0 bytes .../ayon_hiero/api/startup/Icons/edit.png | Bin 8354 -> 0 bytes .../ayon_hiero/api/startup/Icons/fusion.png | Bin 8235 -> 0 bytes .../api/startup/Icons/hierarchy.png | Bin 5711 -> 0 bytes .../ayon_hiero/api/startup/Icons/houdini.png | Bin 5184 -> 0 bytes .../ayon_hiero/api/startup/Icons/layers.psd | Bin 919554 -> 0 bytes .../ayon_hiero/api/startup/Icons/lense.png | Bin 11779 -> 0 bytes .../ayon_hiero/api/startup/Icons/lense1.png | Bin 12964 -> 0 bytes .../ayon_hiero/api/startup/Icons/maya.png | Bin 4629 -> 0 bytes .../ayon_hiero/api/startup/Icons/nuke.png | Bin 7679 -> 0 bytes .../api/startup/Icons/pype_icon.png | Bin 3793 -> 0 bytes .../api/startup/Icons/resolution.png | Bin 3887 -> 0 bytes .../api/startup/Icons/resolution.psd | Bin 65612 -> 0 bytes .../ayon_hiero/api/startup/Icons/retiming.png | Bin 8247 -> 0 bytes .../ayon_hiero/api/startup/Icons/retiming.psd | Bin 158239 -> 0 bytes .../ayon_hiero/api/startup/Icons/review.png | Bin 5611 -> 0 bytes .../ayon_hiero/api/startup/Icons/review.psd | Bin 153287 -> 0 bytes .../ayon_hiero/api/startup/Icons/volume.png | Bin 4862 -> 0 bytes .../api/startup/Icons/z_layer_bg.png | Bin 8042 -> 0 bytes .../api/startup/Icons/z_layer_fg.png | Bin 8002 -> 0 bytes .../api/startup/Icons/z_layer_main.png | Bin 7592 -> 0 bytes .../Python/Startup/SpreadsheetExport.py | 142 -- .../api/startup/Python/Startup/Startup.py | 19 - .../Startup/otioexporter/OTIOExportTask.py | 79 - .../Startup/otioexporter/OTIOExportUI.py | 74 - .../Python/Startup/otioexporter/__init__.py | 7 - .../startup/Python/Startup/project_helpers.py | 246 --- .../Python/Startup/selection_tracker.py | 9 - .../startup/Python/Startup/setFrameRate.py | 166 -- .../Python/StartupUI/PimpMySpreadsheet.py | 845 -------- .../api/startup/Python/StartupUI/Purge.py | 142 -- .../StartupUI/nukeStyleKeyboardShortcuts.py | 34 - .../StartupUI/otioimporter/OTIOImport.py | 424 ---- .../Python/StartupUI/otioimporter/__init__.py | 141 -- .../Python/StartupUI/setPosterFrame.py | 45 - .../pipeline.xml | 198 -- .../pipeline.xml | 198 -- .../pipeline.xml | 198 -- .../hiero/client/ayon_hiero/api/style.css | 26 - .../hiero/client/ayon_hiero/api/tags.py | 197 -- .../hiero/client/ayon_hiero/api/workio.py | 72 - .../plugins/create/create_shot_clip.py | 262 --- .../ayon_hiero/plugins/load/load_clip.py | 230 -- .../ayon_hiero/plugins/load/load_effects.py | 305 --- .../plugins/publish/collect_clip_effects.py | 239 -- .../publish/collect_frame_tag_instances.py | 151 -- .../plugins/publish/collect_tag_tasks.py | 33 - .../plugins/publish/extract_clip_effects.py | 103 - .../plugins/publish/extract_frames.py | 87 - .../plugins/publish/extract_thumbnail.py | 60 - .../publish/integrate_version_up_workfile.py | 24 - .../plugins/publish/precollect_instances.py | 451 ---- .../plugins/publish/precollect_workfile.py | 111 - .../collect_tag_comments.py | 35 - .../publish_old_workflow/precollect_retime.py | 167 -- .../vendor/google/protobuf/__init__.py | 33 - .../vendor/google/protobuf/any_pb2.py | 26 - .../vendor/google/protobuf/api_pb2.py | 32 - .../google/protobuf/compiler/__init__.py | 0 .../google/protobuf/compiler/plugin_pb2.py | 35 - .../vendor/google/protobuf/descriptor.py | 1224 ----------- .../google/protobuf/descriptor_database.py | 177 -- .../vendor/google/protobuf/descriptor_pb2.py | 1925 ----------------- .../vendor/google/protobuf/descriptor_pool.py | 1295 ----------- .../vendor/google/protobuf/duration_pb2.py | 26 - .../vendor/google/protobuf/empty_pb2.py | 26 - .../vendor/google/protobuf/field_mask_pb2.py | 26 - .../google/protobuf/internal/__init__.py | 0 .../protobuf/internal/_parameterized.py | 443 ---- .../protobuf/internal/api_implementation.py | 112 - .../google/protobuf/internal/builder.py | 130 -- .../google/protobuf/internal/containers.py | 710 ------ .../google/protobuf/internal/decoder.py | 1029 --------- .../google/protobuf/internal/encoder.py | 829 ------- .../protobuf/internal/enum_type_wrapper.py | 124 -- .../protobuf/internal/extension_dict.py | 213 -- .../protobuf/internal/message_listener.py | 78 - .../internal/message_set_extensions_pb2.py | 36 - .../internal/missing_enum_values_pb2.py | 37 - .../internal/more_extensions_dynamic_pb2.py | 29 - .../protobuf/internal/more_extensions_pb2.py | 41 - .../protobuf/internal/more_messages_pb2.py | 556 ----- .../protobuf/internal/no_package_pb2.py | 27 - .../protobuf/internal/python_message.py | 1539 ------------- .../google/protobuf/internal/type_checkers.py | 435 ---- .../protobuf/internal/well_known_types.py | 878 -------- .../google/protobuf/internal/wire_format.py | 268 --- .../vendor/google/protobuf/json_format.py | 912 -------- .../vendor/google/protobuf/message.py | 424 ---- .../vendor/google/protobuf/message_factory.py | 185 -- .../vendor/google/protobuf/proto_builder.py | 134 -- .../vendor/google/protobuf/pyext/__init__.py | 0 .../google/protobuf/pyext/cpp_message.py | 65 - .../google/protobuf/pyext/python_pb2.py | 34 - .../vendor/google/protobuf/reflection.py | 95 - .../vendor/google/protobuf/service.py | 228 -- .../google/protobuf/service_reflection.py | 295 --- .../google/protobuf/source_context_pb2.py | 26 - .../vendor/google/protobuf/struct_pb2.py | 36 - .../vendor/google/protobuf/symbol_database.py | 194 -- .../vendor/google/protobuf/text_encoding.py | 110 - .../vendor/google/protobuf/text_format.py | 1795 --------------- .../vendor/google/protobuf/timestamp_pb2.py | 26 - .../vendor/google/protobuf/type_pb2.py | 42 - .../vendor/google/protobuf/util/__init__.py | 0 .../google/protobuf/util/json_format_pb2.py | 72 - .../protobuf/util/json_format_proto3_pb2.py | 129 -- .../vendor/google/protobuf/wrappers_pb2.py | 42 - .../hiero/client/ayon_hiero/version.py | 3 - server_addon/hiero/package.py | 9 - server_addon/hiero/server/__init__.py | 13 - .../hiero/server/settings/__init__.py | 10 - server_addon/hiero/server/settings/common.py | 97 - .../hiero/server/settings/create_plugins.py | 96 - server_addon/hiero/server/settings/filters.py | 25 - server_addon/hiero/server/settings/imageio.py | 185 -- .../hiero/server/settings/loader_plugins.py | 37 - server_addon/hiero/server/settings/main.py | 62 - .../hiero/server/settings/publish_plugins.py | 56 - .../hiero/server/settings/scriptsmenu.py | 40 - 139 files changed, 28779 deletions(-) delete mode 100644 server_addon/hiero/client/ayon_hiero/__init__.py delete mode 100644 server_addon/hiero/client/ayon_hiero/addon.py delete mode 100644 server_addon/hiero/client/ayon_hiero/api/__init__.py delete mode 100644 server_addon/hiero/client/ayon_hiero/api/constants.py delete mode 100644 server_addon/hiero/client/ayon_hiero/api/events.py delete mode 100644 server_addon/hiero/client/ayon_hiero/api/launchforhiero.py delete mode 100644 server_addon/hiero/client/ayon_hiero/api/lib.py delete mode 100644 server_addon/hiero/client/ayon_hiero/api/menu.py delete mode 100644 server_addon/hiero/client/ayon_hiero/api/otio/__init__.py delete mode 100644 server_addon/hiero/client/ayon_hiero/api/otio/hiero_export.py delete mode 100644 server_addon/hiero/client/ayon_hiero/api/otio/hiero_import.py delete mode 100644 server_addon/hiero/client/ayon_hiero/api/otio/utils.py delete mode 100644 server_addon/hiero/client/ayon_hiero/api/pipeline.py delete mode 100644 server_addon/hiero/client/ayon_hiero/api/plugin.py delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/HieroPlayer/PlayerPresets.hrox delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Icons/1_add_handles_end.png delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Icons/2_add_handles.png delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Icons/3D.png delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Icons/3_add_handles_start.png delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Icons/4_2D.png delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Icons/edit.png delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Icons/fusion.png delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Icons/hierarchy.png delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Icons/houdini.png delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Icons/layers.psd delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Icons/lense.png delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Icons/lense1.png delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Icons/maya.png delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Icons/nuke.png delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Icons/pype_icon.png delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Icons/resolution.png delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Icons/resolution.psd delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Icons/retiming.png delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Icons/retiming.psd delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Icons/review.png delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Icons/review.psd delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Icons/volume.png delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Icons/z_layer_bg.png delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Icons/z_layer_fg.png delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Icons/z_layer_main.png delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Python/Startup/SpreadsheetExport.py delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Python/Startup/Startup.py delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Python/Startup/otioexporter/OTIOExportTask.py delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Python/Startup/otioexporter/OTIOExportUI.py delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Python/Startup/otioexporter/__init__.py delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Python/Startup/project_helpers.py delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Python/Startup/selection_tracker.py delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Python/Startup/setFrameRate.py delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Python/StartupUI/PimpMySpreadsheet.py delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Python/StartupUI/Purge.py delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Python/StartupUI/nukeStyleKeyboardShortcuts.py delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Python/StartupUI/otioimporter/OTIOImport.py delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Python/StartupUI/otioimporter/__init__.py delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/Python/StartupUI/setPosterFrame.py delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/TaskPresets/10.5/Processors/hiero.exporters.FnShotProcessor.ShotProcessor/pipeline.xml delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/TaskPresets/11.1/Processors/hiero.exporters.FnShotProcessor.ShotProcessor/pipeline.xml delete mode 100644 server_addon/hiero/client/ayon_hiero/api/startup/TaskPresets/11.2/hiero.exporters.FnShotProcessor.ShotProcessor/pipeline.xml delete mode 100644 server_addon/hiero/client/ayon_hiero/api/style.css delete mode 100644 server_addon/hiero/client/ayon_hiero/api/tags.py delete mode 100644 server_addon/hiero/client/ayon_hiero/api/workio.py delete mode 100644 server_addon/hiero/client/ayon_hiero/plugins/create/create_shot_clip.py delete mode 100644 server_addon/hiero/client/ayon_hiero/plugins/load/load_clip.py delete mode 100644 server_addon/hiero/client/ayon_hiero/plugins/load/load_effects.py delete mode 100644 server_addon/hiero/client/ayon_hiero/plugins/publish/collect_clip_effects.py delete mode 100644 server_addon/hiero/client/ayon_hiero/plugins/publish/collect_frame_tag_instances.py delete mode 100644 server_addon/hiero/client/ayon_hiero/plugins/publish/collect_tag_tasks.py delete mode 100644 server_addon/hiero/client/ayon_hiero/plugins/publish/extract_clip_effects.py delete mode 100644 server_addon/hiero/client/ayon_hiero/plugins/publish/extract_frames.py delete mode 100644 server_addon/hiero/client/ayon_hiero/plugins/publish/extract_thumbnail.py delete mode 100644 server_addon/hiero/client/ayon_hiero/plugins/publish/integrate_version_up_workfile.py delete mode 100644 server_addon/hiero/client/ayon_hiero/plugins/publish/precollect_instances.py delete mode 100644 server_addon/hiero/client/ayon_hiero/plugins/publish/precollect_workfile.py delete mode 100644 server_addon/hiero/client/ayon_hiero/plugins/publish_old_workflow/collect_tag_comments.py delete mode 100644 server_addon/hiero/client/ayon_hiero/plugins/publish_old_workflow/precollect_retime.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/__init__.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/any_pb2.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/api_pb2.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/compiler/__init__.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/compiler/plugin_pb2.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/descriptor.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/descriptor_database.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/descriptor_pb2.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/descriptor_pool.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/duration_pb2.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/empty_pb2.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/field_mask_pb2.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/__init__.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/_parameterized.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/api_implementation.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/builder.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/containers.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/decoder.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/encoder.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/enum_type_wrapper.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/extension_dict.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/message_listener.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/message_set_extensions_pb2.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/missing_enum_values_pb2.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/more_extensions_dynamic_pb2.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/more_extensions_pb2.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/more_messages_pb2.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/no_package_pb2.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/python_message.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/type_checkers.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/well_known_types.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/internal/wire_format.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/json_format.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/message.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/message_factory.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/proto_builder.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/pyext/__init__.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/pyext/cpp_message.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/pyext/python_pb2.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/reflection.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/service.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/service_reflection.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/source_context_pb2.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/struct_pb2.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/symbol_database.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/text_encoding.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/text_format.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/timestamp_pb2.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/type_pb2.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/util/__init__.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/util/json_format_pb2.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/util/json_format_proto3_pb2.py delete mode 100644 server_addon/hiero/client/ayon_hiero/vendor/google/protobuf/wrappers_pb2.py delete mode 100644 server_addon/hiero/client/ayon_hiero/version.py delete mode 100644 server_addon/hiero/package.py delete mode 100644 server_addon/hiero/server/__init__.py delete mode 100644 server_addon/hiero/server/settings/__init__.py delete mode 100644 server_addon/hiero/server/settings/common.py delete mode 100644 server_addon/hiero/server/settings/create_plugins.py delete mode 100644 server_addon/hiero/server/settings/filters.py delete mode 100644 server_addon/hiero/server/settings/imageio.py delete mode 100644 server_addon/hiero/server/settings/loader_plugins.py delete mode 100644 server_addon/hiero/server/settings/main.py delete mode 100644 server_addon/hiero/server/settings/publish_plugins.py delete mode 100644 server_addon/hiero/server/settings/scriptsmenu.py 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 4561745d663a481a3feb92da8d6a9efde9adbb47..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6018 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 THKO#+zvL(*OXNcXbi_XZHLP4; 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 bb4c1802aac54e60340341777b71e2dfd8d3a364..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6244 zcmb_h2UJtpx~2}B1lIRMNp)vyr7PE?t63R-FMf^S|?|pv%mfQ-{1CLD@m|DV#>Q$d@mCd6R)|M zksaf1vU_oIFuns+rlT1*F0z>mm5Jpp@9xEXKsce1iD}Pqg2OS|F>5OnmPAxR<4731 z3Y|!1pqZGobm?R?))!9$VDR1qe{JA$T@w&Mz-a@W;nrYlvLW7wU=~Wj+lL-;z=rx_ zkvO2P4nT{JVh|AVG&F!t^z)~p=-R;VyeP(a_q8ez@Et<))duSC8U!4(wgniHD0l!| z1p&fB)ZhShqzVK9Q$r#T1E64thALP?6#@f65GXY;3JL}M`~Vr&C^#>aosr2;TZ|`d zpbw2kMyaX>2M4PJ!&FEVZ&e5qiBttcRiRK20|BCj_|wpIkUv%S4+bMV6-yzIX#|o# zV3!e%AqCR3fefWTTp*Hv(fU(=hKUg{RXUoi3Q+;?y7V20!~VjN11WyrjpMMYct1Q5 z?@yyLu#jI^vJZ(yqWX~j1@*7#e=@)bt+n+p8-J;VNc?4jN;3{(xbZU}e~G3#gpl#7 zc6cf&kb=b<2Qg&I?s`K;8B*|Q8j0dSBKiH1DBC|I0}Ks!6N3aOIurbHq+qJjpVr`w z&@{X@aCaUAhJ&CG2S(x`>L|F{AutpL2LFIslW+vDkUv8;zC*z%I1~kg{1cQ>H8?a4 z{l9{7Sd$fq+BdHDC}J5{Ut!VP1HUI#>-2 z(!k@8Aha3`1IB>CI4B(d$9f|YHgLBJcGv%C2pkE^;P{6;2vh@!#o#a?JO%;$HiKVK96B0v9DBz~?B_Q5kq z|E6kxSf`S_Xu)U-Uf-LM%YUaaRR5KJDmv)z)g$0w#wLizfYh-_Fh~u}$Riq!R0rYI z(HIOK422>PjOzR$>#x*98T;k0M*0uc|D?zIp#8n^jICc4_@Ddp?{&-n^ye=(hW}T8 zzE|syQd9l!Rrr1GPY1*wCCxZ>c89-?JI2GW0~7Dh2o;5K91=EVt}-$4SC|{=JJ569 z^Y(38He-wq}*wf zbI>JQ$7Wge_b3g@^VbsJfS*^^8@2+wzKoAGRunXO%H4->`PAa4WqtaQxchWl>1}c&&`PJV$eU1p84l2Z7&; zj0zPv-N(d;NgwIgY_m@gWQ6_@nHrfYY?= zO_pficxE!$xYt8@bgzwy_SYl#OLgzMh)uNPB*6)*x9`?oiOy7l?7i@WY`rNyoW0zz zGeEuJ^)&Z#mRbm+ZZ<{sgoVsT)tnTwtvoksk-Mzm&?c)fg zcewb*#I5H(aM8M;r19;b>FjF~GlJGa9UY0jhu);CyciHkdL$?q&lwkhp7I^>8 z>0w09QAH+gJ%aTi!x52G>25o5WdMep;87Gvk#hCMszemdMo9{B3q6*vvgP11SE%nt zRYb~5dnwI_D$crEX{jfRbYwm1dWx4Zaa1y57Z121twq&+HzMFQyn*nIKPtShV~TJx zjp8Ymr)Yn}+iqtLiuO&u9pxM++H(AnVV87)BT2}lmAksB%zuq$=M&@*q|2nyHAU~)M=hx z1&WtgRIDxe9e_vyC05=vex0uz&8ty3m=~S8Ua-2~__u<3r&6{^UQS{>WIr>DP->-s zSayr})hMmGoG=ZU&He1}2apdjBdh6E*ZDjiRf{f;KE2=BwB{}tYu(Jp6%F774*`J3 zu$7%f%mA9lK3gc_BBqEQsHE&UPD_53qhz&XSUpj}cFp7jcY1P}j7bEK{LZYTwEUUMc*khT&QM`J0^i&R%p@swiz)v^} zwX5@%$AbE}cN|LLoKg3*8jo18O16;|GL{RqqOV@Mb$qg+5E3RoT_F&nNt`GEMT?t7 z4!9z&O`X+~B|x*J+c#&wf`+%E7BBAUx7MB4)_cIK7Wjrm;>5tDuarB-3$3K7NRZnQAkopQ-1qk4a_XoLuT>Q`p}%>LiJj ztlM}cXia|OG-mP)gwctf3GTW6XhOk46bBZ)c$@|Ff^)fp%sKUKuu4ta!vbL3XCSUH z9x%x_5xmjx>2rDjyo~8gL_tbKT|!H56atXMrgdtwQWa*O=VeM*2y^^unk?${!sHn* z#$@FS?|v&6GlzsIo(o)r!55PniFnbeL%r1ZPujH#xYlcomJ6S_%e#g@q;ETi#eV)U z*7QaH-ftTA; zDr;eWI9UeSPX=@-Ku&S8hBN!<_p!pLRWG%})fwHvwmIviQ0;>GJhKsD1PJNq0H;a= zjz|V9ozK?e6AC&n43L9gF8$Ukkw1R2a=@eYDqT`&kgMsX$NcO|^VM1w_4;|ellM`m z!A@^rniasLw z<3Meb}A73S)8 zt@6Iehs!_aZ2vGh8rRM4BK#G!;3+wy8NV9Dl4^w-EokL`8s@N>Wb~yw(fH7n61Hod z_cA|SsPlTcfIVyS zq7dmx3Uo;Ci{%lCO^Ax$w$awB8U;Syt5}1$J4Os&oP6geE!Hwf7k`v#)<5gYZ&3AY zo;Ige3%IYa(o-OEHp|x*z_whVI%cY)c%mbmcvFLR`EuW_gITtG`Sm>|=R*b|%e2Q~ z2V`%IIj$u?ILO;?A-Hwt>(bk>!CY86Y#0Pr-oq(M_2_aCGZZU<`^K?yalEgY;)`#V z-?CBcV_BrBxm=N3Id7C!fZ6~%nu4Tb! zT3XX3dtaYC7THzYMk<`ez}j=xbA|8dXH591R(5hb9WGoPGqJ;>#&SF_xb&x8f1WzH zBPLtZPW2B^K7IFg&zqC1;*A${`UcNln+*crzel2a)X|T|BS{+j*bI?lme1j)Py|eh z108Aguk->RSUgcFG<3#|L5_=p7o&#}$Cl6d;?z83M9GQSU z9)+cCu;-1KIr+-52xMfI%*Un2MfLl%;QeAPh+G^9E4MN?qVLshTvQd#c7Z6^ z+U>}&rVVllT6c4ddOk6mzrDVE3hv#T+ZJ{J29)_+7;%Dc1I(2t&mm$Um+`g1`C`p% zH%{wxS_uL7QSceW`k=y1dsmlI(3Edh#);DUm}ng?O<<;;k3oj(zFY6!w3;Z~7sKT0 zkzaIPX0dXf&noM^Q&#cr{G}J4s`so*pE`9iJW(N!9{OzE_g1}oeR^lF#DxK$3>coz zPglcz(K9hcCr~Xn&!zN5Vd)D6uIT0ng!A?WfW@dd<7|vuD)t`4^16Enh0#|@(jS>( zcVs!<^3XL<)ZgtKSf*0mK0)1Y`WE!rt(v>cz;2K>`8N3LgSWmXOS=VoY{TPSNi{Kz zEgo);!wPe6uAyV*oFtb4+=5&xv3B>&dH65 zO0AZAt=+dB#nXdP%kQOpVl3mNEm1?wPq|j^E{vHrKDkgV>s1(ZK4BgyrL_V` zNtQM)ggZOx7`HB`?or~J2;l)|NuRib>M^*wx@q!~es5?(12WFvw)1<$Z$4Mt4+^?@ z)UI!=cbl^F5t{;LH@;M2%W488KFrL$fY#kx#uPkg9=IgNxfad4DX#o6;=YNGs$5&w z^vt^Xg}czI+zD;0oOPw*PSVWR*_KaxZ%HlZ>%OwQ?uagMDn9)e!uht1O|q@;ZRgsFAR2B!+| zPFs>5)4CQ_dS~S#CLZ@g8@gWIALaJ>Lmok2pV+P+TN z7J#U1e77~dkyXp={L$xm{?cnoN*y=#Jj*jJsyVpM%wyhLVer?9!sCw*X>*opNpiBb zh|RsebOTvUyKH!M&*;&Y$bq!Q%_Rro*7J|awL5mtNb`xc((>V0Y!GQ;$Ikf+%KDxb9;Aht@!fiY zTG!b=y=5W)Ipg!urx|U;mZtek`sTh5G<2iShg#QO@`RCv-tjG(hc>X@hXnl*hnAUTS!RGE&si?$ZJkOD-2#>!{H+0QSbLq??Yeq zA{MtDFR~(i2?fzi)42cKYu5S0OM}+I_9f=nexadPMC&VE_MA4@4dxHLCnVcMR!;E; zKT~q=*zZhKmaTpF`{xY27VK$?^yyDY_qRf@vmdXRi=ALn^dMtcv+(X5C-?QtDcZhV zr8pTE!%w=^hUr?S%XfC!6dCs}K3s3My3t_!<<#$w!yI#h9VFo8O>aWC;=%&p+Iimn zmUpX{n>cIy@(PJvM4njJ@}`)4zy6Dx>A$1Cgh`m><&fBbLzG|;K&!{MHxOLyg^UHe-Qkm`SRAwHI z_V2^C+j4SWhKOlH1EaA*Gg&tcA97b8Fh^M|E|*HCG}h-?s00q)maKWG16}DG?3zCh zIx)ggtpDv2|Jh?XIK17VCBP)!O-u#sl5ONz+_AP@2xv9tiX3g0mv{W))_EOYR?v9r zP#cjg#YXq(!tpbfJ_dL6jeOLDO4wUw63!ybRb+-Vz8;LoTR4q#=%WL>#3MPJky;y55y zsQKt-ok6;FiQvu3>zx7kH_WX|{VY2T8@fqJeC9sDF9+YeA1cgl&(Yruj_z3Ku_tjk zG~bNBz1ThQ<*~gWIiP2WqjKtSORuKKW@mxr^Yd8?D} 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 2de7a72775c3d3d9fc65b44200daf2a7bac69e72..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10768 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 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 18555698fed88ae8c837ea8aed6400035c2d4c51..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7938 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 Z|Iq*A36g#S?AO24mklipO7xsV{|~;7Zyx{v 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 97e42054e75fafcfeaef180b0b41dee58938b244..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8354 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 Q{)^z6mZ4_ZRr~P&1F9fkApigX 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 2e498edd69c3c69074de9763c4d80ec4a6346636..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8235 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 B_^JQ^ 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 d8c842dd1727298ddd0b07aaf41da90abe72db27..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5184 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 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 20ba0e81b08b95b4d8672bf40ee41ff2ea16042c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 919554 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%0D>nTwvj;}f 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 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 1ad1264807f1e8972d7b0fe331bf78bcbea7b8d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12964 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 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 fcfa47ae4f6aca36e427b479314b058ad36213a4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4629 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 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 bfacf6eeedc753db0d77e661843a78b0eb13ce38..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3793 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 b;3u>qRjE!lxug$XMKJrL$8D;P_+R@UX<7IA 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 83803fc36d154cd233e9dd8c67bd93032ab4b8ed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3887 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 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 1c6f22e02cb7892b80036ef2336541ffb002f39c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8247 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 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 bac6fc6b58ff8e8bc92308b67e6897dbf3b6faae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 158239 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à^d2B1c@rm1R%sALia~GMZnLAg0vG663?KtFg`7y z?U3#yc;}O#LnUklknS~%#ZLnNJt6T9q*}dtTEeBHh&l-GL4daLyYq+8I(%)>j(P<{>K zZA3^OE2W5i;;%qTL4^7vVDZvb@@ugo5UmLrgJZcOJFmT3IpNWfmJ=fEbu#tTMoJ;WpBT zK!#V1tb@fAr~1*sx%M6QK@8lQSSNo_V%0AbW9E$1X6=HwMkK?%So8hE)7z(FmIgQ( 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 Cyl|`l 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 0d894b698717f88fb7c837faa61ce3a8f569b03e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5611 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 m2;b#S0rqnk(eW35a;YgM)a!PIh3)ec6-% 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 779fcf156d4cab3947f13ac80eb2ef414319f18c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 153287 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 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 e5e12006536e2f0866f7f9e60907f9add3172214..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4862 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 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 51742b5df20be34e94c96bb0ebb287dc5d4cac23..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8042 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 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 01e5f4f81614013885190b2d460f71ad32d2c9b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8002 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 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" - } - ] -}