improve the code and the error message & docstring

This commit is contained in:
Kayla Man 2024-02-28 18:53:44 +08:00
parent ff052520dd
commit fadf820fea
2 changed files with 116 additions and 70 deletions

View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<root>
<error id="main">
<title>Invalid Model Name</title>
<description>## Nodes found with Invalid Model Name
Nodes were detected in your scene which have invalid model name which does not
match the regex you preset in AYON setting.
### How to repair?
Make sure the model name aligns with validation regex in your AYON setting.
</description>
<detail>
### Invalid nodes
{nodes}
### How could this happen?
This often happens if you have mesh with the model naming does not match
with regex in the setting.
</detail>
</error>
</root>

View file

@ -3,30 +3,34 @@
import re
import pyblish.api
from pymxs import runtime as rt
from ayon_core.hosts.max.api.action import SelectInvalidAction
from ayon_core.pipeline.publish import (
OptionalPyblishPluginMixin,
PublishValidationError,
ValidateContentsOrder)
PublishXmlValidationError,
ValidateContentsOrder
)
class ValidateModelName(pyblish.api.InstancePlugin,
OptionalPyblishPluginMixin):
"""Validate Model Name
Validation regex is (.*)_(?P<subset>.*)_(GEO) by default.
e.g. {SOME_RANDOM_NAME}_{YOUR_SUBSET_NAME}_GEO should be your
default model name
"""Validate Model Name.
The regex of (?P<subset>.*) can be replaced by (?P<asset>.*)
and (?P<project>.*).
e.g.
- (.*)_(?P<asset>.*)_(GEO) check if your model name is
{SOME_RANDOM_NAME}_{CURRENT_ASSET_NAME}_GEO
- (.*)_(?P<project>.*)_(GEO) check if your model name is
{SOME_RANDOM_NAME}_{CURRENT_PROJECT_NAME}_GEO
Validation regex is `(.*)_(?P<subset>.*)_(GEO)` by default.
The setting supports the following regex group name:
- project
- asset
- subset
Examples:
`{SOME_RANDOM_NAME}_{YOUR_SUBSET_NAME}_GEO` should be your
default model name.
The regex of `(?P<subset>.*)` can be replaced by `(?P<asset>.*)`
and `(?P<project>.*)`.
`(.*)_(?P<asset>.*)_(GEO)` check if your model name is
`{SOME_RANDOM_NAME}_{CURRENT_ASSET_NAME}_GEO`
`(.*)_(?P<project>.*)_(GEO)` check if your model name is
`{SOME_RANDOM_NAME}_{CURRENT_PROJECT_NAME}_GEO`
"""
optional = True
@ -35,66 +39,82 @@ class ValidateModelName(pyblish.api.InstancePlugin,
families = ["model"]
label = "Validate Model Name"
actions = [SelectInvalidAction]
regex = ""
@classmethod
def get_invalid(cls, instance):
invalid = []
model_names = [model.name for model in instance.data.get("members")]
cls.log.debug(model_names)
if not model_names:
cls.log.error("No Model found in the OP Data.")
invalid.append(model_names)
for name in model_names:
invalid_model_name = cls.get_invalid_model_name(instance, name)
invalid.extend(invalid_model_name)
return invalid
@classmethod
def get_invalid_model_name(cls, instance, name):
invalid = []
regex = cls.regex
reg = re.compile(regex)
matched_name = reg.match(name)
project_name = instance.context.data["projectName"]
current_asset_name = instance.context.data["folderPath"]
if matched_name is None:
cls.log.error("invalid model name on: {}".format(name))
cls.log.error("name doesn't match regex {}".format(regex))
invalid.append((rt.getNodeByName(name),
"Model name doesn't match regex"))
else:
if "asset" in reg.groupindex:
if matched_name.group("asset") != current_asset_name:
cls.log.error(
"Invalid asset name of the model {}.".format(name)
)
invalid.append((rt.getNodeByName(name),
"Model with invalid asset name"))
if "subset" in reg.groupindex:
if matched_name.group("subset") != instance.name:
cls.log.error(
"Invalid subset name of the model {}.".format(name)
)
invalid.append((rt.getNodeByName(name),
"Model with invalid subset name"))
if "project" in reg.groupindex:
if matched_name.group("project") != project_name:
cls.log.error(
"Invalid project name of the model {}.".format(name)
)
invalid.append((rt.getNodeByName(name),
"Model with invalid project name"))
return invalid
# defined by settings
regex = r"(.*)_(?P<subset>.*)_(GEO)"
# cache
regex_compiled = None
def process(self, instance):
if not self.is_active(instance.data):
self.log.debug("Skipping Validate Model Name...")
return
invalid = self.get_invalid(instance)
if invalid:
names = "\n".join(
"- {}".format(node.name) for node in invalid
)
raise PublishXmlValidationError(
plugin=self,
message="Nodes found with invalid model names: {}".format(invalid),
formatting_data={"nodes": names}
)
@classmethod
def get_invalid(cls, instance):
if not cls.regex:
cls.log.warning("No regex pattern set. Nothing to validate.")
return
members = instance.data.get("members")
if not members:
cls.log.error("No members found in the instance.")
return
cls.regex_compiled = re.compile(cls.regex)
invalid = []
for obj in members:
if cls.invalid_name(instance, obj):
invalid.append(obj)
return invalid
@classmethod
def invalid_name(cls, instance, obj):
"""Function to check the object has invalid name
regarding to the validation regex in the AYON setttings
Args:
instance (pyblish.api.instance): Instance
obj (str): object name
Returns:
str: invalid object
"""
regex = cls.regex_compiled
name = obj.name
match = regex.match(name)
if match is None:
cls.log.error("Invalid model name on: %s", name)
cls.log.error("Name doesn't match regex {}".format(regex.pattern))
return obj
# Validate regex groups
invalid = False
compare = {
"project": instance.context.data["projectName"],
"asset": instance.context.data["folderPath"],
"subset": instance.context.data["subset"],
}
for key, required_value in compare.items():
if key in regex.groupindex:
if match.group(key) != required_value:
cls.log.error(
"Invalid %s name for the model %s, "
"required name is %s",
key, name, required_value
)
invalid = True
if invalid:
raise PublishValidationError(
"Model naming is invalid. See the log.")
return obj