mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
Merge pull request #3755 from pypeclub/feature/OP-3842_Change-publish-template-settings-location
General: Change publish template settings location
This commit is contained in:
commit
31b4b3ffdc
9 changed files with 354 additions and 92 deletions
|
|
@ -22,6 +22,8 @@ from .publish_plugins import (
|
|||
)
|
||||
|
||||
from .lib import (
|
||||
get_publish_template_name,
|
||||
|
||||
DiscoverResult,
|
||||
publish_plugins_discover,
|
||||
load_help_content_from_plugin,
|
||||
|
|
@ -62,6 +64,8 @@ __all__ = (
|
|||
|
||||
"Extractor",
|
||||
|
||||
"get_publish_template_name",
|
||||
|
||||
"DiscoverResult",
|
||||
"publish_plugins_discover",
|
||||
"load_help_content_from_plugin",
|
||||
|
|
|
|||
2
openpype/pipeline/publish/contants.py
Normal file
2
openpype/pipeline/publish/contants.py
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
DEFAULT_PUBLISH_TEMPLATE = "publish"
|
||||
DEFAULT_HERO_PUBLISH_TEMPLATE = "hero"
|
||||
|
|
@ -2,6 +2,7 @@ import os
|
|||
import sys
|
||||
import types
|
||||
import inspect
|
||||
import copy
|
||||
import tempfile
|
||||
import xml.etree.ElementTree
|
||||
|
||||
|
|
@ -9,8 +10,190 @@ import six
|
|||
import pyblish.plugin
|
||||
import pyblish.api
|
||||
|
||||
from openpype.lib import Logger
|
||||
from openpype.settings import get_project_settings, get_system_settings
|
||||
from openpype.lib import Logger, filter_profiles
|
||||
from openpype.settings import (
|
||||
get_project_settings,
|
||||
get_system_settings,
|
||||
)
|
||||
|
||||
from .contants import (
|
||||
DEFAULT_PUBLISH_TEMPLATE,
|
||||
DEFAULT_HERO_PUBLISH_TEMPLATE,
|
||||
)
|
||||
|
||||
|
||||
def get_template_name_profiles(
|
||||
project_name, project_settings=None, logger=None
|
||||
):
|
||||
"""Receive profiles for publish template keys.
|
||||
|
||||
At least one of arguments must be passed.
|
||||
|
||||
Args:
|
||||
project_name (str): Name of project where to look for templates.
|
||||
project_settings(Dic[str, Any]): Prepared project settings.
|
||||
|
||||
Returns:
|
||||
List[Dict[str, Any]]: Publish template profiles.
|
||||
"""
|
||||
|
||||
if not project_name and not project_settings:
|
||||
raise ValueError((
|
||||
"Both project name and project settings are missing."
|
||||
" At least one must be entered."
|
||||
))
|
||||
|
||||
if not project_settings:
|
||||
project_settings = get_project_settings(project_name)
|
||||
|
||||
profiles = (
|
||||
project_settings
|
||||
["global"]
|
||||
["tools"]
|
||||
["publish"]
|
||||
["template_name_profiles"]
|
||||
)
|
||||
if profiles:
|
||||
return copy.deepcopy(profiles)
|
||||
|
||||
# Use legacy approach for cases new settings are not filled yet for the
|
||||
# project
|
||||
legacy_profiles = (
|
||||
project_settings
|
||||
["global"]
|
||||
["publish"]
|
||||
["IntegrateAssetNew"]
|
||||
["template_name_profiles"]
|
||||
)
|
||||
if legacy_profiles:
|
||||
if not logger:
|
||||
logger = Logger.get_logger("get_template_name_profiles")
|
||||
|
||||
logger.warning((
|
||||
"Project \"{}\" is using legacy access to publish template."
|
||||
" It is recommended to move settings to new location"
|
||||
" 'project_settings/global/tools/publish/template_name_profiles'."
|
||||
).format(project_name))
|
||||
|
||||
# Replace "tasks" key with "task_names"
|
||||
profiles = []
|
||||
for profile in copy.deepcopy(legacy_profiles):
|
||||
profile["task_names"] = profile.pop("tasks", [])
|
||||
profiles.append(profile)
|
||||
return profiles
|
||||
|
||||
|
||||
def get_hero_template_name_profiles(
|
||||
project_name, project_settings=None, logger=None
|
||||
):
|
||||
"""Receive profiles for hero publish template keys.
|
||||
|
||||
At least one of arguments must be passed.
|
||||
|
||||
Args:
|
||||
project_name (str): Name of project where to look for templates.
|
||||
project_settings(Dic[str, Any]): Prepared project settings.
|
||||
|
||||
Returns:
|
||||
List[Dict[str, Any]]: Publish template profiles.
|
||||
"""
|
||||
|
||||
if not project_name and not project_settings:
|
||||
raise ValueError((
|
||||
"Both project name and project settings are missing."
|
||||
" At least one must be entered."
|
||||
))
|
||||
|
||||
if not project_settings:
|
||||
project_settings = get_project_settings(project_name)
|
||||
|
||||
profiles = (
|
||||
project_settings
|
||||
["global"]
|
||||
["tools"]
|
||||
["publish"]
|
||||
["hero_template_name_profiles"]
|
||||
)
|
||||
if profiles:
|
||||
return copy.deepcopy(profiles)
|
||||
|
||||
# Use legacy approach for cases new settings are not filled yet for the
|
||||
# project
|
||||
legacy_profiles = copy.deepcopy(
|
||||
project_settings
|
||||
["global"]
|
||||
["publish"]
|
||||
["IntegrateHeroVersion"]
|
||||
["template_name_profiles"]
|
||||
)
|
||||
if legacy_profiles:
|
||||
if not logger:
|
||||
logger = Logger.get_logger("get_hero_template_name_profiles")
|
||||
|
||||
logger.warning((
|
||||
"Project \"{}\" is using legacy access to hero publish template."
|
||||
" It is recommended to move settings to new location"
|
||||
" 'project_settings/global/tools/publish/"
|
||||
"hero_template_name_profiles'."
|
||||
).format(project_name))
|
||||
return legacy_profiles
|
||||
|
||||
|
||||
def get_publish_template_name(
|
||||
project_name,
|
||||
host_name,
|
||||
family,
|
||||
task_name,
|
||||
task_type,
|
||||
project_settings=None,
|
||||
hero=False,
|
||||
logger=None
|
||||
):
|
||||
"""Get template name which should be used for passed context.
|
||||
|
||||
Publish templates are filtered by host name, family, task name and
|
||||
task type.
|
||||
|
||||
Default template which is used at if profiles are not available or profile
|
||||
has empty value is defined by 'DEFAULT_PUBLISH_TEMPLATE' constant.
|
||||
|
||||
Args:
|
||||
project_name (str): Name of project where to look for settings.
|
||||
host_name (str): Name of host integration.
|
||||
family (str): Family for which should be found template.
|
||||
task_name (str): Task name on which is intance working.
|
||||
task_type (str): Task type on which is intance working.
|
||||
project_setting (Dict[str, Any]): Prepared project settings.
|
||||
logger (logging.Logger): Custom logger used for 'filter_profiles'
|
||||
function.
|
||||
|
||||
Returns:
|
||||
str: Template name which should be used for integration.
|
||||
"""
|
||||
|
||||
template = None
|
||||
filter_criteria = {
|
||||
"hosts": host_name,
|
||||
"families": family,
|
||||
"task_names": task_name,
|
||||
"task_types": task_type,
|
||||
}
|
||||
if hero:
|
||||
default_template = DEFAULT_HERO_PUBLISH_TEMPLATE
|
||||
profiles = get_hero_template_name_profiles(
|
||||
project_name, project_settings, logger
|
||||
)
|
||||
|
||||
else:
|
||||
profiles = get_template_name_profiles(
|
||||
project_name, project_settings, logger
|
||||
)
|
||||
default_template = DEFAULT_PUBLISH_TEMPLATE
|
||||
|
||||
profile = filter_profiles(profiles, filter_criteria, logger=logger)
|
||||
if profile:
|
||||
template = profile["template_name"]
|
||||
return template or default_template
|
||||
|
||||
|
||||
class DiscoverResult:
|
||||
|
|
|
|||
|
|
@ -5,6 +5,9 @@ import copy
|
|||
import clique
|
||||
import six
|
||||
|
||||
from bson.objectid import ObjectId
|
||||
import pyblish.api
|
||||
|
||||
from openpype.client.operations import (
|
||||
OperationsSession,
|
||||
new_subset_document,
|
||||
|
|
@ -14,8 +17,6 @@ from openpype.client.operations import (
|
|||
prepare_version_update_data,
|
||||
prepare_representation_update_data,
|
||||
)
|
||||
from bson.objectid import ObjectId
|
||||
import pyblish.api
|
||||
|
||||
from openpype.client import (
|
||||
get_representations,
|
||||
|
|
@ -23,10 +24,12 @@ from openpype.client import (
|
|||
get_version_by_name,
|
||||
)
|
||||
from openpype.lib import source_hash
|
||||
from openpype.lib.profiles_filtering import filter_profiles
|
||||
from openpype.lib.file_transaction import FileTransaction
|
||||
from openpype.pipeline import legacy_io
|
||||
from openpype.pipeline.publish import KnownPublishError
|
||||
from openpype.pipeline.publish import (
|
||||
KnownPublishError,
|
||||
get_publish_template_name,
|
||||
)
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
|
@ -792,52 +795,26 @@ class IntegrateAsset(pyblish.api.InstancePlugin):
|
|||
|
||||
def get_template_name(self, instance):
|
||||
"""Return anatomy template name to use for integration"""
|
||||
# Define publish template name from profiles
|
||||
filter_criteria = self.get_profile_filter_criteria(instance)
|
||||
template_name_profiles = self._get_template_name_profiles(instance)
|
||||
profile = filter_profiles(
|
||||
template_name_profiles,
|
||||
filter_criteria,
|
||||
logger=self.log
|
||||
)
|
||||
|
||||
if profile:
|
||||
return profile["template_name"]
|
||||
return self.default_template_name
|
||||
|
||||
def _get_template_name_profiles(self, instance):
|
||||
"""Receive profiles for publish template keys.
|
||||
|
||||
Reuse template name profiles from legacy integrator. Goal is to move
|
||||
the profile settings out of plugin settings but until that happens we
|
||||
want to be able set it at one place and don't break backwards
|
||||
compatibility (more then once).
|
||||
"""
|
||||
|
||||
return (
|
||||
instance.context.data["project_settings"]
|
||||
["global"]
|
||||
["publish"]
|
||||
["IntegrateAssetNew"]
|
||||
["template_name_profiles"]
|
||||
)
|
||||
|
||||
def get_profile_filter_criteria(self, instance):
|
||||
"""Return filter criteria for `filter_profiles`"""
|
||||
|
||||
# Anatomy data is pre-filled by Collectors
|
||||
anatomy_data = instance.data["anatomyData"]
|
||||
|
||||
project_name = legacy_io.active_project()
|
||||
|
||||
# Task can be optional in anatomy data
|
||||
task = anatomy_data.get("task", {})
|
||||
host_name = instance.context.data["hostName"]
|
||||
anatomy_data = instance.data["anatomyData"]
|
||||
family = anatomy_data["family"]
|
||||
task_info = anatomy_data.get("task") or {}
|
||||
|
||||
# Return filter criteria
|
||||
return {
|
||||
"families": anatomy_data["family"],
|
||||
"tasks": task.get("name"),
|
||||
"task_types": task.get("type"),
|
||||
"hosts": instance.context.data["hostName"],
|
||||
}
|
||||
return get_publish_template_name(
|
||||
project_name,
|
||||
host_name,
|
||||
family,
|
||||
task_name=task_info.get("name"),
|
||||
task_type=task_info.get("type"),
|
||||
project_settings=instance.context.data["project_settings"],
|
||||
logger=self.log
|
||||
)
|
||||
|
||||
def get_rootless_path(self, anatomy, path):
|
||||
"""Returns, if possible, path without absolute portion from root
|
||||
|
|
|
|||
|
|
@ -14,14 +14,12 @@ from openpype.client import (
|
|||
get_archived_representations,
|
||||
get_representations,
|
||||
)
|
||||
from openpype.lib import (
|
||||
create_hard_link,
|
||||
filter_profiles
|
||||
)
|
||||
from openpype.lib import create_hard_link
|
||||
from openpype.pipeline import (
|
||||
schema,
|
||||
legacy_io,
|
||||
)
|
||||
from openpype.pipeline.publish import get_publish_template_name
|
||||
|
||||
|
||||
class IntegrateHeroVersion(pyblish.api.InstancePlugin):
|
||||
|
|
@ -68,10 +66,11 @@ class IntegrateHeroVersion(pyblish.api.InstancePlugin):
|
|||
)
|
||||
return
|
||||
|
||||
template_key = self._get_template_key(instance)
|
||||
|
||||
anatomy = instance.context.data["anatomy"]
|
||||
project_name = anatomy.project_name
|
||||
|
||||
template_key = self._get_template_key(project_name, instance)
|
||||
|
||||
if template_key not in anatomy.templates:
|
||||
self.log.warning((
|
||||
"!!! Anatomy of project \"{}\" does not have set"
|
||||
|
|
@ -527,30 +526,24 @@ class IntegrateHeroVersion(pyblish.api.InstancePlugin):
|
|||
|
||||
return publish_folder
|
||||
|
||||
def _get_template_key(self, instance):
|
||||
def _get_template_key(self, project_name, instance):
|
||||
anatomy_data = instance.data["anatomyData"]
|
||||
task_data = anatomy_data.get("task") or {}
|
||||
task_name = task_data.get("name")
|
||||
task_type = task_data.get("type")
|
||||
task_info = anatomy_data.get("task") or {}
|
||||
host_name = instance.context.data["hostName"]
|
||||
|
||||
# TODO raise error if Hero not set?
|
||||
family = self.main_family_from_instance(instance)
|
||||
key_values = {
|
||||
"families": family,
|
||||
"task_names": task_name,
|
||||
"task_types": task_type,
|
||||
"hosts": host_name
|
||||
}
|
||||
profile = filter_profiles(
|
||||
self.template_name_profiles,
|
||||
key_values,
|
||||
|
||||
return get_publish_template_name(
|
||||
project_name,
|
||||
host_name,
|
||||
family,
|
||||
task_info.get("name"),
|
||||
task_info.get("type"),
|
||||
project_settings=instance.context.data["project_settings"],
|
||||
hero=True,
|
||||
logger=self.log
|
||||
)
|
||||
if profile:
|
||||
template_name = profile["template_name"]
|
||||
else:
|
||||
template_name = self._default_template_name
|
||||
return template_name
|
||||
|
||||
def main_family_from_instance(self, instance):
|
||||
"""Returns main family of entered instance."""
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ from bson.objectid import ObjectId
|
|||
from pymongo import DeleteOne, InsertOne
|
||||
import pyblish.api
|
||||
|
||||
import openpype.api
|
||||
from openpype.client import (
|
||||
get_asset_by_name,
|
||||
get_subset_by_id,
|
||||
|
|
@ -25,14 +24,17 @@ from openpype.client import (
|
|||
get_representations,
|
||||
get_archived_representations,
|
||||
)
|
||||
from openpype.lib.profiles_filtering import filter_profiles
|
||||
from openpype.lib import (
|
||||
prepare_template_data,
|
||||
create_hard_link,
|
||||
StringTemplate,
|
||||
TemplateUnsolved
|
||||
TemplateUnsolved,
|
||||
source_hash,
|
||||
filter_profiles,
|
||||
get_local_site_id,
|
||||
)
|
||||
from openpype.pipeline import legacy_io
|
||||
from openpype.pipeline.publish import get_publish_template_name
|
||||
|
||||
# this is needed until speedcopy for linux is fixed
|
||||
if sys.platform == "win32":
|
||||
|
|
@ -138,7 +140,6 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin):
|
|||
integrated_file_sizes = {}
|
||||
|
||||
# Attributes set by settings
|
||||
template_name_profiles = None
|
||||
subset_grouping_profiles = None
|
||||
|
||||
def process(self, instance):
|
||||
|
|
@ -388,22 +389,16 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin):
|
|||
|
||||
family = self.main_family_from_instance(instance)
|
||||
|
||||
key_values = {
|
||||
"families": family,
|
||||
"tasks": task_name,
|
||||
"hosts": instance.context.data["hostName"],
|
||||
"task_types": task_type
|
||||
}
|
||||
profile = filter_profiles(
|
||||
self.template_name_profiles,
|
||||
key_values,
|
||||
template_name = get_publish_template_name(
|
||||
project_name,
|
||||
instance.context.data["hostName"],
|
||||
family,
|
||||
task_name=task_info.get("name"),
|
||||
task_type=task_info.get("type"),
|
||||
project_settings=instance.context.data["project_settings"],
|
||||
logger=self.log
|
||||
)
|
||||
|
||||
template_name = "publish"
|
||||
if profile:
|
||||
template_name = profile["template_name"]
|
||||
|
||||
published_representations = {}
|
||||
for idx, repre in enumerate(repres):
|
||||
published_files = []
|
||||
|
|
@ -1058,7 +1053,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin):
|
|||
for _src, dest in resources:
|
||||
path = self.get_rootless_path(anatomy, dest)
|
||||
dest = self.get_dest_temp_url(dest)
|
||||
file_hash = openpype.api.source_hash(dest)
|
||||
file_hash = source_hash(dest)
|
||||
if self.TMP_FILE_EXT and \
|
||||
',{}'.format(self.TMP_FILE_EXT) in file_hash:
|
||||
file_hash = file_hash.replace(',{}'.format(self.TMP_FILE_EXT),
|
||||
|
|
@ -1168,7 +1163,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin):
|
|||
|
||||
def _get_sites(self, sync_project_presets):
|
||||
"""Returns tuple (local_site, remote_site)"""
|
||||
local_site_id = openpype.api.get_local_site_id()
|
||||
local_site_id = get_local_site_id()
|
||||
local_site = sync_project_presets["config"]. \
|
||||
get("active_site", "studio").strip()
|
||||
|
||||
|
|
|
|||
|
|
@ -418,6 +418,10 @@
|
|||
"filter_families": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"publish": {
|
||||
"template_name_profiles": [],
|
||||
"hero_template_name_profiles": []
|
||||
}
|
||||
},
|
||||
"project_folder_structure": "{\"__project_root__\": {\"prod\": {}, \"resources\": {\"footage\": {\"plates\": {}, \"offline\": {}}, \"audio\": {}, \"art_dept\": {}}, \"editorial\": {}, \"assets\": {\"characters\": {}, \"locations\": {}}, \"shots\": {}}}",
|
||||
|
|
|
|||
|
|
@ -663,10 +663,14 @@
|
|||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"label": "<b>NOTE:</b> Publish template profiles settings were moved to <a href=\"settings://project_settings/global/tools/publish/template_name_profiles\"><b>Tools/Publish/Template name profiles</b></a>. Please move values there."
|
||||
},
|
||||
{
|
||||
"type": "list",
|
||||
"key": "template_name_profiles",
|
||||
"label": "Template name profiles",
|
||||
"label": "Template name profiles (DEPRECATED)",
|
||||
"use_label_wrap": true,
|
||||
"object_type": {
|
||||
"type": "dict",
|
||||
|
|
@ -771,10 +775,14 @@
|
|||
"type": "list",
|
||||
"object_type": "text"
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"label": "<b>NOTE:</b> Hero publish template profiles settings were moved to <a href=\"settings://project_settings/global/tools/publish/hero_template_name_profiles\"><b>Tools/Publish/Hero template name profiles</b></a>. Please move values there."
|
||||
},
|
||||
{
|
||||
"type": "list",
|
||||
"key": "template_name_profiles",
|
||||
"label": "Template name profiles",
|
||||
"label": "Template name profiles (DEPRECATED)",
|
||||
"use_label_wrap": true,
|
||||
"object_type": {
|
||||
"type": "dict",
|
||||
|
|
|
|||
|
|
@ -284,6 +284,102 @@
|
|||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "dict",
|
||||
"key": "publish",
|
||||
"label": "Publish",
|
||||
"children": [
|
||||
{
|
||||
"type": "label",
|
||||
"label": "<b>NOTE:</b> For backwards compatibility can be value empty and in that case are used values from <a href=\"settings://project_settings/global/publish/IntegrateAssetNew\"><b>IntegrateAssetNew</b></a>. This will change in future so please move all values here as soon as possible."
|
||||
},
|
||||
{
|
||||
"type": "list",
|
||||
"key": "template_name_profiles",
|
||||
"label": "Template name profiles",
|
||||
"use_label_wrap": true,
|
||||
"object_type": {
|
||||
"type": "dict",
|
||||
"children": [
|
||||
{
|
||||
"key": "families",
|
||||
"label": "Families",
|
||||
"type": "list",
|
||||
"object_type": "text"
|
||||
},
|
||||
{
|
||||
"type": "hosts-enum",
|
||||
"key": "hosts",
|
||||
"label": "Hosts",
|
||||
"multiselection": true
|
||||
},
|
||||
{
|
||||
"key": "task_types",
|
||||
"label": "Task types",
|
||||
"type": "task-types-enum"
|
||||
},
|
||||
{
|
||||
"key": "task_names",
|
||||
"label": "Task names",
|
||||
"type": "list",
|
||||
"object_type": "text"
|
||||
},
|
||||
{
|
||||
"type": "separator"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"key": "template_name",
|
||||
"label": "Template name"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "list",
|
||||
"key": "hero_template_name_profiles",
|
||||
"label": "Hero template name profiles",
|
||||
"use_label_wrap": true,
|
||||
"object_type": {
|
||||
"type": "dict",
|
||||
"children": [
|
||||
{
|
||||
"key": "families",
|
||||
"label": "Families",
|
||||
"type": "list",
|
||||
"object_type": "text"
|
||||
},
|
||||
{
|
||||
"type": "hosts-enum",
|
||||
"key": "hosts",
|
||||
"label": "Hosts",
|
||||
"multiselection": true
|
||||
},
|
||||
{
|
||||
"key": "task_types",
|
||||
"label": "Task types",
|
||||
"type": "task-types-enum"
|
||||
},
|
||||
{
|
||||
"key": "task_names",
|
||||
"label": "Task names",
|
||||
"type": "list",
|
||||
"object_type": "text"
|
||||
},
|
||||
{
|
||||
"type": "separator"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"key": "template_name",
|
||||
"label": "Template name",
|
||||
"tooltip": "Name of template from Anatomy templates"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue