From 6a599da37a0cc5ce7a695d7a9f2ca33d236824f0 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 12 Apr 2021 17:50:27 +0200 Subject: [PATCH 01/12] disabled attributes options for now --- .../event_handlers_user/action_prepare_project.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py b/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py index 7f674310fc..367b4b9e69 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py +++ b/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py @@ -63,9 +63,9 @@ class PrepareProject(BaseAction): root_items = self.prepare_root_items(anatomy) - ca_items, multiselect_enumerators = ( - self.prepare_custom_attribute_items(project_defaults) - ) + # ca_items, multiselect_enumerators = ( + # self.prepare_custom_attribute_items(project_defaults) + # ) self.log.debug("Heavy items are ready. Preparing last items group.") @@ -94,7 +94,7 @@ class PrepareProject(BaseAction): "value": "

Set basic Attributes:

" }) - items.extend(ca_items) + # items.extend(ca_items) # This item will be last (before enumerators) # - sets value of auto synchronization @@ -108,9 +108,9 @@ class PrepareProject(BaseAction): # Add autosync attribute items.append(auto_sync_item) - # Add enumerator items at the end - for item in multiselect_enumerators: - items.append(item) + # # Add enumerator items at the end + # for item in multiselect_enumerators: + # items.append(item) return { "items": items, From dfe35176f6cbb9e13cf928f3e2ea5e5358f4259f Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 12 Apr 2021 17:50:43 +0200 Subject: [PATCH 02/12] roots are filled with current values --- .../action_prepare_project.py | 34 +++++++------------ 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py b/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py index 367b4b9e69..16921f1bda 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py +++ b/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py @@ -3,7 +3,10 @@ import json from openpype.modules.ftrack.lib import BaseAction, statics_icon from openpype.api import config, Anatomy -from openpype.modules.ftrack.lib.avalon_sync import get_pype_attr +from openpype.modules.ftrack.lib.avalon_sync import ( + get_pype_attr, + CUST_ATTR_AUTO_SYNC +) class PrepareProject(BaseAction): @@ -44,24 +47,10 @@ class PrepareProject(BaseAction): self.log.debug("Loading custom attributes") - project_name = entities[0]["full_name"] + project_entity = entities[0] + project_name = project_entity["full_name"] - project_defaults = ( - config.get_presets(project_name) - .get("ftrack", {}) - .get("project_defaults", {}) - ) - - anatomy = Anatomy(project_name) - if not anatomy.roots: - return { - "success": False, - "message": ( - "Have issues with loading Roots for project \"{}\"." - ).format(anatomy.project_name) - } - - root_items = self.prepare_root_items(anatomy) + root_items = self.prepare_root_items(project_name) # ca_items, multiselect_enumerators = ( # self.prepare_custom_attribute_items(project_defaults) @@ -99,10 +88,13 @@ class PrepareProject(BaseAction): # This item will be last (before enumerators) # - sets value of auto synchronization auto_sync_name = "avalon_auto_sync" + auto_sync_value = project_entity["custom_attributes"].get( + CUST_ATTR_AUTO_SYNC, False + ) auto_sync_item = { "name": auto_sync_name, "type": "boolean", - "value": project_defaults.get(auto_sync_name, False), + "value": auto_sync_value, "label": "AutoSync to Avalon" } # Add autosync attribute @@ -117,10 +109,10 @@ class PrepareProject(BaseAction): "title": title } - def prepare_root_items(self, anatomy): + def prepare_root_items(self, project_name): root_items = [] self.log.debug("Root items preparation begins.") - + anatomy = Anatomy(project_name) root_names = anatomy.root_names() roots = anatomy.roots From 6695fa7382a2058ab7b9a01d3bab63997e74b57e Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 12 Apr 2021 19:06:33 +0200 Subject: [PATCH 03/12] interface inputs are created using project settings --- .../action_prepare_project.py | 127 +++++++----------- 1 file changed, 46 insertions(+), 81 deletions(-) diff --git a/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py b/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py index 16921f1bda..5b3828f554 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py +++ b/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py @@ -1,8 +1,12 @@ import os import json -from openpype.modules.ftrack.lib import BaseAction, statics_icon -from openpype.api import config, Anatomy +from openpype.api import config, ProjectSettings + +from openpype.modules.ftrack.lib import ( + BaseAction, + statics_icon +) from openpype.modules.ftrack.lib.avalon_sync import ( get_pype_attr, CUST_ATTR_AUTO_SYNC @@ -50,11 +54,20 @@ class PrepareProject(BaseAction): project_entity = entities[0] project_name = project_entity["full_name"] - root_items = self.prepare_root_items(project_name) + try: + project_settings = ProjectSettings(project_name) + except ValueError: + return { + "message": "Project is not synchronized yet", + "success": False + } - # ca_items, multiselect_enumerators = ( - # self.prepare_custom_attribute_items(project_defaults) - # ) + project_anatom_settings = project_settings["project_anatomy"] + root_items = self.prepare_root_items(project_anatom_settings) + + ca_items, multiselect_enumerators = ( + self.prepare_custom_attribute_items(project_anatom_settings) + ) self.log.debug("Heavy items are ready. Preparing last items group.") @@ -83,7 +96,7 @@ class PrepareProject(BaseAction): "value": "

