mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
use folder naming
This commit is contained in:
parent
262cbda493
commit
c3296b1322
11 changed files with 110 additions and 106 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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"])
|
||||
):
|
||||
|
|
|
|||
|
|
@ -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
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
"<AYON_PROJECT_ROOT_NAS>/project/asset/task/animation_v001.ma"
|
||||
"<AYON_PROJECT_ROOT_NAS>/project/folder/task/animation_v001.ma"
|
||||
|
||||
Args:
|
||||
filepath (str): Full file path where root should be replaced.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue