Merge pull request #2462 from pypeclub/feature/extra_work_folders

General: Workdir extra folders
This commit is contained in:
Jakub Trllo 2022-01-03 09:43:27 +01:00 committed by GitHub
commit 62bd44ca95
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 145 additions and 60 deletions

View 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,
)

View file

@ -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",

View file

@ -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:
"""

View file

@ -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:

View file

@ -291,21 +291,7 @@
"enabled": false
}
],
"sw_folders": {
"compositing": [
"nuke",
"ae"
],
"modeling": [
"maya",
"blender",
"zbrush"
],
"lookdev": [
"substance",
"textures"
]
}
"extra_folders": []
},
"loader": {
"family_filter_profiles": [

View file

@ -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"
}
]
}
}
]

View file

@ -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()