mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-26 13:52:15 +01:00
Merge branch 'develop' into feature/prettier_jsons
This commit is contained in:
commit
a82f7bcd1d
15 changed files with 812 additions and 140 deletions
20
pype.py
20
pype.py
|
|
@ -48,8 +48,11 @@ from igniter.tools import load_environments, add_acre_to_sys_path
|
|||
|
||||
from igniter import BootstrapRepos
|
||||
|
||||
add_acre_to_sys_path()
|
||||
import acre
|
||||
try:
|
||||
import acre
|
||||
except ImportError:
|
||||
add_acre_to_sys_path()
|
||||
import acre
|
||||
|
||||
|
||||
def set_environments() -> None:
|
||||
|
|
@ -101,18 +104,9 @@ def set_modules_environments():
|
|||
|
||||
def boot():
|
||||
"""Bootstrap Pype."""
|
||||
art = r"""
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___ ___ ___
|
||||
\ \ \___/ ---- \ \\ \\ \
|
||||
\ \____\ / \____\ \__\\__\\__\
|
||||
\/____/ \/____/ . PYPE Club .
|
||||
|
||||
"""
|
||||
|
||||
print(art)
|
||||
from pype.lib.terminal_splash import play_animation
|
||||
play_animation()
|
||||
|
||||
# find pype versions
|
||||
bootstrap = BootstrapRepos()
|
||||
|
|
|
|||
413
pype/lib/splash.txt
Normal file
413
pype/lib/splash.txt
Normal file
|
|
@ -0,0 +1,413 @@
|
|||
|
||||
|
||||
|
||||
*
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.*
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
*
|
||||
.*
|
||||
*
|
||||
|
||||
|
||||
|
||||
.
|
||||
*
|
||||
.*
|
||||
*
|
||||
.
|
||||
|
||||
.
|
||||
*
|
||||
.*
|
||||
.*
|
||||
.*
|
||||
*
|
||||
.
|
||||
.
|
||||
*
|
||||
.*
|
||||
.*
|
||||
.*
|
||||
*
|
||||
.
|
||||
_.
|
||||
/**
|
||||
\ *
|
||||
\*
|
||||
*
|
||||
*
|
||||
.
|
||||
__.
|
||||
---*
|
||||
\ \*
|
||||
\ *
|
||||
\*
|
||||
*
|
||||
.
|
||||
\___.
|
||||
/* *
|
||||
\ \ *
|
||||
\ \*
|
||||
\ *
|
||||
\*
|
||||
.
|
||||
|____.
|
||||
/* *
|
||||
\|\ *
|
||||
\ \ *
|
||||
\ \ *
|
||||
\ \*
|
||||
\/.
|
||||
_/_____.
|
||||
/* *
|
||||
/ \ *
|
||||
\ \ *
|
||||
\ \ *
|
||||
\ \__*
|
||||
\/__.
|
||||
__________.
|
||||
--*-- ___*
|
||||
\ \ \/_*
|
||||
\ \ __*
|
||||
\ \ \_*
|
||||
\ \____\*
|
||||
\/____/.
|
||||
\____________ .
|
||||
/* ___ \*
|
||||
\ \ \/_\ *
|
||||
\ \ _____*
|
||||
\ \ \___/*
|
||||
\ \____\ *
|
||||
\/____/ .
|
||||
|___________ .
|
||||
/* ___ \ *
|
||||
\|\ \/_\ \ *
|
||||
\ \ _____/ *
|
||||
\ \ \___/ *
|
||||
\ \____\ / *
|
||||
\/____/ \.
|
||||
_/__________ .
|
||||
/* ___ \ *
|
||||
/ \ \/_\ \ *
|
||||
\ \ _____/ *
|
||||
\ \ \___/ ---*
|
||||
\ \____\ / \__*
|
||||
\/____/ \/__.
|
||||
____________ .
|
||||
--*-- ___ \ *
|
||||
\ \ \/_\ \ *
|
||||
\ \ _____/ *
|
||||
\ \ \___/ ---- *
|
||||
\ \____\ / \____\*
|
||||
\/____/ \/____/.
|
||||
____________
|
||||
/\ ___ \ .
|
||||
\ \ \/_\ \ *
|
||||
\ \ _____/ *
|
||||
\ \ \___/ ---- *
|
||||
\ \____\ / \____\ .
|
||||
\/____/ \/____/
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \ .
|
||||
\ \ _____/ *
|
||||
\ \ \___/ ---- *
|
||||
\ \____\ / \____\ .
|
||||
\/____/ \/____/
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ .
|
||||
\ \ \___/ ---- *
|
||||
\ \____\ / \____\ .
|
||||
\/____/ \/____/
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/
|
||||
\ \ \___/ ---- *
|
||||
\ \____\ / \____\
|
||||
\/____/ \/____/
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/
|
||||
\ \ \___/ ---- .
|
||||
\ \____\ / \____\
|
||||
\/____/ \/____/
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ _
|
||||
\ \ \___/ ----
|
||||
\ \____\ / \____\
|
||||
\/____/ \/____/
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___
|
||||
\ \ \___/ ----
|
||||
\ \____\ / \____\
|
||||
\/____/ \/____/
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___
|
||||
\ \ \___/ ---- \
|
||||
\ \____\ / \____\
|
||||
\/____/ \/____/
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___
|
||||
\ \ \___/ ---- \
|
||||
\ \____\ / \____\ \
|
||||
\/____/ \/____/
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___
|
||||
\ \ \___/ ---- \
|
||||
\ \____\ / \____\ __\
|
||||
\/____/ \/____/
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___
|
||||
\ \ \___/ ---- \
|
||||
\ \____\ / \____\ \__\
|
||||
\/____/ \/____/
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___
|
||||
\ \ \___/ ---- \ \
|
||||
\ \____\ / \____\ \__\
|
||||
\/____/ \/____/
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___
|
||||
\ \ \___/ ---- \ \
|
||||
\ \____\ / \____\ \__\
|
||||
\/____/ \/____/
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___.
|
||||
\ \ \___/ ---- \ \\
|
||||
\ \____\ / \____\ \__\,
|
||||
\/____/ \/____/
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___ .
|
||||
\ \ \___/ ---- \ \\
|
||||
\ \____\ / \____\ \__\\,
|
||||
\/____/ \/____/
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___ _.
|
||||
\ \ \___/ ---- \ \\\
|
||||
\ \____\ / \____\ \__\\\
|
||||
\/____/ \/____/
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___ __.
|
||||
\ \ \___/ ---- \ \\ \
|
||||
\ \____\ / \____\ \__\\_/.
|
||||
\/____/ \/____/
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___ ___.
|
||||
\ \ \___/ ---- \ \\ \\
|
||||
\ \____\ / \____\ \__\\__\.
|
||||
\/____/ \/____/
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___ ___ .
|
||||
\ \ \___/ ---- \ \\ \\
|
||||
\ \____\ / \____\ \__\\__\\.
|
||||
\/____/ \/____/
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___ ___ _.
|
||||
\ \ \___/ ---- \ \\ \\\
|
||||
\ \____\ / \____\ \__\\__\\.
|
||||
\/____/ \/____/
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___ ___ __.
|
||||
\ \ \___/ ---- \ \\ \\ \
|
||||
\ \____\ / \____\ \__\\__\\_.
|
||||
\/____/ \/____/
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___ ___ __.
|
||||
\ \ \___/ ---- \ \\ \\ \
|
||||
\ \____\ / \____\ \__\\__\\__.
|
||||
\/____/ \/____/
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___ ___ ___
|
||||
\ \ \___/ ---- \ \\ \\ \
|
||||
\ \____\ / \____\ \__\\__\\__\
|
||||
\/____/ \/____/ .
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___ ___ ___
|
||||
\ \ \___/ ---- \ \\ \\ \
|
||||
\ \____\ / \____\ \__\\__\\__\
|
||||
\/____/ \/____/ *
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___ ___ ___
|
||||
\ \ \___/ ---- \ \\ \\ \
|
||||
\ \____\ / \____\ \__\\__\\__\
|
||||
\/____/ \/____/ O*
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___ ___ ___
|
||||
\ \ \___/ ---- \ \\ \\ \
|
||||
\ \____\ / \____\ \__\\__\\__\
|
||||
\/____/ \/____/ oO*
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___ ___ ___
|
||||
\ \ \___/ ---- \ \\ \\ \
|
||||
\ \____\ / \____\ \__\\__\\__\
|
||||
\/____/ \/____/ .oO*
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___ ___ ___
|
||||
\ \ \___/ ---- \ \\ \\ \
|
||||
\ \____\ / \____\ \__\\__\\__\
|
||||
\/____/ \/____/ ..oO*
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___ ___ ___
|
||||
\ \ \___/ ---- \ \\ \\ \
|
||||
\ \____\ / \____\ \__\\__\\__\
|
||||
\/____/ \/____/ . .oO*
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___ ___ ___
|
||||
\ \ \___/ ---- \ \\ \\ \
|
||||
\ \____\ / \____\ \__\\__\\__\
|
||||
\/____/ \/____/ . p.oO*
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___ ___ ___
|
||||
\ \ \___/ ---- \ \\ \\ \
|
||||
\ \____\ / \____\ \__\\__\\__\
|
||||
\/____/ \/____/ . Py.oO*
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___ ___ ___
|
||||
\ \ \___/ ---- \ \\ \\ \
|
||||
\ \____\ / \____\ \__\\__\\__\
|
||||
\/____/ \/____/ . PYp.oO*
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___ ___ ___
|
||||
\ \ \___/ ---- \ \\ \\ \
|
||||
\ \____\ / \____\ \__\\__\\__\
|
||||
\/____/ \/____/ . PYPe.oO*
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___ ___ ___
|
||||
\ \ \___/ ---- \ \\ \\ \
|
||||
\ \____\ / \____\ \__\\__\\__\
|
||||
\/____/ \/____/ . PYPE .oO*
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___ ___ ___
|
||||
\ \ \___/ ---- \ \\ \\ \
|
||||
\ \____\ / \____\ \__\\__\\__\
|
||||
\/____/ \/____/ . PYPE c.oO*
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___ ___ ___
|
||||
\ \ \___/ ---- \ \\ \\ \
|
||||
\ \____\ / \____\ \__\\__\\__\
|
||||
\/____/ \/____/ . PYPE C1.oO*
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___ ___ ___
|
||||
\ \ \___/ ---- \ \\ \\ \
|
||||
\ \____\ / \____\ \__\\__\\__\
|
||||
\/____/ \/____/ . PYPE ClU.oO*
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___ ___ ___
|
||||
\ \ \___/ ---- \ \\ \\ \
|
||||
\ \____\ / \____\ \__\\__\\__\
|
||||
\/____/ \/____/ . PYPE CluB.oO*
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___ ___ ___
|
||||
\ \ \___/ ---- \ \\ \\ \
|
||||
\ \____\ / \____\ \__\\__\\__\
|
||||
\/____/ \/____/ . PYPE Club .oO*
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___ ___ ___
|
||||
\ \ \___/ ---- \ \\ \\ \
|
||||
\ \____\ / \____\ \__\\__\\__\
|
||||
\/____/ \/____/ . PYPE Club . ..
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___ ___ ___
|
||||
\ \ \___/ ---- \ \\ \\ \
|
||||
\ \____\ / \____\ \__\\__\\__\
|
||||
\/____/ \/____/ . PYPE Club . ..
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___ ___ ___
|
||||
\ \ \___/ ---- \ \\ \\ \
|
||||
\ \____\ / \____\ \__\\__\\__\
|
||||
\/____/ \/____/ . PYPE Club . .
|
||||
____________
|
||||
/\ ___ \
|
||||
\ \ \/_\ \
|
||||
\ \ _____/ ___ ___ ___
|
||||
\ \ \___/ ---- \ \\ \\ \
|
||||
\ \____\ / \____\ \__\\__\\__\
|
||||
\/____/ \/____/ . PYPE Club .
|
||||
|
|
@ -13,11 +13,10 @@
|
|||
import re
|
||||
import os
|
||||
import sys
|
||||
noColorama = False
|
||||
try:
|
||||
from colorama import Fore, Style, init, ansitowin32
|
||||
except ImportError:
|
||||
noColorama = True
|
||||
import blessed
|
||||
|
||||
|
||||
term = blessed.Terminal()
|
||||
|
||||
|
||||
class Terminal:
|
||||
|
|
@ -30,40 +29,37 @@ class Terminal:
|
|||
"""
|
||||
|
||||
# shortcuts for colorama codes
|
||||
if noColorama:
|
||||
_SB = _RST = _LR = _LG = _LB = _LM = _R = _G = _B = _C = _Y = _W = ""
|
||||
_LY = ""
|
||||
else:
|
||||
_SB = Style.BRIGHT
|
||||
_RST = Style.RESET_ALL
|
||||
_LR = Fore.LIGHTRED_EX
|
||||
_LG = Fore.LIGHTGREEN_EX
|
||||
_LB = Fore.LIGHTBLUE_EX
|
||||
_LM = Fore.LIGHTMAGENTA_EX
|
||||
_LY = Fore.LIGHTYELLOW_EX
|
||||
_R = Fore.RED
|
||||
_G = Fore.GREEN
|
||||
_B = Fore.BLUE
|
||||
_C = Fore.CYAN
|
||||
_Y = Fore.YELLOW
|
||||
_W = Fore.WHITE
|
||||
|
||||
_SB = term.bold
|
||||
_RST = ""
|
||||
_LR = term.tomato2
|
||||
_LG = term.aquamarine3
|
||||
_LB = term.turquoise2
|
||||
_LM = term.slateblue2
|
||||
_LY = term.gold
|
||||
_R = term.red
|
||||
_G = term.green
|
||||
_B = term.blue
|
||||
_C = term.cyan
|
||||
_Y = term.yellow
|
||||
_W = term.white
|
||||
|
||||
# dictionary replacing string sequences with colorized one
|
||||
_sdict = {
|
||||
|
||||
r">>> ": _SB + _G + r">>> " + _RST,
|
||||
r">>> ": _SB + _LG + r">>> " + _RST,
|
||||
r"!!!(?!\sCRI|\sERR)": _SB + _R + r"!!! " + _RST,
|
||||
r"\-\-\- ": _SB + _C + r"--- " + _RST,
|
||||
r"\*\*\*(?!\sWRN)": _SB + _LM + r"***" + _RST,
|
||||
r"\*\*\*(?!\sWRN)": _SB + _LY + r"***" + _RST,
|
||||
r"\*\*\* WRN": _SB + _LY + r"*** WRN" + _RST,
|
||||
r" \- ": _SB + _Y + r" - " + _RST,
|
||||
r" \- ": _SB + _LY + r" - " + _RST,
|
||||
r"\[ ": _SB + _LG + r"[ " + _RST,
|
||||
r"\]": _SB + _LG + r"]" + _RST,
|
||||
r"{": _LG + r"{",
|
||||
r"}": r"}" + _RST,
|
||||
r"\(": _LY + r"(",
|
||||
r"\)": r")" + _RST,
|
||||
r"^\.\.\. ": _SB + _LM + r"... " + _RST,
|
||||
r"^\.\.\. ": _SB + _LR + r"... " + _RST,
|
||||
r"!!! ERR: ":
|
||||
_SB + _LR + r"!!! ERR: " + _RST,
|
||||
r"!!! CRI: ":
|
||||
|
|
@ -73,8 +69,7 @@ class Terminal:
|
|||
}
|
||||
|
||||
def __init__(self):
|
||||
if not noColorama:
|
||||
init()
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def _multiple_replace(text, adict):
|
||||
|
|
@ -108,11 +103,6 @@ class Terminal:
|
|||
str: Colorized message.
|
||||
|
||||
"""
|
||||
if noColorama:
|
||||
print(message)
|
||||
return message
|
||||
if not isinstance(sys.stdout, ansitowin32.StreamWrapper):
|
||||
init()
|
||||
colorized = Terminal.log(message)
|
||||
print(colorized)
|
||||
|
||||
|
|
|
|||
34
pype/lib/terminal_splash.py
Normal file
34
pype/lib/terminal_splash.py
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Pype terminal animation."""
|
||||
import blessed
|
||||
from pathlib import Path
|
||||
from time import sleep
|
||||
|
||||
|
||||
term = blessed.Terminal()
|
||||
|
||||
|
||||
def play_animation():
|
||||
"""Play ASCII art Pype animation."""
|
||||
print(term.home + term.clear)
|
||||
frame_size = 7
|
||||
splash_file = Path(__file__).parent / "splash.txt"
|
||||
with splash_file.open("r") as sf:
|
||||
animation = sf.readlines()
|
||||
|
||||
animation_length = int(len(animation) / frame_size)
|
||||
current_frame = 0
|
||||
for _ in range(animation_length):
|
||||
frame = ""
|
||||
y = 0
|
||||
for scanline in animation[current_frame:current_frame + frame_size]:
|
||||
frame += scanline
|
||||
y += 1
|
||||
|
||||
with term.location(0, 0):
|
||||
# term.aquamarine3_bold(frame)
|
||||
print(f"{term.bold}{term.aquamarine3}{frame}{term.normal}")
|
||||
|
||||
sleep(0.02)
|
||||
current_frame += frame_size
|
||||
print(term.move_y(7))
|
||||
|
|
@ -1,25 +1,40 @@
|
|||
from pype.modules.ftrack import BaseEvent
|
||||
from pype.api import get_project_settings
|
||||
|
||||
|
||||
class VersionToTaskStatus(BaseEvent):
|
||||
"""Propagates status from version to task when changed."""
|
||||
def launch(self, session, event):
|
||||
'''Propagates status from version to task when changed'''
|
||||
# Filter event entities
|
||||
# - output is dictionary where key is project id and event info in
|
||||
# value
|
||||
filtered_entities_info = self.filter_entity_info(event)
|
||||
if not filtered_entities_info:
|
||||
return
|
||||
|
||||
# start of event procedure ----------------------------------
|
||||
for entity in event['data'].get('entities', []):
|
||||
for project_id, entities_info in filtered_entities_info.items():
|
||||
self.process_by_project(session, event, project_id, entities_info)
|
||||
|
||||
# TODO remove `join_query_keys` as it should be in `BaseHandler`
|
||||
@staticmethod
|
||||
def join_query_keys(keys):
|
||||
"""Helper to join keys to query."""
|
||||
return ",".join(["\"{}\"".format(key) for key in keys])
|
||||
|
||||
def filter_entity_info(self, event):
|
||||
filtered_entity_info = {}
|
||||
for entity_info in event["data"].get("entities", []):
|
||||
# Filter AssetVersions
|
||||
if entity["entityType"] != "assetversion":
|
||||
if entity_info["entityType"] != "assetversion":
|
||||
continue
|
||||
|
||||
# Skip if statusid not in keys (in changes)
|
||||
keys = entity.get("keys")
|
||||
keys = entity_info.get("keys")
|
||||
if not keys or "statusid" not in keys:
|
||||
continue
|
||||
|
||||
# Get new version task name
|
||||
version_status_id = (
|
||||
entity
|
||||
entity_info
|
||||
.get("changes", {})
|
||||
.get("statusid", {})
|
||||
.get("new", {})
|
||||
|
|
@ -29,74 +44,162 @@ class VersionToTaskStatus(BaseEvent):
|
|||
if not version_status_id:
|
||||
continue
|
||||
|
||||
try:
|
||||
version_status = session.get("Status", version_status_id)
|
||||
except Exception:
|
||||
self.log.warning(
|
||||
"Troubles with query status id [ {} ]".format(
|
||||
version_status_id
|
||||
),
|
||||
exc_info=True
|
||||
# Get project id from entity info
|
||||
project_id = entity_info["parents"][-1]["entityId"]
|
||||
if project_id not in filtered_entity_info:
|
||||
filtered_entity_info[project_id] = []
|
||||
filtered_entity_info[project_id].append(entity_info)
|
||||
return filtered_entity_info
|
||||
|
||||
def process_by_project(self, session, event, project_id, entities_info):
|
||||
# Check for project data if event is enabled for event handler
|
||||
status_mapping = None
|
||||
project_entity = self.get_project_entity_from_event(
|
||||
session, event, project_id
|
||||
)
|
||||
project_settings = self.get_settings_for_project(
|
||||
session, event, project_entity=project_entity
|
||||
)
|
||||
|
||||
project_name = project_entity["full_name"]
|
||||
# Load status mapping from presets
|
||||
event_settings = (
|
||||
project_settings["ftrack"]["events"]["status_version_to_task"]
|
||||
)
|
||||
# Skip if event is not enabled or status mapping is not set
|
||||
if not event_settings["enabled"]:
|
||||
self.log.debug("Project \"{}\" has disabled {}".format(
|
||||
project_name, self.__class__.__name__
|
||||
))
|
||||
return
|
||||
|
||||
_status_mapping = event_settings["mapping"]
|
||||
if not _status_mapping:
|
||||
self.log.debug(
|
||||
"Project \"{}\" does not have set mapping for {}".format(
|
||||
project_name, self.__class__.__name__
|
||||
)
|
||||
)
|
||||
return
|
||||
|
||||
if not version_status:
|
||||
status_mapping = {
|
||||
key.lower(): value
|
||||
for key, value in _status_mapping.items()
|
||||
}
|
||||
|
||||
asset_types_to_skip = [
|
||||
short_name.lower()
|
||||
for short_name in event_settings["asset_types_to_skip"]
|
||||
]
|
||||
|
||||
# Collect entity ids
|
||||
asset_version_ids = set()
|
||||
for entity_info in entities_info:
|
||||
asset_version_ids.add(entity_info["entityId"])
|
||||
|
||||
# Query tasks for AssetVersions
|
||||
_asset_version_entities = session.query(
|
||||
"AssetVersion where task_id != none and id in ({})".format(
|
||||
self.join_query_keys(asset_version_ids)
|
||||
)
|
||||
).all()
|
||||
if not _asset_version_entities:
|
||||
return
|
||||
|
||||
# Filter asset versions by asset type and store their task_ids
|
||||
task_ids = set()
|
||||
asset_version_entities = []
|
||||
for asset_version in _asset_version_entities:
|
||||
if asset_types_to_skip:
|
||||
short_name = asset_version["asset"]["type"]["short"].lower()
|
||||
if short_name in asset_types_to_skip:
|
||||
continue
|
||||
asset_version_entities.append(asset_version)
|
||||
task_ids.add(asset_version["task_id"])
|
||||
|
||||
# Skipt if `task_ids` are empty
|
||||
if not task_ids:
|
||||
return
|
||||
|
||||
task_entities = session.query(
|
||||
"select link from Task where id in ({})".format(
|
||||
self.join_query_keys(task_ids)
|
||||
)
|
||||
).all()
|
||||
task_entities_by_id = {
|
||||
task_entiy["id"]: task_entiy
|
||||
for task_entiy in task_entities
|
||||
}
|
||||
|
||||
# Prepare asset version by their id
|
||||
asset_versions_by_id = {
|
||||
asset_version["id"]: asset_version
|
||||
for asset_version in asset_version_entities
|
||||
}
|
||||
|
||||
# Query status entities
|
||||
status_ids = set()
|
||||
for entity_info in entities_info:
|
||||
# Skip statuses of asset versions without task
|
||||
if entity_info["entityId"] not in asset_versions_by_id:
|
||||
continue
|
||||
status_ids.add(entity_info["changes"]["statusid"]["new"])
|
||||
|
||||
version_status_orig = version_status["name"]
|
||||
version_status_entities = session.query(
|
||||
"select id, name from Status where id in ({})".format(
|
||||
self.join_query_keys(status_ids)
|
||||
)
|
||||
).all()
|
||||
|
||||
# Get entities necessary for processing
|
||||
version = session.get("AssetVersion", entity["entityId"])
|
||||
task = version.get("task")
|
||||
if not task:
|
||||
continue
|
||||
|
||||
project_entity = self.get_project_from_entity(task)
|
||||
project_name = project_entity["full_name"]
|
||||
project_settings = get_project_settings(project_name)
|
||||
|
||||
# Load status mapping from presets
|
||||
status_mapping = (
|
||||
project_settings["ftrack"]["events"]["status_version_to_task"])
|
||||
# Skip if mapping is empty
|
||||
if not status_mapping:
|
||||
# Qeury statuses
|
||||
statusese_by_obj_id = self.statuses_for_tasks(
|
||||
session, task_entities, project_entity
|
||||
)
|
||||
# Prepare status names by their ids
|
||||
status_name_by_id = {
|
||||
status_entity["id"]: status_entity["name"]
|
||||
for status_entity in version_status_entities
|
||||
}
|
||||
for entity_info in entities_info:
|
||||
entity_id = entity_info["entityId"]
|
||||
status_id = entity_info["changes"]["statusid"]["new"]
|
||||
status_name = status_name_by_id.get(status_id)
|
||||
if not status_name:
|
||||
continue
|
||||
status_name_low = status_name.lower()
|
||||
|
||||
# Lower version status name and check if has mapping
|
||||
version_status = version_status_orig.lower()
|
||||
new_status_names = []
|
||||
mapped = status_mapping.get(version_status)
|
||||
mapped = status_mapping.get(status_name_low)
|
||||
if mapped:
|
||||
new_status_names.extend(list(mapped))
|
||||
|
||||
new_status_names.append(version_status)
|
||||
new_status_names.append(status_name_low)
|
||||
|
||||
self.log.debug(
|
||||
"Processing AssetVersion status change: [ {} ]".format(
|
||||
version_status_orig
|
||||
status_name
|
||||
)
|
||||
)
|
||||
|
||||
asset_version = asset_versions_by_id[entity_id]
|
||||
task_entity = task_entities_by_id[asset_version["task_id"]]
|
||||
type_id = task_entity["type_id"]
|
||||
|
||||
# Lower all names from presets
|
||||
new_status_names = [name.lower() for name in new_status_names]
|
||||
|
||||
if version["asset"]["type"]["short"].lower() == "scene":
|
||||
continue
|
||||
|
||||
project_schema = project_entity["project_schema"]
|
||||
# Get all available statuses for Task
|
||||
statuses = project_schema.get_statuses("Task", task["type_id"])
|
||||
# map lowered status name with it's object
|
||||
stat_names_low = {
|
||||
status["name"].lower(): status for status in statuses
|
||||
}
|
||||
task_statuses_by_low_name = statusese_by_obj_id[type_id]
|
||||
|
||||
new_status = None
|
||||
for status_name in new_status_names:
|
||||
if status_name not in stat_names_low:
|
||||
if status_name not in task_statuses_by_low_name:
|
||||
self.log.debug((
|
||||
"Task does not have status name \"{}\" available."
|
||||
).format(status_name))
|
||||
continue
|
||||
|
||||
# store object of found status
|
||||
new_status = stat_names_low[status_name]
|
||||
new_status = task_statuses_by_low_name[status_name]
|
||||
self.log.debug("Status to set: [ {} ]".format(
|
||||
new_status["name"]
|
||||
))
|
||||
|
|
@ -110,16 +213,15 @@ class VersionToTaskStatus(BaseEvent):
|
|||
)
|
||||
)
|
||||
continue
|
||||
|
||||
# Get full path to task for logging
|
||||
ent_path = "/".join([ent["name"] for ent in task["link"]])
|
||||
ent_path = "/".join([ent["name"] for ent in task_entity["link"]])
|
||||
|
||||
# Setting task status
|
||||
try:
|
||||
task["status"] = new_status
|
||||
task_entity["status"] = new_status
|
||||
session.commit()
|
||||
self.log.debug("[ {} ] Status updated to [ {} ]".format(
|
||||
ent_path, new_status['name']
|
||||
ent_path, new_status["name"]
|
||||
))
|
||||
except Exception:
|
||||
session.rollback()
|
||||
|
|
@ -128,6 +230,22 @@ class VersionToTaskStatus(BaseEvent):
|
|||
exc_info=True
|
||||
)
|
||||
|
||||
def statuses_for_tasks(self, session, task_entities, project_entity):
|
||||
task_type_ids = set()
|
||||
for task_entity in task_entities:
|
||||
task_type_ids.add(task_entity["type_id"])
|
||||
|
||||
project_schema = project_entity["project_schema"]
|
||||
output = {}
|
||||
for task_type_id in task_type_ids:
|
||||
statuses = project_schema.get_statuses("Task", task_type_id)
|
||||
output[task_type_id] = {
|
||||
status["name"].lower(): status
|
||||
for status in statuses
|
||||
}
|
||||
|
||||
return output
|
||||
|
||||
|
||||
def register(session, plugins_presets):
|
||||
'''Register plugin. Called when used as an plugin.'''
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ from pype.modules.ftrack.ftrack_server.lib import (
|
|||
get_ftrack_event_mongo_info
|
||||
)
|
||||
|
||||
import socket_thread
|
||||
from pype.modules.ftrack.ftrack_server import socket_thread
|
||||
|
||||
|
||||
class MongoPermissionsError(Exception):
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ import inspect
|
|||
|
||||
import ftrack_api
|
||||
|
||||
from pype.api import Logger
|
||||
from pype.lib import PypeLogger
|
||||
|
||||
|
||||
log = Logger().get_logger(__name__)
|
||||
log = PypeLogger().get_logger(__name__)
|
||||
|
||||
"""
|
||||
# Required - Needed for connection to Ftrack
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import functools
|
||||
import time
|
||||
from pype.api import Logger
|
||||
from pype.settings import get_project_settings
|
||||
|
||||
import ftrack_api
|
||||
from pype.modules.ftrack import ftrack_server
|
||||
|
||||
|
|
@ -581,3 +583,67 @@ class BaseHandler(object):
|
|||
return self.session.query(
|
||||
"Project where id is {}".format(project_data["id"])
|
||||
).one()
|
||||
|
||||
def get_project_entity_from_event(self, session, event, project_id):
|
||||
"""Load or query and fill project entity from/to event data.
|
||||
|
||||
Project data are stored by ftrack id because in most cases it is
|
||||
easier to access project id than project name.
|
||||
|
||||
Args:
|
||||
session (ftrack_api.Session): Current session.
|
||||
event (ftrack_api.Event): Processed event by session.
|
||||
project_id (str): Ftrack project id.
|
||||
"""
|
||||
if not project_id:
|
||||
raise ValueError(
|
||||
"Entered `project_id` is not valid. {} ({})".format(
|
||||
str(project_id), str(type(project_id))
|
||||
)
|
||||
)
|
||||
# Try to get project entity from event
|
||||
project_entities = event["data"].get("project_entities")
|
||||
if not project_entities:
|
||||
project_entities = {}
|
||||
event["data"]["project_entities"] = project_entities
|
||||
|
||||
project_entity = project_entities.get(project_id)
|
||||
if not project_entity:
|
||||
# Get project entity from task and store to event
|
||||
project_entity = session.get("Project", project_id)
|
||||
event["data"]["project_entities"][project_id] = project_entity
|
||||
return project_entity
|
||||
|
||||
def get_settings_for_project(
|
||||
self, session, event, project_id=None, project_entity=None
|
||||
):
|
||||
"""Load or fill pype's project settings from event data.
|
||||
|
||||
Project data are stored by ftrack id because in most cases it is
|
||||
easier to access project id than project name.
|
||||
|
||||
Args:
|
||||
session (ftrack_api.Session): Current session.
|
||||
event (ftrack_api.Event): Processed event by session.
|
||||
project_id (str): Ftrack project id. Must be entered if
|
||||
project_entity is not.
|
||||
project_entity (ftrack_api.Entity): Project entity. Must be entered
|
||||
if project_id is not.
|
||||
"""
|
||||
if not project_entity:
|
||||
project_entity = self.get_project_entity_from_event(
|
||||
session, event, project_id
|
||||
)
|
||||
|
||||
project_name = project_entity["full_name"]
|
||||
|
||||
project_settings_by_id = event["data"].get("project_settings")
|
||||
if not project_settings_by_id:
|
||||
project_settings_by_id = {}
|
||||
event["data"]["project_settings"] = project_settings_by_id
|
||||
|
||||
project_settings = project_settings_by_id.get(project_id)
|
||||
if not project_settings:
|
||||
project_settings = get_project_settings(project_name)
|
||||
event["data"]["project_settings"][project_id] = project_settings
|
||||
return project_settings
|
||||
|
|
|
|||
|
|
@ -60,7 +60,18 @@ class PypeCommands:
|
|||
return return_code
|
||||
|
||||
def launch_eventservercli(self, args):
|
||||
pass
|
||||
from pype.modules import ftrack
|
||||
from pype.lib import execute
|
||||
|
||||
fname = os.path.join(
|
||||
os.path.dirname(os.path.abspath(ftrack.__file__)),
|
||||
"ftrack_server",
|
||||
"event_server_cli.py"
|
||||
)
|
||||
|
||||
return execute([
|
||||
sys.executable, "-u", fname
|
||||
])
|
||||
|
||||
def publish(self, gui, paths):
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -71,11 +71,13 @@
|
|||
"status_version_to_task": {
|
||||
"enabled": true,
|
||||
"mapping": {
|
||||
"Complete": [
|
||||
"Approved",
|
||||
"Approved": [
|
||||
"Complete"
|
||||
]
|
||||
}
|
||||
},
|
||||
"asset_types_to_skip": [
|
||||
"scene"
|
||||
]
|
||||
},
|
||||
"first_version_status": {
|
||||
"enabled": true,
|
||||
|
|
|
|||
|
|
@ -179,4 +179,4 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -136,7 +136,8 @@
|
|||
"enabled": false
|
||||
},
|
||||
"ValidateAttributes": {
|
||||
"enabled": false
|
||||
"enabled": false,
|
||||
"attributes": {}
|
||||
},
|
||||
"ExtractCameraAlembic": {
|
||||
"enabled": true,
|
||||
|
|
|
|||
|
|
@ -87,4 +87,4 @@
|
|||
]
|
||||
},
|
||||
"filters": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -91,40 +91,82 @@
|
|||
]
|
||||
},
|
||||
{
|
||||
"type": "dict",
|
||||
"key": "thumbnail_updates",
|
||||
"label": "Update Hierarchy thumbnails",
|
||||
"checkbox_key": "enabled",
|
||||
"children": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"key": "enabled",
|
||||
"label": "Enabled"
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"label": "Push thumbnail from version, up through multiple hierarchy levels."
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"key": "levels",
|
||||
"label": "Levels"
|
||||
}
|
||||
]
|
||||
"type": "list",
|
||||
"object_type": "text"
|
||||
}
|
||||
}]
|
||||
},
|
||||
{
|
||||
"type": "dict",
|
||||
"key": "status_version_to_task",
|
||||
"label": "Sync status from Version to Task",
|
||||
"checkbox_key": "enabled",
|
||||
"children": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"key": "enabled",
|
||||
"label": "Enabled"
|
||||
},
|
||||
{
|
||||
"type": "dict",
|
||||
"key": "user_assignment",
|
||||
"label": "Run script on user assignments",
|
||||
"checkbox_key": "enabled",
|
||||
"children": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"key": "enabled",
|
||||
"label": "Enabled"
|
||||
}
|
||||
]
|
||||
"type": "label",
|
||||
"label": "<b>Change Task status based on a changed Version status.</b><br/>Version's new status on the <b>left</b> will trigger a change of a task status to the first available from the list on <b>right</b>.<br/> - if no status from the list is available it will use the same status as the version."
|
||||
},
|
||||
{
|
||||
"type": "dict-modifiable",
|
||||
"key": "mapping",
|
||||
"object_type":
|
||||
{
|
||||
"type": "list",
|
||||
"object_type": "text"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "separator"
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"label": "<b>Disable<b/> event if status was changed on specific Asset type."
|
||||
},
|
||||
{
|
||||
"type": "list",
|
||||
"label": "Asset types (short)",
|
||||
"key": "asset_types_to_skip",
|
||||
"object_type": "text"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "dict",
|
||||
"key": "first_version_status",
|
||||
"label": "Set status on first created version",
|
||||
"checkbox_key": "enabled",
|
||||
"children": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"key": "enabled",
|
||||
"label": "Enabled"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"key": "status",
|
||||
"label": "Status"
|
||||
}]
|
||||
},
|
||||
{
|
||||
"type": "dict",
|
||||
"key": "next_task_update",
|
||||
"label": "Update status on next task",
|
||||
"checkbox_key": "enabled",
|
||||
"children": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"key": "enabled",
|
||||
"label": "Enabled"
|
||||
},
|
||||
{
|
||||
"type": "dict-modifiable",
|
||||
"key": "mapping",
|
||||
"object_type":
|
||||
{
|
||||
"type": "dict",
|
||||
"key": "status_update",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
aiohttp
|
||||
appdirs
|
||||
arrow
|
||||
blessed
|
||||
certifi
|
||||
Click
|
||||
clique==1.5.0
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue