import nuke import pyblish.api import pype.api class ValidateKnobs(pyblish.api.ContextPlugin): """Ensure knobs are consistent. Knobs to validate and their values comes from the Controled by plugin settings that require json in following structure: "ValidateKnobs": { "enabled": true, "knobs": { "family": { "knob_name": knob_value } } } """ order = pyblish.api.ValidatorOrder label = "Validate Knobs" hosts = ["nuke"] actions = [pype.api.RepairContextAction] optional = True def process(self, context): invalid = self.get_invalid(context, compute=True) if invalid: raise RuntimeError( "Found knobs with invalid values:\n{}".format(invalid) ) @classmethod def get_invalid(cls, context, compute=False): invalid = context.data.get("invalid_knobs", []) if compute: invalid = cls.get_invalid_knobs(context) return invalid @classmethod def get_invalid_knobs(cls, context): invalid_knobs = [] for instance in context: # Filter publisable instances. if not instance.data["publish"]: continue # Filter families. families = [instance.data["family"]] families += instance.data.get("families", []) families = list(set(families) & set(self.knobs.keys())) if not families: continue # Get all knobs to validate. knobs = {} for family in families: for preset in self.knobs[family]: knobs.update({preset: self.knobs[family][preset]}) # Get invalid knobs. nodes = [] for node in nuke.allNodes(): nodes.append(node) if node.Class() == "Group": node.begin() for i in nuke.allNodes(): nodes.append(i) node.end() for node in nodes: for knob in node.knobs(): if knob not in knobs.keys(): continue expected = knobs[knob] if node[knob].value() != expected: invalid_knobs.append( { "knob": node[knob], "name": node[knob].name(), "label": node[knob].label(), "expected": expected, "current": node[knob].value() } ) context.data["invalid_knobs"] = invalid_knobs return invalid_knobs @classmethod def repair(cls, instance): invalid = cls.get_invalid(instance) for data in invalid: if isinstance(data["expected"], unicode): data["knob"].setValue(str(data["expected"])) continue data["knob"].setValue(data["expected"])