mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-25 05:14:40 +01:00
Merge pull request #2462 from pypeclub/feature/extra_work_folders
General: Workdir extra folders
This commit is contained in:
commit
62bd44ca95
7 changed files with 145 additions and 60 deletions
33
openpype/hooks/pre_create_extra_workdir_folders.py
Normal file
33
openpype/hooks/pre_create_extra_workdir_folders.py
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
import os
|
||||
from openpype.lib import (
|
||||
PreLaunchHook,
|
||||
create_workdir_extra_folders
|
||||
)
|
||||
|
||||
|
||||
class AddLastWorkfileToLaunchArgs(PreLaunchHook):
|
||||
"""Add last workfile path to launch arguments.
|
||||
|
||||
This is not possible to do for all applications the same way.
|
||||
"""
|
||||
|
||||
# Execute after workfile template copy
|
||||
order = 15
|
||||
|
||||
def execute(self):
|
||||
if not self.application.is_host:
|
||||
return
|
||||
|
||||
env = self.data.get("env") or {}
|
||||
workdir = env.get("AVALON_WORKDIR")
|
||||
if not workdir or not os.path.exists(workdir):
|
||||
return
|
||||
|
||||
host_name = self.application.host_name
|
||||
task_type = self.data["task_type"]
|
||||
task_name = self.data["task_name"]
|
||||
project_name = self.data["project_name"]
|
||||
|
||||
create_workdir_extra_folders(
|
||||
workdir, host_name, task_type, task_name, project_name,
|
||||
)
|
||||
|
|
@ -148,7 +148,8 @@ from .path_tools import (
|
|||
get_version_from_path,
|
||||
get_last_version_from_path,
|
||||
create_project_folders,
|
||||
get_project_basic_paths
|
||||
create_workdir_extra_folders,
|
||||
get_project_basic_paths,
|
||||
)
|
||||
|
||||
from .editorial import (
|
||||
|
|
@ -290,6 +291,7 @@ __all__ = [
|
|||
"frames_to_timecode",
|
||||
"make_sequence_collection",
|
||||
"create_project_folders",
|
||||
"create_workdir_extra_folders",
|
||||
"get_project_basic_paths",
|
||||
|
||||
"get_openpype_version",
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
import json
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import abc
|
||||
import json
|
||||
import logging
|
||||
import six
|
||||
|
||||
from openpype.settings import get_project_settings
|
||||
from openpype.settings.lib import get_site_local_overrides
|
||||
|
||||
from .anatomy import Anatomy
|
||||
from openpype.settings import get_project_settings
|
||||
from .profiles_filtering import filter_profiles
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
|
@ -200,6 +202,58 @@ def get_project_basic_paths(project_name):
|
|||
return _list_path_items(folder_structure)
|
||||
|
||||
|
||||
def create_workdir_extra_folders(
|
||||
workdir, host_name, task_type, task_name, project_name,
|
||||
project_settings=None
|
||||
):
|
||||
"""Create extra folders in work directory based on context.
|
||||
|
||||
Args:
|
||||
workdir (str): Path to workdir where workfiles is stored.
|
||||
host_name (str): Name of host implementation.
|
||||
task_type (str): Type of task for which extra folders should be
|
||||
created.
|
||||
task_name (str): Name of task for which extra folders should be
|
||||
created.
|
||||
project_name (str): Name of project on which task is.
|
||||
project_settings (dict): Prepared project settings. Are loaded if not
|
||||
passed.
|
||||
"""
|
||||
# Load project settings if not set
|
||||
if not project_settings:
|
||||
project_settings = get_project_settings(project_name)
|
||||
|
||||
# Load extra folders profiles
|
||||
extra_folders_profiles = (
|
||||
project_settings["global"]["tools"]["Workfiles"]["extra_folders"]
|
||||
)
|
||||
# Skip if are empty
|
||||
if not extra_folders_profiles:
|
||||
return
|
||||
|
||||
# Prepare profiles filters
|
||||
filter_data = {
|
||||
"task_types": task_type,
|
||||
"task_names": task_name,
|
||||
"hosts": host_name
|
||||
}
|
||||
profile = filter_profiles(extra_folders_profiles, filter_data)
|
||||
if profile is None:
|
||||
return
|
||||
|
||||
for subfolder in profile["folders"]:
|
||||
# Make sure backslashes are converted to forwards slashes
|
||||
# and does not start with slash
|
||||
subfolder = subfolder.replace("\\", "/").lstrip("/")
|
||||
# Skip empty strings
|
||||
if not subfolder:
|
||||
continue
|
||||
|
||||
fullpath = os.path.join(workdir, subfolder)
|
||||
if not os.path.exists(fullpath):
|
||||
os.makedirs(fullpath)
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class HostDirmap:
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -111,13 +111,6 @@ class CreateFolders(BaseAction):
|
|||
publish_template = publish_template[key]
|
||||
publish_has_apps = "{app" in publish_template
|
||||
|
||||
tools_settings = project_settings["global"]["tools"]
|
||||
app_presets = tools_settings["Workfiles"]["sw_folders"]
|
||||
app_manager_apps = None
|
||||
if app_presets and (work_has_apps or publish_has_apps):
|
||||
app_manager_apps = ApplicationManager().applications
|
||||
|
||||
cached_apps = {}
|
||||
collected_paths = []
|
||||
for entity in all_entities:
|
||||
if entity.entity_type.lower() == "project":
|
||||
|
|
@ -143,26 +136,10 @@ class CreateFolders(BaseAction):
|
|||
if child["object_type"]["name"].lower() != "task":
|
||||
continue
|
||||
tasks_created = True
|
||||
task_type_name = child["type"]["name"].lower()
|
||||
task_data = ent_data.copy()
|
||||
task_data["task"] = child["name"]
|
||||
|
||||
apps = []
|
||||
if app_manager_apps:
|
||||
possible_apps = app_presets.get(task_type_name) or []
|
||||
for app_name in possible_apps:
|
||||
|
||||
if app_name in cached_apps:
|
||||
apps.append(cached_apps[app_name])
|
||||
continue
|
||||
|
||||
app_def = app_manager_apps.get(app_name)
|
||||
if app_def and app_def.is_host:
|
||||
app_dir = app_def.host_name
|
||||
else:
|
||||
app_dir = app_name
|
||||
cached_apps[app_name] = app_dir
|
||||
apps.append(app_dir)
|
||||
|
||||
# Template wok
|
||||
if work_has_apps:
|
||||
|
|
|
|||
|
|
@ -291,21 +291,7 @@
|
|||
"enabled": false
|
||||
}
|
||||
],
|
||||
"sw_folders": {
|
||||
"compositing": [
|
||||
"nuke",
|
||||
"ae"
|
||||
],
|
||||
"modeling": [
|
||||
"maya",
|
||||
"blender",
|
||||
"zbrush"
|
||||
],
|
||||
"lookdev": [
|
||||
"substance",
|
||||
"textures"
|
||||
]
|
||||
}
|
||||
"extra_folders": []
|
||||
},
|
||||
"loader": {
|
||||
"family_filter_profiles": [
|
||||
|
|
|
|||
|
|
@ -195,14 +195,48 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"type": "dict-modifiable",
|
||||
"type": "list",
|
||||
"key": "extra_folders",
|
||||
"label": "Extra work folders",
|
||||
"collapsible": true,
|
||||
"key": "sw_folders",
|
||||
"label": "Extra task folders",
|
||||
"use_label_wrap": true,
|
||||
"is_group": true,
|
||||
"object_type": {
|
||||
"type": "list",
|
||||
"object_type": "text"
|
||||
"type": "dict",
|
||||
"children": [
|
||||
{
|
||||
"type": "hosts-enum",
|
||||
"key": "hosts",
|
||||
"label": "Hosts",
|
||||
"multiselection": true
|
||||
},
|
||||
{
|
||||
"type": "task-types-enum",
|
||||
"key": "task_types",
|
||||
"label": "Task types"
|
||||
},
|
||||
{
|
||||
"label": "Task names",
|
||||
"key": "task_names",
|
||||
"type": "list",
|
||||
"object_type": "text"
|
||||
},
|
||||
{
|
||||
"type": "splitter"
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"label": "Folders will be created in directory next to workfile. Items may contain nested directories (e.g. <b>resources/images</b>)."
|
||||
},
|
||||
{
|
||||
"key": "folders",
|
||||
"label": "Folders",
|
||||
"type": "list",
|
||||
"highlight_content": true,
|
||||
"collapsible": false,
|
||||
"object_type": "text"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ from avalon import io, api, pipeline
|
|||
|
||||
from openpype import style
|
||||
from openpype.tools.utils.lib import (
|
||||
schedule,
|
||||
qt_app_context
|
||||
)
|
||||
from openpype.tools.utils import PlaceholderLineEdit
|
||||
|
|
@ -25,7 +24,8 @@ from openpype.lib import (
|
|||
get_workfile_doc,
|
||||
create_workfile_doc,
|
||||
save_workfile_data_to_doc,
|
||||
get_workfile_template_key
|
||||
get_workfile_template_key,
|
||||
create_workdir_extra_folders
|
||||
)
|
||||
|
||||
from .model import FilesModel
|
||||
|
|
@ -672,7 +672,13 @@ class FilesWidget(QtWidgets.QWidget):
|
|||
self.set_asset_task(
|
||||
self._asset_id, self._task_name, self._task_type
|
||||
)
|
||||
|
||||
create_workdir_extra_folders(
|
||||
self.root,
|
||||
api.Session["AVALON_APP"],
|
||||
self._task_type,
|
||||
self._task_name,
|
||||
api.Session["AVALON_PROJECT"]
|
||||
)
|
||||
pipeline.emit("after.workfile.save", [file_path])
|
||||
|
||||
self.workfile_created.emit(file_path)
|
||||
|
|
@ -729,7 +735,7 @@ class FilesWidget(QtWidgets.QWidget):
|
|||
self.files_model.refresh()
|
||||
|
||||
if self.auto_select_latest_modified:
|
||||
schedule(self._select_last_modified_file, 100)
|
||||
self._select_last_modified_file()
|
||||
|
||||
def on_context_menu(self, point):
|
||||
index = self.files_view.indexAt(point)
|
||||
|
|
@ -934,8 +940,8 @@ class Window(QtWidgets.QMainWindow):
|
|||
|
||||
# Connect signals
|
||||
set_context_timer.timeout.connect(self._on_context_set_timeout)
|
||||
assets_widget.selection_changed.connect(self.on_asset_changed)
|
||||
tasks_widget.task_changed.connect(self.on_task_changed)
|
||||
assets_widget.selection_changed.connect(self._on_asset_changed)
|
||||
tasks_widget.task_changed.connect(self._on_task_changed)
|
||||
files_widget.file_selected.connect(self.on_file_select)
|
||||
files_widget.workfile_created.connect(self.on_workfile_create)
|
||||
files_widget.file_opened.connect(self._on_file_opened)
|
||||
|
|
@ -980,13 +986,6 @@ class Window(QtWidgets.QMainWindow):
|
|||
def set_save_enabled(self, enabled):
|
||||
self.files_widget.btn_save.setEnabled(enabled)
|
||||
|
||||
def on_task_changed(self):
|
||||
# Since we query the disk give it slightly more delay
|
||||
schedule(self._on_task_changed, 100, channel="mongo")
|
||||
|
||||
def on_asset_changed(self):
|
||||
schedule(self._on_asset_changed, 50, channel="mongo")
|
||||
|
||||
def on_file_select(self, filepath):
|
||||
asset_id = self.assets_widget.get_selected_asset_id()
|
||||
task_name = self.tasks_widget.get_selected_task_name()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue