Skip to content

collect_status

CollectStatus

Bases: InstancePlugin, AYONPyblishPluginMixin

Allow to define version status for published version. It is possible to change setttings so user can set status in publisher UI.

Source code in client/ayon_core/plugins/publish/collect_status.py
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
class CollectStatus(pyblish.api.InstancePlugin, AYONPyblishPluginMixin):
    """Allow to define version status for published version.
    It is possible to change setttings so user can set status in publisher UI.
    """

    order = pyblish.api.CollectorOrder + 0.499
    label = "Collect Version Status"

    enabled = False
    status_profiles: list[dict] = []

    def process(self, instance):
        if not self.status_profiles:
            return

        if instance.data.get("status"):
            # already set so we won't override it
            return
        attr_values = self.get_attr_values_from_data(instance.data)
        status_state = attr_values.get("status_state")
        if not status_state or status_state == "dont_use":
            return

        if status_state == "use_status":
            status = attr_values.get("status", "")
        elif status_state.startswith("status|"):
            status = status_state.removeprefix("status|")
        else:
            return
        if status:
            instance.data["status"] = status

    @classmethod
    def get_attr_defs_for_instance(
        cls, create_context: "CreateContext", instance: "CreatedInstance"
    ):
        status_state_attr = TextDef(
            "status_state", visible=False, default="dont_use"
        )
        output = [status_state_attr]
        if not cls.status_profiles:
            cls._set_instance_state(instance, status_state_attr, "dont_use")
            return output

        project_entity = create_context.get_current_project_entity()
        statuses = [
            status["name"]
            for status in project_entity["statuses"]
            if "version" in status["scope"]
        ]
        if not statuses:
            cls.log.warning("No version statuses found in current project.")
            cls._set_instance_state(instance, status_state_attr, "dont_use")
            return output

        folder_path = instance.get("folderPath")
        folder_entity = create_context.get_folder_entity(folder_path)
        task_entity = None
        task_name = None
        task_type = None
        if folder_entity:
            task_name = instance.get("task")
            task_entity = create_context.get_task_entity(
                folder_path, task_name
            )
            if task_entity:
                task_type = task_entity["taskType"]

        filter_data = {
            "host_names": create_context.host_name,
            "task_types": task_type,
            "task_names": task_name,
            "product_base_types": instance.product_base_type,
        }

        status_profile = filter_profiles(
            cls.status_profiles,
            filter_data,
            logger=cls.log
        )
        default_status = None
        artist_can_change = True
        if status_profile:
            artist_can_change = status_profile["artist_can_change"]
            default_status = status_profile["default_status"]

        if default_status not in statuses:
            if status_profile:
                cls.log.warning(
                    f"Default status '{default_status}' is not available"
                    f" on project: {project_entity['name']}"
                    f"Using '{statuses[0]}' instead."
                )
            default_status = statuses[0]

        if not artist_can_change:
            cls._set_instance_state(
                instance, status_state_attr, f"status|{default_status}"
            )
            cls.log.debug(
                "Artist cannot change status based on profile settings."
            )
            return output

        cls._set_instance_state(instance, status_state_attr, "use_status")

        output.append(EnumDef(
           "status",
            label="Version status",
            items=statuses,
            default=default_status,
        ))
        return output

    @classmethod
    def _set_instance_state(
        cls,
        instance: "CreatedInstance",
        status_state_attr: "TextDef",
        state: str
    ) -> None:
        status_state_attr.default = state
        plugin_attributes = instance.publish_attributes.get(cls.__name__)
        if plugin_attributes is None:
            return

        plugin_attributes["status_state"] = state