From c3296b13228637d7db236c95e00b7b909b9dfd32 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 4 Mar 2024 17:48:24 +0100 Subject: [PATCH] use folder naming --- client/ayon_core/cli_commands.py | 4 +- client/ayon_core/host/host.py | 6 +- .../perjob/m50__openpype_publish_render.py | 6 +- .../plugins/publish/start_timer.py | 6 +- .../modules/timers_manager/rest_api.py | 12 +-- .../modules/timers_manager/timers_manager.py | 98 ++++++++++--------- client/ayon_core/pipeline/anatomy.py | 4 +- client/ayon_core/pipeline/create/context.py | 10 +- client/ayon_core/tools/adobe_webserver/app.py | 20 ++-- .../ayon_core/tools/context_dialog/window.py | 42 ++++---- .../tools/launcher/models/actions.py | 8 +- 11 files changed, 110 insertions(+), 106 deletions(-) diff --git a/client/ayon_core/cli_commands.py b/client/ayon_core/cli_commands.py index a24710aef2..156196c401 100644 --- a/client/ayon_core/cli_commands.py +++ b/client/ayon_core/cli_commands.py @@ -181,7 +181,7 @@ class Commands: json.dump(env, file_stream, indent=4) @staticmethod - def contextselection(output_path, project_name, asset_name, strict): + def contextselection(output_path, project_name, folder_path, strict): from ayon_core.tools.context_dialog import main - main(output_path, project_name, asset_name, strict) + main(output_path, project_name, folder_path, strict) diff --git a/client/ayon_core/host/host.py b/client/ayon_core/host/host.py index d9739603d7..b815dadfe1 100644 --- a/client/ayon_core/host/host.py +++ b/client/ayon_core/host/host.py @@ -161,13 +161,13 @@ class HostBase(object): # Use current context to fill the context title current_context = self.get_current_context() project_name = current_context["project_name"] - asset_name = current_context["folder_path"] + folder_path = current_context["folder_path"] task_name = current_context["task_name"] items = [] if project_name: items.append(project_name) - if asset_name: - items.append(asset_name.lstrip("/")) + if folder_path: + items.append(folder_path.lstrip("/")) if task_name: items.append(task_name) if items: diff --git a/client/ayon_core/modules/royalrender/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py b/client/ayon_core/modules/royalrender/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py index 778052778f..8405f69b3e 100644 --- a/client/ayon_core/modules/royalrender/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py +++ b/client/ayon_core/modules/royalrender/rr_root/plugins/control_job/perjob/m50__openpype_publish_render.py @@ -109,7 +109,7 @@ class OpenPypeContextSelector: if not self.context or \ not self.context.get("project") or \ - not self.context.get("asset") or \ + not self.context.get("folder") or \ not self.context.get("task"): self._show_rr_warning("Context selection failed.") return False @@ -137,7 +137,7 @@ class OpenPypeContextSelector: def run_publish(self): """Run publish process.""" env = {"AYON_PROJECT_NAME": str(self.context.get("project")), - "AYON_FOLDER_PATH": str(self.context.get("asset")), + "AYON_FOLDER_PATH": str(self.context.get("folder")), "AYON_TASK_NAME": str(self.context.get("task")), # "AYON_APP_NAME": str(self.context.get("app_name")) } @@ -184,7 +184,7 @@ selector = OpenPypeContextSelector() # try to set context from environment for key, env_keys in ( ("project", ["AYON_PROJECT_NAME", "AVALON_PROJECT"]), - ("asset", ["AYON_FOLDER_PATH", "AVALON_ASSET"]), + ("folder", ["AYON_FOLDER_PATH", "AVALON_ASSET"]), ("task", ["AYON_TASK_NAME", "AVALON_TASK"]), # ("app_name", ["AYON_APP_NAME", "AVALON_APP_NAME"]) ): diff --git a/client/ayon_core/modules/timers_manager/plugins/publish/start_timer.py b/client/ayon_core/modules/timers_manager/plugins/publish/start_timer.py index 182efbc4ae..620cdb6e65 100644 --- a/client/ayon_core/modules/timers_manager/plugins/publish/start_timer.py +++ b/client/ayon_core/modules/timers_manager/plugins/publish/start_timer.py @@ -24,14 +24,14 @@ class StartTimer(pyblish.api.ContextPlugin): return project_name = context.data["projectName"] - asset_name = context.data.get("folderPath") + folder_path = context.data.get("folderPath") task_name = context.data.get("task") - if not project_name or not asset_name or not task_name: + if not project_name or not folder_path or not task_name: self.log.info(( "Current context does not contain all" " required information to start a timer." )) return timers_manager.start_timer_with_webserver( - project_name, asset_name, task_name, self.log + project_name, folder_path, task_name, self.log ) diff --git a/client/ayon_core/modules/timers_manager/rest_api.py b/client/ayon_core/modules/timers_manager/rest_api.py index c890d587de..88a6539510 100644 --- a/client/ayon_core/modules/timers_manager/rest_api.py +++ b/client/ayon_core/modules/timers_manager/rest_api.py @@ -45,7 +45,7 @@ class TimersManagerModuleRestApi: data = await request.json() try: project_name = data["project_name"] - asset_name = data["folder_path"] + folder_path = data["folder_path"] task_name = data["task_name"] except KeyError: msg = ( @@ -57,7 +57,7 @@ class TimersManagerModuleRestApi: self.module.stop_timers() try: - self.module.start_timer(project_name, asset_name, task_name) + self.module.start_timer(project_name, folder_path, task_name) except Exception as exc: return Response(status=404, message=str(exc)) @@ -70,9 +70,9 @@ class TimersManagerModuleRestApi: async def get_task_time(self, request): data = await request.json() try: - project_name = data['project_name'] - asset_name = data['folder_path'] - task_name = data['task_name'] + project_name = data["project_name"] + folder_path = data["folder_path"] + task_name = data["task_name"] except KeyError: message = ( "Payload must contain fields 'project_name, 'folder_path'," @@ -81,5 +81,5 @@ class TimersManagerModuleRestApi: self.log.warning(message) return Response(text=message, status=404) - time = self.module.get_task_time(project_name, asset_name, task_name) + time = self.module.get_task_time(project_name, folder_path, task_name) return Response(text=json.dumps(time)) diff --git a/client/ayon_core/modules/timers_manager/timers_manager.py b/client/ayon_core/modules/timers_manager/timers_manager.py index e04200525a..4212ff6b25 100644 --- a/client/ayon_core/modules/timers_manager/timers_manager.py +++ b/client/ayon_core/modules/timers_manager/timers_manager.py @@ -1,8 +1,8 @@ import os import platform +import ayon_api -from ayon_core.client import get_asset_by_name from ayon_core.addon import ( AYONAddon, ITrayService, @@ -24,14 +24,18 @@ class ExampleTimersManagerConnector: Required methods are 'stop_timer' and 'start_timer'. - # TODO pass asset document instead of `hierarchy` Example of `data` that are passed during changing timer: ``` data = { "project_name": project_name, + "folder_id": folder_id, + "folder_path": folder_entity["path"], "task_name": task_name, "task_type": task_type, - "hierarchy": hierarchy + # Deprecated + "asset_id": folder_id, + "asset_name": folder_entity["name"], + "hierarchy": hierarchy_items, } ``` """ @@ -176,16 +180,14 @@ class TimersManager( """Convert string path to a timer data. It is expected that first item is project name, last item is task name - and parent asset name is before task name. + and folder path in the middle. """ path_items = task_path.split("/") - if len(path_items) < 3: - raise InvalidContextError("Invalid path \"{}\"".format(task_path)) task_name = path_items.pop(-1) - asset_name = path_items.pop(-1) project_name = path_items.pop(0) + folder_path = "/" + "/".join(path_items) return self.get_timer_data_for_context( - project_name, asset_name, task_name, self.log + project_name, folder_path, task_name, self.log ) def get_launch_hook_paths(self): @@ -204,40 +206,38 @@ class TimersManager( @staticmethod def get_timer_data_for_context( - project_name, asset_name, task_name, logger=None + project_name, folder_path, task_name, logger=None ): - """Prepare data for timer related callbacks. - - TODO: - - return predefined object that has access to asset document etc. - """ - if not project_name or not asset_name or not task_name: + """Prepare data for timer related callbacks.""" + if not project_name or not folder_path or not task_name: raise InvalidContextError(( "Missing context information got" - " Project: \"{}\" Asset: \"{}\" Task: \"{}\"" - ).format(str(project_name), str(asset_name), str(task_name))) + " Project: \"{}\" Folder: \"{}\" Task: \"{}\"" + ).format(str(project_name), str(folder_path), str(task_name))) - asset_doc = get_asset_by_name( + folder_entity = ayon_api.get_folder_by_path( project_name, - asset_name, - fields=["_id", "name", "data.tasks", "data.parents"] + folder_path, + fields={"id", "name", "path"} ) - if not asset_doc: + if not folder_entity: raise InvalidContextError(( - "Asset \"{}\" not found in project \"{}\"" - ).format(asset_name, project_name)) + "Folder \"{}\" not found in project \"{}\"" + ).format(folder_path, project_name)) - asset_data = asset_doc.get("data") or {} - asset_tasks = asset_data.get("tasks") or {} - if task_name not in asset_tasks: + folder_id = folder_entity["id"] + task_entity = ayon_api.get_task_by_name( + project_name, folder_id, task_name + ) + if not task_entity: raise InvalidContextError(( - "Task \"{}\" not found on asset \"{}\" in project \"{}\"" - ).format(task_name, asset_name, project_name)) + "Task \"{}\" not found on folder \"{}\" in project \"{}\"" + ).format(task_name, folder_path, project_name)) task_type = "" try: - task_type = asset_tasks[task_name]["type"] + task_type = task_entity["taskType"] except KeyError: msg = "Couldn't find task_type for {}".format(task_name) if logger is not None: @@ -245,32 +245,34 @@ class TimersManager( else: print(msg) - hierarchy_items = asset_data.get("parents") or [] - hierarchy_items.append(asset_name) + hierarchy_items = folder_entity["path"].split("/") + hierarchy_items.pop(0) return { "project_name": project_name, - "asset_id": str(asset_doc["_id"]), - "asset_name": asset_name, + "folder_id": folder_id, + "folder_path": folder_entity["path"], "task_name": task_name, "task_type": task_type, - "hierarchy": hierarchy_items + "asset_id": folder_id, + "asset_name": folder_entity["name"], + "hierarchy": hierarchy_items, } - def start_timer(self, project_name, asset_name, task_name): + def start_timer(self, project_name, folder_path, task_name): """Start timer for passed context. Args: - project_name (str): Project name - asset_name (str): Asset name - task_name (str): Task name + project_name (str): Project name. + folder_path (str): Folder path. + task_name (str): Task name. """ data = self.get_timer_data_for_context( - project_name, asset_name, task_name, self.log + project_name, folder_path, task_name, self.log ) self.timer_started(None, data) - def get_task_time(self, project_name, asset_name, task_name): + def get_task_time(self, project_name, folder_path, task_name): """Get total time for passed context. TODO: @@ -281,7 +283,7 @@ class TimersManager( if hasattr(connector, "get_task_time"): module = self._modules_by_id[module_id] times[module.name] = connector.get_task_time( - project_name, asset_name, task_name + project_name, folder_path, task_name ) return times @@ -394,7 +396,7 @@ class TimersManager( @staticmethod def start_timer_with_webserver( - project_name, asset_name, task_name, logger=None + project_name, folder_path, task_name, logger=None ): """Prepared method for calling change timers on REST api. @@ -403,7 +405,7 @@ class TimersManager( Args: project_name (str): Project name. - asset_name (str): Asset name. + folder_path (str): Folder path. task_name (str): Task name. logger (logging.Logger): Logger object. Using 'print' if not passed. @@ -430,7 +432,7 @@ class TimersManager( return data = { "project_name": project_name, - "folder_path": asset_name, + "folder_path": folder_path, "task_name": task_name } @@ -472,13 +474,13 @@ class TimersManager( def _on_host_task_change(self, event): project_name = event["project_name"] - asset_name = event["folder_path"] + folder_path = event["folder_path"] task_name = event["task_name"] self.log.debug(( "Sending message that timer should change to" - " Project: {} Asset: {} Task: {}" - ).format(project_name, asset_name, task_name)) + " Project: {} Folder: {} Task: {}" + ).format(project_name, folder_path, task_name)) self.start_timer_with_webserver( - project_name, asset_name, task_name, self.log + project_name, folder_path, task_name, self.log ) diff --git a/client/ayon_core/pipeline/anatomy.py b/client/ayon_core/pipeline/anatomy.py index 6ba5175a2a..d6e09bad39 100644 --- a/client/ayon_core/pipeline/anatomy.py +++ b/client/ayon_core/pipeline/anatomy.py @@ -280,13 +280,13 @@ class BaseAnatomy(object): ``` ## Entered filepath - "P:/projects/project/asset/task/animation_v001.ma" + "P:/projects/project/folder/task/animation_v001.ma" ## Entered template "<{}>" ## Output - "/project/asset/task/animation_v001.ma" + "/project/folder/task/animation_v001.ma" Args: filepath (str): Full file path where root should be replaced. diff --git a/client/ayon_core/pipeline/create/context.py b/client/ayon_core/pipeline/create/context.py index 46c4d2d1b4..4fdba96bb6 100644 --- a/client/ayon_core/pipeline/create/context.py +++ b/client/ayon_core/pipeline/create/context.py @@ -1603,12 +1603,12 @@ class CreateContext: bool: Context changed. """ - project_name, asset_name, task_name, workfile_path = ( + project_name, folder_path, task_name, workfile_path = ( self._get_current_host_context() ) return ( self._current_project_name != project_name - or self._current_folder_path != asset_name + or self._current_folder_path != folder_path or self._current_task_name != task_name or self._current_workfile_path != workfile_path ) @@ -1679,18 +1679,18 @@ class CreateContext: self.refresh_thumbnails() def _get_current_host_context(self): - project_name = asset_name = task_name = workfile_path = None + project_name = folder_path = task_name = workfile_path = None if hasattr(self.host, "get_current_context"): host_context = self.host.get_current_context() if host_context: project_name = host_context.get("project_name") - asset_name = host_context.get("folder_path") + folder_path = host_context.get("folder_path") task_name = host_context.get("task_name") if isinstance(self.host, IWorkfileHost): workfile_path = self.host.get_current_workfile() - return project_name, asset_name, task_name, workfile_path + return project_name, folder_path, task_name, workfile_path def reset_current_context(self): """Refresh current context. diff --git a/client/ayon_core/tools/adobe_webserver/app.py b/client/ayon_core/tools/adobe_webserver/app.py index b10509f484..7d97d7d66d 100644 --- a/client/ayon_core/tools/adobe_webserver/app.py +++ b/client/ayon_core/tools/adobe_webserver/app.py @@ -81,15 +81,19 @@ class WebServerTool: await client.connect() context = get_global_context() - project = context["project_name"] - asset = context["folder_path"] - task = context["task_name"] - log.info("Sending context change to {}-{}-{}".format(project, - asset, - task)) + project_name = context["project_name"] + folder_path = context["folder_path"] + task_name = context["task_name"] + log.info("Sending context change to {}{}/{}".format( + project_name, folder_path, task_name + )) - await client.call('{}.set_context'.format(host), - project=project, asset=asset, task=task) + await client.call( + '{}.set_context'.format(host), + project=project_name, + folder=folder_path, + task=task_name + ) await client.close() def port_occupied(self, host_name, port): diff --git a/client/ayon_core/tools/context_dialog/window.py b/client/ayon_core/tools/context_dialog/window.py index e2c9f71aaa..b145e77515 100644 --- a/client/ayon_core/tools/context_dialog/window.py +++ b/client/ayon_core/tools/context_dialog/window.py @@ -277,8 +277,8 @@ class ContextDialogController: def is_initial_context_valid(self): return self._initial_folder_found and self._initial_project_found - def set_initial_context(self, project_name=None, asset_name=None): - result = self._prepare_initial_context(project_name, asset_name) + def set_initial_context(self, project_name=None, folder_path=None): + result = self._prepare_initial_context(project_name, folder_path) self._initial_project_name = project_name self._initial_folder_id = result["folder_id"] @@ -352,7 +352,7 @@ class ContextDialogController: with open(self._output_path, "w") as stream: json.dump(self.get_selected_context(), stream, indent=4) - def _prepare_initial_context(self, project_name, asset_name): + def _prepare_initial_context(self, project_name, folder_path): project_found = True output = { "project_found": project_found, @@ -362,26 +362,26 @@ class ContextDialogController: "tasks_found": True, } if project_name is None: - asset_name = None + folder_path = None else: project = ayon_api.get_project(project_name) project_found = project is not None output["project_found"] = project_found - if not project_found or not asset_name: + if not project_found or not folder_path: return output - output["folder_label"] = asset_name + output["folder_label"] = folder_path folder_id = None folder_found = False # First try to find by path - folder = ayon_api.get_folder_by_path(project_name, asset_name) + folder = ayon_api.get_folder_by_path(project_name, folder_path) # Try to find by name if folder was not found by path - # - prevent to query by name if 'asset_name' contains '/' - if not folder and "/" not in asset_name: + # - prevent to query by name if 'folder_path' contains '/' + if not folder and "/" not in folder_path: folder = next( ayon_api.get_folders( - project_name, folder_names=[asset_name], fields=["id"]), + project_name, folder_names=[folder_path], fields=["id"]), None ) @@ -496,10 +496,10 @@ class ContextDialog(QtWidgets.QDialog): Context has 3 parts: - Project - - Asset + - Folder - Task - It is possible to predefine project and asset. In that case their widgets + It is possible to predefine project and folder. In that case their widgets will have passed preselected values and will be disabled. """ def __init__(self, controller=None, parent=None): @@ -521,7 +521,7 @@ class ContextDialog(QtWidgets.QDialog): # UI initialization main_splitter = QtWidgets.QSplitter(self) - # Left side widget contains project combobox and asset widget + # Left side widget contains project combobox and folders widget left_side_widget = QtWidgets.QWidget(main_splitter) project_combobox = ProjectsCombobox( @@ -531,7 +531,7 @@ class ContextDialog(QtWidgets.QDialog): ) project_combobox.set_select_item_visible(True) - # Assets widget + # Folders widget folders_widget = FoldersWidget( controller, parent=left_side_widget, @@ -661,11 +661,7 @@ class ContextDialog(QtWidgets.QDialog): self._controller.set_strict(enabled) def refresh(self): - """Refresh all widget one by one. - - When asset refresh is triggered we have to wait when is done so - this method continues with `_on_asset_widget_refresh_finished`. - """ + """Refresh all widget one by one.""" self._controller.reset() @@ -673,10 +669,10 @@ class ContextDialog(QtWidgets.QDialog): """Result of dialog.""" return self._controller.get_selected_context() - def set_context(self, project_name=None, asset_name=None): + def set_context(self, project_name=None, folder_path=None): """Set context which will be used and locked in dialog.""" - self._controller.set_initial_context(project_name, asset_name) + self._controller.set_initial_context(project_name, folder_path) def _on_projects_refresh(self): initial_context = self._controller.get_initial_context() @@ -784,14 +780,14 @@ class ContextDialog(QtWidgets.QDialog): def main( path_to_store, project_name=None, - asset_name=None, + folder_path=None, strict=True ): # Run Qt application app = get_ayon_qt_app() controller = ContextDialogController() controller.set_strict(strict) - controller.set_initial_context(project_name, asset_name) + controller.set_initial_context(project_name, folder_path) controller.set_output_json_path(path_to_store) window = ContextDialog(controller=controller) window.show() diff --git a/client/ayon_core/tools/launcher/models/actions.py b/client/ayon_core/tools/launcher/models/actions.py index 6b9a33e57a..50c3e85b0a 100644 --- a/client/ayon_core/tools/launcher/models/actions.py +++ b/client/ayon_core/tools/launcher/models/actions.py @@ -309,9 +309,11 @@ class ActionsModel: task_name = None task_type = None if task_id is not None: - task = self._controller.get_task_entity(project_name, task_id) - task_name = task["name"] - task_type = task["taskType"] + task_entity = self._controller.get_task_entity( + project_name, task_id + ) + task_name = task_entity["name"] + task_type = task_entity["taskType"] output = should_start_last_workfile( project_name,