Set basic Attributes:

" }) - # items.extend(ca_items) + items.extend(ca_items) # This item will be last (before enumerators) # - sets value of auto synchronization @@ -100,22 +113,19 @@ class PrepareProject(BaseAction): # Add autosync attribute items.append(auto_sync_item) - # # Add enumerator items at the end - # for item in multiselect_enumerators: - # items.append(item) + # Add enumerator items at the end + for item in multiselect_enumerators: + items.append(item) return { "items": items, "title": title } - def prepare_root_items(self, project_name): - root_items = [] + def prepare_root_items(self, project_anatom_settings): self.log.debug("Root items preparation begins.") - anatomy = Anatomy(project_name) - root_names = anatomy.root_names() - roots = anatomy.roots + root_items = [] root_items.append({ "type": "label", "value": "

Check your Project root settings

" @@ -135,85 +145,40 @@ class PrepareProject(BaseAction): ) }) - default_roots = anatomy.roots - while isinstance(default_roots, dict): - key = tuple(default_roots.keys())[0] - default_roots = default_roots[key] - empty_text = "Enter root path here..." - # Root names is None when anatomy templates contain "{root}" - all_platforms = ["windows", "linux", "darwin"] - if root_names is None: - root_items.append(self.item_splitter) - # find first possible key - for platform in all_platforms: - value = default_roots.raw_data.get(platform) or "" - root_items.append({ - "label": platform, - "name": "__root__{}".format(platform), - "type": "text", - "value": value, - "empty_text": empty_text - }) - return root_items - - root_name_data = {} - missing_roots = [] - for root_name in root_names: - root_name_data[root_name] = {} - if not isinstance(roots, dict): - missing_roots.append(root_name) - continue - - root_item = roots.get(root_name) - if not root_item: - missing_roots.append(root_name) - continue - - for platform in all_platforms: - root_name_data[root_name][platform] = ( - root_item.raw_data.get(platform) or "" - ) - - if missing_roots: - default_values = {} - for platform in all_platforms: - default_values[platform] = ( - default_roots.raw_data.get(platform) or "" - ) - - for root_name in missing_roots: - root_name_data[root_name] = default_values - - root_names = list(root_name_data.keys()) - root_items.append({ - "type": "hidden", - "name": "__rootnames__", - "value": json.dumps(root_names) - }) - - for root_name, values in root_name_data.items(): + roots_entity = project_anatom_settings["roots"] + for root_name, root_entity in roots_entity.items(): root_items.append(self.item_splitter) root_items.append({ "type": "label", "value": "Root: \"{}\"".format(root_name) }) - for platform, value in values.items(): + for platform_name, value_entity in root_entity.items(): root_items.append({ - "label": platform, - "name": "__root__{}{}".format(root_name, platform), + "label": platform_name, + "name": "__root__{}{}".format(root_name, platform_name), "type": "text", - "value": value, + "value": value_entity.value, "empty_text": empty_text }) + root_items.append({ + "type": "hidden", + "name": "__rootnames__", + "value": json.dumps(list(roots_entity.keys())) + }) + self.log.debug("Root items preparation ended.") return root_items - def _attributes_to_set(self, project_defaults): + def _attributes_to_set(self, project_anatom_settings): attributes_to_set = {} + attribute_values_by_key = {} + for key, entity in project_anatom_settings["attributes"].items(): + attribute_values_by_key[key] = entity.value + cust_attrs, hier_cust_attrs = get_pype_attr(self.session, True) for attr in hier_cust_attrs: @@ -223,7 +188,7 @@ class PrepareProject(BaseAction): attributes_to_set[key] = { "label": attr["label"], "object": attr, - "default": project_defaults.get(key) + "default": attribute_values_by_key.get(key) } for attr in cust_attrs: @@ -235,7 +200,7 @@ class PrepareProject(BaseAction): attributes_to_set[key] = { "label": attr["label"], "object": attr, - "default": project_defaults.get(key) + "default": attribute_values_by_key.get(key) } # Sort by label @@ -245,10 +210,10 @@ class PrepareProject(BaseAction): )) return attributes_to_set - def prepare_custom_attribute_items(self, project_defaults): + def prepare_custom_attribute_items(self, project_anatom_settings): items = [] multiselect_enumerators = [] - attributes_to_set = self._attributes_to_set(project_defaults) + attributes_to_set = self._attributes_to_set(project_anatom_settings) self.log.debug("Preparing interface for keys: \"{}\"".format( str([key for key in attributes_to_set]) From 610abac38191933ec065ab94e30ed418575c6955 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 12 Apr 2021 19:49:19 +0200 Subject: [PATCH 04/12] using new way of storing anatomy data --- .../action_prepare_project.py | 100 +++++------------- 1 file changed, 27 insertions(+), 73 deletions(-) diff --git a/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py b/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py index 5b3828f554..e7b8bfc3e1 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py +++ b/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py @@ -28,7 +28,6 @@ class PrepareProject(BaseAction): settings_key = "prepare_project" # Key to store info about trigerring create folder structure - create_project_structure_key = "create_folder_structure" item_splitter = {'type': 'label', 'value': '---'} def discover(self, session, entities, event): @@ -76,19 +75,6 @@ class PrepareProject(BaseAction): # Add root items items.extend(root_items) - items.append(self.item_splitter) - - # Ask if want to trigger Action Create Folder Structure - items.append({ - "type": "label", - "value": "

