diff --git a/.gitignore b/.gitignore index f379b516..7b25526f 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ __pycache__ .vscode poetry.lock package/ +package.py frontend/node_modules frontend/dist diff --git a/client/ayon_kitsu/addon.py b/client/ayon_kitsu/addon.py index b69b1e73..e8c0f8a8 100644 --- a/client/ayon_kitsu/addon.py +++ b/client/ayon_kitsu/addon.py @@ -96,13 +96,15 @@ def get_plugin_paths(self): return { "publish": self.get_publish_plugin_paths(), + "hooks": self.get_launch_hook_paths(), # The laucher action is not working since AYON conversion # "actions": [os.path.join(KITSU_ROOT, "plugins", "launcher")], } def get_publish_plugin_paths(self, host_name=None): return [os.path.join(KITSU_ROOT, "plugins", "publish")] - + def get_launch_hook_paths(self, host_name=None): + return [os.path.join(KITSU_ROOT, "hooks")] def is_kitsu_enabled_in_settings(project_settings): """Check if kitsu is enabled in kitsu project settings. diff --git a/client/ayon_kitsu/hooks/pre_status_change.py b/client/ayon_kitsu/hooks/pre_status_change.py new file mode 100644 index 00000000..571e9fb8 --- /dev/null +++ b/client/ayon_kitsu/hooks/pre_status_change.py @@ -0,0 +1,107 @@ +from ayon_applications import PostLaunchHook + +import os +import gazu + +class PreKitsuStatusChange(PostLaunchHook): + """On launch of an application change task statuses on Kitsu. + + When launching an application this launch hook may change the + status on Kitsu with the relevant task id. + + If "pause other tasks" is enabled this will also change the status of + all other tasks to the paused task status. This can be useful for + X, Y, Z. + """ + order = 1 + launch_types = set() + + # status settings + set_status_app_start_note = False + app_start_status_shortname = "wip" + status_change_conditions = { + "status_conditions": [] + } + + # comment settings + custom_comment_template = { + "enabled": False, + "comment_template": "{comment}", + } + def execute(self): + if "KITSU_LOGIN" not in os.environ: + self.log.info( + "KITSU_LOGIN is not set. assuming rendeing in deadline. Skipping status." + ) + return + + data = self.launch_context.data + project_settings = data["project_settings"]["kitsu"]["appstart"] + + if project_settings["set_status_app_start_note"]: + self.log.info("Kitsu Status change is Enabled.") + else: + self.log.info("Kitsu Status change is disabled.") + return + + if not project_settings["app_start_status_shortname"]: + self.log.info("App starting status in not configured") + return + app_start_status_shortname= project_settings[ + "app_start_status_shortname" + ] + + if project_settings["app_startstatus_change_conditions"]: + status_conditions= project_settings["app_startstatus_change_conditions"] + else: + self.log.info("Status change condotions are empty") + + gazu.set_host(os.environ["KITSU_SERVER"]) + gazu.log_in(os.environ["KITSU_LOGIN"], os.environ["KITSU_PWD"]) + + if not self.data["task_entity"]["data"].get("kitsuId"): + self.log.info("This task does not have a kitsu task id. Skipping kitsu task status change.") + return + + kitsuId = self.data["task_entity"]["data"]["kitsuId"] + task=gazu.task.get_task(kitsuId) + task_current_status_shortname= task["task_status"]["short_name"] + + # Check if any status condition is not met + allow_status_change = True + for status_cond in status_conditions: + condition = status_cond["condition"] == "equal" + match = status_cond["short_name"] == task_current_status_shortname + if match and not condition or condition and not match: + allow_status_change = False + break + + if allow_status_change: + if not gazu.task.get_task_status_by_short_name(self.app_start_status_shortname): + self.log.info("Failed to recieve kitsu status instance for shortname. Skipping Status change.") + return + kitsu_wip_status = gazu.task.get_task_status_by_short_name(self.app_start_status_shortname) + + self.log.info("Current Kitsu task status is {task_current_status_shortname}. Task id {kitsuId}") + self.log.info("Changing Kitsu task status to {self.app_start_status_shortname}.") + + gazu.task.add_comment(task["id"], kitsu_wip_status) + + if not project_settings["set_pause_status_to_other_tasks"]: + self.log.info("Pausing all other tasks with same status disabled.") + else: + self.log.info("Pausing all other tasks with same status enabled.") + pause_status_shortname= project_settings["pause_status_shortname"] + if gazu.task.get_task_status_by_short_name(pause_status_shortname): + pause_status=gazu.task.get_task_status_by_short_name(pause_status_shortname) + user_tasks= gazu.user.all_tasks_to_do() + for other_task in user_tasks: + same_status = other_task["task_status_short_name"] == app_start_status_shortname + same_task = other_task["id"] == kitsuId + if same_status and not same_task: + gazu.task.add_comment(other_task["id"], pause_status,) + else: + self.log.info("Failed to recieve kitsu pause status instance. Skipping pause Status change.") + else: + self.log.info("Status not changed due to conditions: {status_conditions}") + gazu.log_out() diff --git a/client/ayon_kitsu/plugins/publish/integrate_kitsu_note.py b/client/ayon_kitsu/plugins/publish/integrate_kitsu_note.py index c06b0286..eb8eec3c 100644 --- a/client/ayon_kitsu/plugins/publish/integrate_kitsu_note.py +++ b/client/ayon_kitsu/plugins/publish/integrate_kitsu_note.py @@ -12,7 +12,7 @@ class IntegrateKitsuNote(KitsuPublishContextPlugin): order = pyblish.api.IntegratorOrder label = "Kitsu Note and Status" - families = ["kitsu"] + families = ["*"] # status settings set_status_note = False @@ -27,6 +27,8 @@ class IntegrateKitsuNote(KitsuPublishContextPlugin): "enabled": False, "comment_template": "{comment}", } + set_status_note_farm = False + note_farm_status_shortname = "farm" def format_publish_comment(self, instance): """Format the instance's publish comment @@ -62,16 +64,34 @@ def process(self, context): "family_requirements" ] + farm_status_change = False + + families= [] + + for instance in context: + if instance.data.get("farm"): + farm_status_change = True + + self.log.debug(f'Instance in context has farm flag: {farm_status_change}') + + if farm_status_change and self.set_status_note_farm: + kitsu_task = instance.data.get("kitsuTask") + farm_status = gazu.task.get_task_status_by_short_name(self.note_farm_status_shortname) + gazu.task.add_comment(kitsu_task, farm_status) + return + for instance in context: # Check if instance is a review by checking its family # Allow a match to primary family or any of families families = set( [instance.data["family"]] + instance.data.get("families", []) ) + if "review" not in families or "kitsu" not in families: continue kitsu_task = instance.data.get("kitsuTask") + if not kitsu_task: continue diff --git a/server/settings/app_start.py b/server/settings/app_start.py new file mode 100644 index 00000000..2ba4350a --- /dev/null +++ b/server/settings/app_start.py @@ -0,0 +1,34 @@ +from ayon_server.settings import BaseSettingsModel, SettingsField + + +def _status_change_cond_enum(): + return [ + {"value": "equal", "label": "Equal"}, + {"value": "not_equal", "label": "Not equal"}, + ] + + +class AppStartStatusChangeCondition(BaseSettingsModel): + condition: str = SettingsField( + "equal", enum_resolver=_status_change_cond_enum, title="Condition" + ) + short_name: str = SettingsField("", title="Short name") + + +class AppStartStatusChange(BaseSettingsModel): + set_status_app_start_note: bool = SettingsField(title="Set status change on app start") + app_start_status_shortname: str = SettingsField(title="App start Status shortname") + app_startstatus_change_conditions: list[AppStartStatusChangeCondition] = SettingsField( + default_factory=AppStartStatusChangeCondition, title="App start status change conditions" + ) + set_pause_status_to_other_tasks: bool = SettingsField(title="Set pause status to other tasks") + pause_status_shortname: str = SettingsField(title="Pause Status shortname") + + +APPSTART_DEFAULT_VALUES = { + "set_status_app_start_note": False, + "app_start_status_shortname": "wip", + "app_startstatus_change_conditions": [], + "set_pause_status_to_other_tasks": False, + "pause_status_shortname": "pause", + } diff --git a/server/settings/main.py b/server/settings/main.py index 36efdd5e..65b84d58 100644 --- a/server/settings/main.py +++ b/server/settings/main.py @@ -3,6 +3,7 @@ from .sync_settings import SyncSettings, SYNC_DEFAULT_VALUES from .publish_plugins import PublishPlugins, PUBLISH_DEFAULT_VALUES +from .app_start import AppStartStatusChange, APPSTART_DEFAULT_VALUES ## Entities naming pattern @@ -43,6 +44,10 @@ class KitsuSettings(BaseSettingsModel): default_factory=EntityPattern, title="Entities naming pattern", ) + appstart: AppStartStatusChange = SettingsField( + default_factory=AppStartStatusChange, + title="App start status change", + ) publish: PublishPlugins = SettingsField( default_factory=PublishPlugins, title="Publish plugins", @@ -59,6 +64,7 @@ class KitsuSettings(BaseSettingsModel): "sequence": "SQ##", "shot": "SH##", }, + "appstart": APPSTART_DEFAULT_VALUES, "publish": PUBLISH_DEFAULT_VALUES, "sync_settings": SYNC_DEFAULT_VALUES, } diff --git a/server/settings/publish_plugins.py b/server/settings/publish_plugins.py index 643415d7..d73436dc 100644 --- a/server/settings/publish_plugins.py +++ b/server/settings/publish_plugins.py @@ -103,6 +103,8 @@ class IntegrateKitsuNotes(BaseSettingsModel): default_factory=CustomCommentTemplateModel, title="Custom Comment Template", ) + set_status_note_farm: bool = SettingsField(title="Set status on note farm") + note_farm_status_shortname: str = SettingsField(title="Note farm shortname") class PublishPlugins(BaseSettingsModel): @@ -294,5 +296,7 @@ class PublishPlugins(BaseSettingsModel): | family | `{family}` | | name | `{name}` |""", }, + "set_status_note_farm": False, + "note_farm_status_shortname": "farm" } }