Want to create basic Folder Structure?

" - }) - items.append({ - "name": self.create_project_structure_key, - "type": "boolean", - "value": False, - "label": "Check if Yes" - }) items.append(self.item_splitter) items.append({ @@ -157,7 +143,7 @@ class PrepareProject(BaseAction): for platform_name, value_entity in root_entity.items(): root_items.append({ "label": platform_name, - "name": "__root__{}{}".format(root_name, platform_name), + "name": "__root__{}__{}".format(root_name, platform_name), "type": "text", "value": value_entity.value, "empty_text": empty_text @@ -320,24 +306,15 @@ class PrepareProject(BaseAction): root_names = in_data.pop("__rootnames__", None) root_data = {} - if root_names: - for root_name in json.loads(root_names): - root_data[root_name] = {} - for key, value in tuple(root_values.items()): - if key.startswith(root_name): - _key = key[len(root_name):] - root_data[root_name][_key] = value + for root_name in json.loads(root_names): + root_data[root_name] = {} + for key, value in tuple(root_values.items()): + prefix = "{}__".format(root_name) + if not key.startswith(prefix): + continue - else: - for key, value in root_values.items(): - root_data[key] = value - - # TODO implement creating of anatomy for new projects - # project_name = entities[0]["full_name"] - # anatomy = Anatomy(project_name) - - # pop out info about creating project structure - create_proj_struct = in_data.pop(self.create_project_structure_key) + _key = key[len(prefix):] + root_data[root_name][_key] = value # Find hidden items for multiselect enumerators keys_to_process = [] @@ -364,53 +341,30 @@ class PrepareProject(BaseAction): new_key = item.replace(name, "") in_data[key].append(new_key) - self.log.debug("Setting Custom Attribute values:") - entity = entities[0] + self.log.debug("Setting Custom Attribute values") + + project_name = entities[0]["full_name"] + project_settings = ProjectSettings(project_name) + project_anatomy_settings = project_settings["project_anatomy"] + project_anatomy_settings["roots"] = root_data + + custom_attribute_values = {} + attributes_entity = project_anatomy_settings["attributes"] for key, value in in_data.items(): + if key not in attributes_entity: + custom_attribute_values[key] = value + else: + attributes_entity[key] = value + + project_settings.save() + + entity = entities[0] + for key, value in custom_attribute_values.items(): entity["custom_attributes"][key] = value self.log.debug("- Key \"{}\" set to \"{}\"".format(key, value)) - session.commit() - - # Create project structure - self.create_project_specific_config(entities[0]["full_name"], in_data) - - # Trigger Create Project Structure action - if create_proj_struct is True: - self.trigger_action("create.project.structure", event) - return True - def create_project_specific_config(self, project_name, json_data): - self.log.debug("*** Creating project specifig configs ***") - project_specific_path = project_overrides_dir_path(project_name) - if not os.path.exists(project_specific_path): - os.makedirs(project_specific_path) - self.log.debug(( - "Project specific config folder for project \"{}\" created." - ).format(project_name)) - - # Presets #################################### - self.log.debug("--- Processing Presets Begins: ---") - - project_defaults_dir = os.path.normpath(os.path.join( - project_specific_path, "presets", "ftrack" - )) - project_defaults_path = os.path.normpath(os.path.join( - project_defaults_dir, "project_defaults.json" - )) - # Create folder if not exist - if not os.path.exists(project_defaults_dir): - self.log.debug("Creating Ftrack Presets folder: \"{}\"".format( - project_defaults_dir - )) - os.makedirs(project_defaults_dir) - - with open(project_defaults_path, 'w') as file_stream: - json.dump(json_data, file_stream, indent=4) - - self.log.debug("*** Creating project specifig configs Finished ***") - def register(session): '''Register plugin. Called when used as an plugin.''' From ef8601422aa884ce8279dfe7b4d271f706f00074 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 13 Apr 2021 13:57:08 +0200 Subject: [PATCH 05/12] renamed "Prepare Project" to "Prepare Project (Local)" --- .../action_prepare_project.py | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py b/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py index e7b8bfc3e1..adc6a97fb8 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py +++ b/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py @@ -13,25 +13,21 @@ from openpype.modules.ftrack.lib.avalon_sync import ( ) -class PrepareProject(BaseAction): - '''Edit meta data action.''' +class PrepareProjectLocal(BaseAction): + """Prepare project attributes in Anatomy.""" - #: Action identifier. - identifier = 'prepare.project' - #: Action label. - label = 'Prepare Project' - #: Action description. - description = 'Set basic attributes on the project' - #: roles that are allowed to register this action + identifier = "prepare.project.local" + label = "Prepare Project (Local)" + description = "Set basic attributes on the project" icon = statics_icon("ftrack", "action_icons", "PrepareProject.svg") settings_key = "prepare_project" # Key to store info about trigerring create folder structure - item_splitter = {'type': 'label', 'value': '---'} + item_splitter = {"type": "label", "value": "---"} def discover(self, session, entities, event): - ''' Validation ''' + """Show only on project.""" if ( len(entities) != 1 or entities[0].entity_type.lower() != "project" @@ -368,4 +364,4 @@ class PrepareProject(BaseAction): def register(session): '''Register plugin. Called when used as an plugin.''' - PrepareProject(session).register() + PrepareProjectLocal(session).register() From 4d1ad337cc2d324018cb35254047fdcc8a0b42e0 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 13 Apr 2021 14:09:28 +0200 Subject: [PATCH 06/12] created server version of prepare project --- .../action_prepare_project.py | 365 ++++++++++++++++++ 1 file changed, 365 insertions(+) create mode 100644 openpype/modules/ftrack/event_handlers_server/action_prepare_project.py diff --git a/openpype/modules/ftrack/event_handlers_server/action_prepare_project.py b/openpype/modules/ftrack/event_handlers_server/action_prepare_project.py new file mode 100644 index 0000000000..6a1066c39d --- /dev/null +++ b/openpype/modules/ftrack/event_handlers_server/action_prepare_project.py @@ -0,0 +1,365 @@ +import os +import json + +from openpype.api import config, ProjectSettings + +from openpype.modules.ftrack.lib import ServerAction +from openpype.modules.ftrack.lib.avalon_sync import ( + get_pype_attr, + CUST_ATTR_AUTO_SYNC +) + + +class PrepareProjectServer(ServerAction): + """Prepare project attributes in Anatomy.""" + + identifier = "prepare.project.server" + label = "Prepare Project (Server)" + description = "Set basic attributes on the project" + + settings_key = "prepare_project" + + role_list = ["Pypeclub", "Administrator", "Project Manager"] + + # Key to store info about trigerring create folder structure + item_splitter = {"type": "label", "value": "---"} + + def discover(self, session, entities, event): + """Show only on project.""" + if ( + len(entities) != 1 + or entities[0].entity_type.lower() != "project" + ): + return False + + return self.valid_roles(session, entities, event) + + def interface(self, session, entities, event): + if event['data'].get('values', {}): + return + + # Inform user that this may take a while + self.show_message(event, "Preparing data... Please wait", True) + self.log.debug("Preparing data which will be shown") + + self.log.debug("Loading custom attributes") + + project_entity = entities[0] + project_name = project_entity["full_name"] + + try: + project_settings = ProjectSettings(project_name) + except ValueError: + return { + "message": "Project is not synchronized yet", + "success": False + } + + project_anatom_settings = project_settings["project_anatomy"] + root_items = self.prepare_root_items(project_anatom_settings) + + ca_items, multiselect_enumerators = ( + self.prepare_custom_attribute_items(project_anatom_settings) + ) + + self.log.debug("Heavy items are ready. Preparing last items group.") + + title = "Prepare Project" + items = [] + + # Add root items + items.extend(root_items) + + items.append(self.item_splitter) + items.append({ + "type": "label", + "value": "

Set basic Attributes:

" + }) + + items.extend(ca_items) + + # This item will be last (before enumerators) + # - sets value of auto synchronization + auto_sync_name = "avalon_auto_sync" + auto_sync_value = project_entity["custom_attributes"].get( + CUST_ATTR_AUTO_SYNC, False + ) + auto_sync_item = { + "name": auto_sync_name, + "type": "boolean", + "value": auto_sync_value, + "label": "AutoSync to Avalon" + } + # Add autosync attribute + items.append(auto_sync_item) + + # Add enumerator items at the end + for item in multiselect_enumerators: + items.append(item) + + return { + "items": items, + "title": title + } + + def prepare_root_items(self, project_anatom_settings): + self.log.debug("Root items preparation begins.") + + root_items = [] + root_items.append({ + "type": "label", + "value": "

Check your Project root settings

" + }) + root_items.append({ + "type": "label", + "value": ( + "

NOTE: Roots are crutial for path filling" + " (and creating folder structure).

" + ) + }) + root_items.append({ + "type": "label", + "value": ( + "

WARNING: Do not change roots on running project," + " that will cause workflow issues.

" + ) + }) + + empty_text = "Enter root path here..." + + roots_entity = project_anatom_settings["roots"] + for root_name, root_entity in roots_entity.items(): + root_items.append(self.item_splitter) + root_items.append({ + "type": "label", + "value": "Root: \"{}\"".format(root_name) + }) + for platform_name, value_entity in root_entity.items(): + root_items.append({ + "label": platform_name, + "name": "__root__{}__{}".format(root_name, platform_name), + "type": "text", + "value": value_entity.value, + "empty_text": empty_text + }) + + root_items.append({ + "type": "hidden", + "name": "__rootnames__", + "value": json.dumps(list(roots_entity.keys())) + }) + + self.log.debug("Root items preparation ended.") + return root_items + + def _attributes_to_set(self, project_anatom_settings): + attributes_to_set = {} + + attribute_values_by_key = {} + for key, entity in project_anatom_settings["attributes"].items(): + attribute_values_by_key[key] = entity.value + + cust_attrs, hier_cust_attrs = get_pype_attr(self.session, True) + + for attr in hier_cust_attrs: + key = attr["key"] + if key.startswith("avalon_"): + continue + attributes_to_set[key] = { + "label": attr["label"], + "object": attr, + "default": attribute_values_by_key.get(key) + } + + for attr in cust_attrs: + if attr["entity_type"].lower() != "show": + continue + key = attr["key"] + if key.startswith("avalon_"): + continue + attributes_to_set[key] = { + "label": attr["label"], + "object": attr, + "default": attribute_values_by_key.get(key) + } + + # Sort by label + attributes_to_set = dict(sorted( + attributes_to_set.items(), + key=lambda x: x[1]["label"] + )) + return attributes_to_set + + def prepare_custom_attribute_items(self, project_anatom_settings): + items = [] + multiselect_enumerators = [] + attributes_to_set = self._attributes_to_set(project_anatom_settings) + + self.log.debug("Preparing interface for keys: \"{}\"".format( + str([key for key in attributes_to_set]) + )) + + for key, in_data in attributes_to_set.items(): + attr = in_data["object"] + + # initial item definition + item = { + "name": key, + "label": in_data["label"] + } + + # cust attr type - may have different visualization + type_name = attr["type"]["name"].lower() + easy_types = ["text", "boolean", "date", "number"] + + easy_type = False + if type_name in easy_types: + easy_type = True + + elif type_name == "enumerator": + + attr_config = json.loads(attr["config"]) + attr_config_data = json.loads(attr_config["data"]) + + if attr_config["multiSelect"] is True: + multiselect_enumerators.append(self.item_splitter) + multiselect_enumerators.append({ + "type": "label", + "value": in_data["label"] + }) + + default = in_data["default"] + names = [] + for option in sorted( + attr_config_data, key=lambda x: x["menu"] + ): + name = option["value"] + new_name = "__{}__{}".format(key, name) + names.append(new_name) + item = { + "name": new_name, + "type": "boolean", + "label": "- {}".format(option["menu"]) + } + if default: + if isinstance(default, (list, tuple)): + if name in default: + item["value"] = True + else: + if name == default: + item["value"] = True + + multiselect_enumerators.append(item) + + multiselect_enumerators.append({ + "type": "hidden", + "name": "__hidden__{}".format(key), + "value": json.dumps(names) + }) + else: + easy_type = True + item["data"] = attr_config_data + + else: + self.log.warning(( + "Custom attribute \"{}\" has type \"{}\"." + " I don't know how to handle" + ).format(key, type_name)) + items.append({ + "type": "label", + "value": ( + "!!! Can't handle Custom attritubte type \"{}\"" + " (key: \"{}\")" + ).format(type_name, key) + }) + + if easy_type: + item["type"] = type_name + + # default value in interface + default = in_data["default"] + if default is not None: + item["value"] = default + + items.append(item) + + return items, multiselect_enumerators + + def launch(self, session, entities, event): + if not event['data'].get('values', {}): + return + + in_data = event['data']['values'] + + root_values = {} + root_key = "__root__" + for key in tuple(in_data.keys()): + if key.startswith(root_key): + _key = key[len(root_key):] + root_values[_key] = in_data.pop(key) + + root_names = in_data.pop("__rootnames__", None) + root_data = {} + for root_name in json.loads(root_names): + root_data[root_name] = {} + for key, value in tuple(root_values.items()): + prefix = "{}__".format(root_name) + if not key.startswith(prefix): + continue + + _key = key[len(prefix):] + root_data[root_name][_key] = value + + # Find hidden items for multiselect enumerators + keys_to_process = [] + for key in in_data: + if key.startswith("__hidden__"): + keys_to_process.append(key) + + self.log.debug("Preparing data for Multiselect Enumerators") + enumerators = {} + for key in keys_to_process: + new_key = key.replace("__hidden__", "") + enumerator_items = in_data.pop(key) + enumerators[new_key] = json.loads(enumerator_items) + + # find values set for multiselect enumerator + for key, enumerator_items in enumerators.items(): + in_data[key] = [] + + name = "__{}__".format(key) + + for item in enumerator_items: + value = in_data.pop(item) + if value is True: + new_key = item.replace(name, "") + in_data[key].append(new_key) + + self.log.debug("Setting Custom Attribute values") + + project_name = entities[0]["full_name"] + project_settings = ProjectSettings(project_name) + project_anatomy_settings = project_settings["project_anatomy"] + project_anatomy_settings["roots"] = root_data + + custom_attribute_values = {} + attributes_entity = project_anatomy_settings["attributes"] + for key, value in in_data.items(): + if key not in attributes_entity: + custom_attribute_values[key] = value + else: + attributes_entity[key] = value + + project_settings.save() + + entity = entities[0] + for key, value in custom_attribute_values.items(): + entity["custom_attributes"][key] = value + self.log.debug("- Key \"{}\" set to \"{}\"".format(key, value)) + + return True + + +def register(session): + '''Register plugin. Called when used as an plugin.''' + PrepareProjectServer(session).register() From 35d8059a3a4ccfd4749c3bf26e048a8caf1e53cf Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 13 Apr 2021 14:09:41 +0200 Subject: [PATCH 07/12] defined roles in prepare project action --- .../ftrack/event_handlers_user/action_prepare_project.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py b/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py index adc6a97fb8..dc1bb7adce 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py +++ b/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py @@ -21,6 +21,8 @@ class PrepareProjectLocal(BaseAction): description = "Set basic attributes on the project" icon = statics_icon("ftrack", "action_icons", "PrepareProject.svg") + role_list = ["Pypeclub", "Administrator", "Project Manager"] + settings_key = "prepare_project" # Key to store info about trigerring create folder structure From 43187d8b110bd8f872ac987dec24af766bb0d841 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 13 Apr 2021 14:19:40 +0200 Subject: [PATCH 08/12] removed unused imports --- .../ftrack/event_handlers_server/action_prepare_project.py | 2 +- .../ftrack/event_handlers_user/action_prepare_project.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/modules/ftrack/event_handlers_server/action_prepare_project.py b/openpype/modules/ftrack/event_handlers_server/action_prepare_project.py index 6a1066c39d..e274ce8eb3 100644 --- a/openpype/modules/ftrack/event_handlers_server/action_prepare_project.py +++ b/openpype/modules/ftrack/event_handlers_server/action_prepare_project.py @@ -1,7 +1,7 @@ import os import json -from openpype.api import config, ProjectSettings +from openpype.api import ProjectSettings from openpype.modules.ftrack.lib import ServerAction from openpype.modules.ftrack.lib.avalon_sync import ( diff --git a/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py b/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py index dc1bb7adce..a885f8571c 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py +++ b/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py @@ -1,7 +1,7 @@ import os import json -from openpype.api import config, ProjectSettings +from openpype.api import ProjectSettings from openpype.modules.ftrack.lib import ( BaseAction, From 0fe1bc64f2b55b28b955c36a9cbf4d746bd74e10 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 13 Apr 2021 14:23:53 +0200 Subject: [PATCH 09/12] added PrepareProject to OpenPype Admin group --- .../ftrack/event_handlers_server/action_prepare_project.py | 3 ++- .../ftrack/event_handlers_user/action_prepare_project.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/openpype/modules/ftrack/event_handlers_server/action_prepare_project.py b/openpype/modules/ftrack/event_handlers_server/action_prepare_project.py index e274ce8eb3..decb6c6a75 100644 --- a/openpype/modules/ftrack/event_handlers_server/action_prepare_project.py +++ b/openpype/modules/ftrack/event_handlers_server/action_prepare_project.py @@ -14,7 +14,8 @@ class PrepareProjectServer(ServerAction): """Prepare project attributes in Anatomy.""" identifier = "prepare.project.server" - label = "Prepare Project (Server)" + label = "OpenPype Admin" + variant = "- Prepare Project (Server)" description = "Set basic attributes on the project" settings_key = "prepare_project" diff --git a/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py b/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py index a885f8571c..c2f0533c33 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py +++ b/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py @@ -17,7 +17,8 @@ class PrepareProjectLocal(BaseAction): """Prepare project attributes in Anatomy.""" identifier = "prepare.project.local" - label = "Prepare Project (Local)" + label = "OpenPype Admin" + variant = "- Prepare Project (Local)" description = "Set basic attributes on the project" icon = statics_icon("ftrack", "action_icons", "PrepareProject.svg") From 03b2337bf442d686927ce7d4748f76ccdcf7ce29 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 13 Apr 2021 14:24:27 +0200 Subject: [PATCH 10/12] added prepare project settings to server settings --- .../defaults/project_settings/ftrack.json | 8 ++++++++ .../schema_project_ftrack.json | 19 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/openpype/settings/defaults/project_settings/ftrack.json b/openpype/settings/defaults/project_settings/ftrack.json index 03ac8f309f..04f2842b93 100644 --- a/openpype/settings/defaults/project_settings/ftrack.json +++ b/openpype/settings/defaults/project_settings/ftrack.json @@ -7,6 +7,14 @@ "not ready" ] }, + "prepare_project": { + "enabled": true, + "role_list": [ + "Pypeclub", + "Administrator", + "Project manager" + ] + }, "sync_hier_entity_attributes": { "enabled": true, "interest_entity_types": [ diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_ftrack.json b/openpype/settings/entities/schemas/projects_schema/schema_project_ftrack.json index eefc0e12b7..a801175031 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_ftrack.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_ftrack.json @@ -36,6 +36,25 @@ } ] }, + { + "type": "dict", + "key": "prepare_project", + "label": "Prepare Project", + "checkbox_key": "enabled", + "children": [ + { + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "list", + "key": "role_list", + "label": "Roles", + "object_type": "text" + } + ] + }, { "type": "dict", "key": "sync_hier_entity_attributes", From 684dcb918d406404211562e2e1823eafd10f0a5e Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 13 Apr 2021 14:35:14 +0200 Subject: [PATCH 11/12] local version is not under OpenPype Admin group --- .../ftrack/event_handlers_user/action_prepare_project.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py b/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py index c2f0533c33..e6a161d95f 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py +++ b/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py @@ -17,8 +17,7 @@ class PrepareProjectLocal(BaseAction): """Prepare project attributes in Anatomy.""" identifier = "prepare.project.local" - label = "OpenPype Admin" - variant = "- Prepare Project (Local)" + label = "Prepare Project" description = "Set basic attributes on the project" icon = statics_icon("ftrack", "action_icons", "PrepareProject.svg") From d49a93a58a78a22dc9b85336836be9c2846d4d28 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 13 Apr 2021 14:38:19 +0200 Subject: [PATCH 12/12] removed unused import --- .../ftrack/event_handlers_server/action_prepare_project.py | 1 - .../modules/ftrack/event_handlers_user/action_prepare_project.py | 1 - 2 files changed, 2 deletions(-) diff --git a/openpype/modules/ftrack/event_handlers_server/action_prepare_project.py b/openpype/modules/ftrack/event_handlers_server/action_prepare_project.py index decb6c6a75..8248bf532e 100644 --- a/openpype/modules/ftrack/event_handlers_server/action_prepare_project.py +++ b/openpype/modules/ftrack/event_handlers_server/action_prepare_project.py @@ -1,4 +1,3 @@ -import os import json from openpype.api import ProjectSettings diff --git a/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py b/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py index e6a161d95f..bd25f995fe 100644 --- a/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py +++ b/openpype/modules/ftrack/event_handlers_user/action_prepare_project.py @@ -1,4 +1,3 @@ -import os import json from openpype.api import ProjectSettings