mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-25 21:32:15 +01:00
Merge branch 'pypeclub:develop' into enhancement/minimal-ftrack-browser-open-from-tray
This commit is contained in:
commit
b2b52cdcb5
12 changed files with 410 additions and 39 deletions
44
CHANGELOG.md
44
CHANGELOG.md
|
|
@ -1,23 +1,39 @@
|
|||
# Changelog
|
||||
|
||||
## [3.11.0-nightly.1](https://github.com/pypeclub/OpenPype/tree/HEAD)
|
||||
## [3.11.0-nightly.2](https://github.com/pypeclub/OpenPype/tree/HEAD)
|
||||
|
||||
[Full Changelog](https://github.com/pypeclub/OpenPype/compare/3.10.0...HEAD)
|
||||
|
||||
### 📖 Documentation
|
||||
|
||||
- Documentation: Add app key to template documentation [\#3299](https://github.com/pypeclub/OpenPype/pull/3299)
|
||||
- doc: adding royal render and multiverse to the web site [\#3285](https://github.com/pypeclub/OpenPype/pull/3285)
|
||||
|
||||
**🚀 Enhancements**
|
||||
|
||||
- updated poetry installation source [\#3316](https://github.com/pypeclub/OpenPype/pull/3316)
|
||||
- TVPaint: Extractor use mark in/out range to render [\#3309](https://github.com/pypeclub/OpenPype/pull/3309)
|
||||
- Ftrack: Delivery action can work on ReviewSessions [\#3307](https://github.com/pypeclub/OpenPype/pull/3307)
|
||||
- Maya: Look assigner UI improvements [\#3298](https://github.com/pypeclub/OpenPype/pull/3298)
|
||||
- Ftrack: Action to transfer values of hierarchical attributes [\#3284](https://github.com/pypeclub/OpenPype/pull/3284)
|
||||
- Maya: better handling of legacy review subsets names [\#3269](https://github.com/pypeclub/OpenPype/pull/3269)
|
||||
- General: Updated windows oiio tool [\#3268](https://github.com/pypeclub/OpenPype/pull/3268)
|
||||
- Unreal: add support for skeletalMesh and staticMesh to loaders [\#3267](https://github.com/pypeclub/OpenPype/pull/3267)
|
||||
- Maya: reference loaders could store placeholder in referenced url [\#3264](https://github.com/pypeclub/OpenPype/pull/3264)
|
||||
- TVPaint: Init file for TVPaint worker also handle guideline images [\#3250](https://github.com/pypeclub/OpenPype/pull/3250)
|
||||
- Nuke: Change default icon path in settings [\#3247](https://github.com/pypeclub/OpenPype/pull/3247)
|
||||
- Maya: publishing of animation and pointcache on a farm [\#3225](https://github.com/pypeclub/OpenPype/pull/3225)
|
||||
- Maya: Look assigner UI improvements [\#3208](https://github.com/pypeclub/OpenPype/pull/3208)
|
||||
- Nuke: add pointcache and animation to loader [\#3186](https://github.com/pypeclub/OpenPype/pull/3186)
|
||||
|
||||
**🐛 Bug fixes**
|
||||
|
||||
- Houdini: Fix Houdini VDB manage update wrong file attribute name [\#3322](https://github.com/pypeclub/OpenPype/pull/3322)
|
||||
- General: Vendorized modules for Python 2 and update poetry lock [\#3305](https://github.com/pypeclub/OpenPype/pull/3305)
|
||||
- Fix - added local targets to install host [\#3303](https://github.com/pypeclub/OpenPype/pull/3303)
|
||||
- Settings: Add missing default settings for nuke gizmo [\#3301](https://github.com/pypeclub/OpenPype/pull/3301)
|
||||
- Maya: Fix swaped width and height in reviews [\#3300](https://github.com/pypeclub/OpenPype/pull/3300)
|
||||
- Maya: point cache publish handles Maya instances [\#3297](https://github.com/pypeclub/OpenPype/pull/3297)
|
||||
- Global: extract review slate issues [\#3286](https://github.com/pypeclub/OpenPype/pull/3286)
|
||||
- Webpublisher: return only active projects in ProjectsEndpoint [\#3281](https://github.com/pypeclub/OpenPype/pull/3281)
|
||||
- Hiero: add support for task tags 3.10.x [\#3279](https://github.com/pypeclub/OpenPype/pull/3279)
|
||||
|
|
@ -30,24 +46,15 @@
|
|||
- Unreal: Fixed Render creation in UE5 [\#3239](https://github.com/pypeclub/OpenPype/pull/3239)
|
||||
- Unreal: Fixed Camera loading in UE5 [\#3238](https://github.com/pypeclub/OpenPype/pull/3238)
|
||||
- Flame: debugging [\#3224](https://github.com/pypeclub/OpenPype/pull/3224)
|
||||
- add silent audio to slate [\#3162](https://github.com/pypeclub/OpenPype/pull/3162)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- Maya: better handling of legacy review subsets names [\#3269](https://github.com/pypeclub/OpenPype/pull/3269)
|
||||
- Deadline: publishing of animation and pointcache on a farm [\#3225](https://github.com/pypeclub/OpenPype/pull/3225)
|
||||
- Nuke: add pointcache and animation to loader [\#3186](https://github.com/pypeclub/OpenPype/pull/3186)
|
||||
- Add a gizmo menu to nuke [\#3172](https://github.com/pypeclub/OpenPype/pull/3172)
|
||||
- Maya: add pointcache family to gpu cache loader [\#3318](https://github.com/pypeclub/OpenPype/pull/3318)
|
||||
|
||||
## [3.10.0](https://github.com/pypeclub/OpenPype/tree/3.10.0) (2022-05-26)
|
||||
|
||||
[Full Changelog](https://github.com/pypeclub/OpenPype/compare/CI/3.10.0-nightly.6...3.10.0)
|
||||
|
||||
**🆕 New features**
|
||||
|
||||
- General: OpenPype modules publish plugins are registered in host [\#3180](https://github.com/pypeclub/OpenPype/pull/3180)
|
||||
- General: Creator plugins from addons can be registered [\#3179](https://github.com/pypeclub/OpenPype/pull/3179)
|
||||
|
||||
**🚀 Enhancements**
|
||||
|
||||
- Maya: FBX camera export [\#3253](https://github.com/pypeclub/OpenPype/pull/3253)
|
||||
|
|
@ -55,10 +62,6 @@
|
|||
- Project Manager: Allow to paste Tasks into multiple assets at the same time [\#3226](https://github.com/pypeclub/OpenPype/pull/3226)
|
||||
- Project manager: Sped up project load [\#3216](https://github.com/pypeclub/OpenPype/pull/3216)
|
||||
- Loader UI: Speed issues of loader with sync server [\#3199](https://github.com/pypeclub/OpenPype/pull/3199)
|
||||
- Looks: add basic support for Renderman [\#3190](https://github.com/pypeclub/OpenPype/pull/3190)
|
||||
- Maya: added clean\_import option to Import loader [\#3181](https://github.com/pypeclub/OpenPype/pull/3181)
|
||||
- Add the scripts menu definition to nuke [\#3168](https://github.com/pypeclub/OpenPype/pull/3168)
|
||||
- Maya: add maya 2023 to default applications [\#3167](https://github.com/pypeclub/OpenPype/pull/3167)
|
||||
|
||||
**🐛 Bug fixes**
|
||||
|
||||
|
|
@ -76,12 +79,6 @@
|
|||
- Photoshop: skip collector when automatic testing [\#3202](https://github.com/pypeclub/OpenPype/pull/3202)
|
||||
- Nuke: render/workfile version sync doesn't work on farm [\#3185](https://github.com/pypeclub/OpenPype/pull/3185)
|
||||
- Ftrack: Review image only if there are no mp4 reviews [\#3183](https://github.com/pypeclub/OpenPype/pull/3183)
|
||||
- Ftrack: Locations deepcopy issue [\#3177](https://github.com/pypeclub/OpenPype/pull/3177)
|
||||
- General: Avoid creating multiple thumbnails [\#3176](https://github.com/pypeclub/OpenPype/pull/3176)
|
||||
- General/Hiero: better clip duration calculation [\#3169](https://github.com/pypeclub/OpenPype/pull/3169)
|
||||
- General: Oiio conversion for ffmpeg checks for invalid characters [\#3166](https://github.com/pypeclub/OpenPype/pull/3166)
|
||||
- Fix for attaching render to subset [\#3164](https://github.com/pypeclub/OpenPype/pull/3164)
|
||||
- Harmony: fixed missing task name in render instance [\#3163](https://github.com/pypeclub/OpenPype/pull/3163)
|
||||
|
||||
**🔀 Refactored code**
|
||||
|
||||
|
|
@ -92,7 +89,6 @@
|
|||
- Harmony: message length in 21.1 [\#3257](https://github.com/pypeclub/OpenPype/pull/3257)
|
||||
- Harmony: 21.1 fix [\#3249](https://github.com/pypeclub/OpenPype/pull/3249)
|
||||
- Maya: added jpg to filter for Image Plane Loader [\#3223](https://github.com/pypeclub/OpenPype/pull/3223)
|
||||
- Webpublisher: replace space by underscore in subset names [\#3160](https://github.com/pypeclub/OpenPype/pull/3160)
|
||||
|
||||
## [3.9.8](https://github.com/pypeclub/OpenPype/tree/3.9.8) (2022-05-19)
|
||||
|
||||
|
|
@ -103,15 +99,13 @@
|
|||
- nuke: generate publishing nodes inside render group node [\#3206](https://github.com/pypeclub/OpenPype/pull/3206)
|
||||
- Loader UI: Speed issues of loader with sync server [\#3200](https://github.com/pypeclub/OpenPype/pull/3200)
|
||||
- Backport of fix for attaching renders to subsets [\#3195](https://github.com/pypeclub/OpenPype/pull/3195)
|
||||
- Looks: add basic support for Renderman [\#3190](https://github.com/pypeclub/OpenPype/pull/3190)
|
||||
|
||||
**🐛 Bug fixes**
|
||||
|
||||
- Standalone Publisher: Always create new representation for thumbnail [\#3204](https://github.com/pypeclub/OpenPype/pull/3204)
|
||||
- Nuke: render/workfile version sync doesn't work on farm [\#3184](https://github.com/pypeclub/OpenPype/pull/3184)
|
||||
- Ftrack: Review image only if there are no mp4 reviews [\#3182](https://github.com/pypeclub/OpenPype/pull/3182)
|
||||
- Ftrack: Locations deepcopy issue [\#3175](https://github.com/pypeclub/OpenPype/pull/3175)
|
||||
- General: Avoid creating multiple thumbnails [\#3174](https://github.com/pypeclub/OpenPype/pull/3174)
|
||||
- General: TemplateResult can be copied [\#3170](https://github.com/pypeclub/OpenPype/pull/3170)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ def create_time_effects(otio_clip, track_item):
|
|||
otio_effect = otio.schema.TimeEffect()
|
||||
otio_effect.name = name
|
||||
otio_effect.effect_name = effect_name
|
||||
otio_effect.metadata = metadata
|
||||
otio_effect.metadata.update(metadata)
|
||||
|
||||
# add otio effect to clip effects
|
||||
otio_clip.effects.append(otio_effect)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ from openpype.api import get_project_settings
|
|||
class GpuCacheLoader(load.LoaderPlugin):
|
||||
"""Load Alembic as gpuCache"""
|
||||
|
||||
families = ["model"]
|
||||
families = ["model", "animation", "pointcache"]
|
||||
representations = ["abc"]
|
||||
|
||||
label = "Import Gpu Cache"
|
||||
|
|
|
|||
|
|
@ -1,9 +1,49 @@
|
|||
from maya import cmds
|
||||
import maya.api.OpenMaya as om
|
||||
|
||||
import pyblish.api
|
||||
import json
|
||||
|
||||
|
||||
def get_all_children(nodes):
|
||||
"""Return all children of `nodes` including each instanced child.
|
||||
Using maya.cmds.listRelatives(allDescendents=True) includes only the first
|
||||
instance. As such, this function acts as an optimal replacement with a
|
||||
focus on a fast query.
|
||||
|
||||
"""
|
||||
|
||||
sel = om.MSelectionList()
|
||||
traversed = set()
|
||||
iterator = om.MItDag(om.MItDag.kDepthFirst)
|
||||
for node in nodes:
|
||||
|
||||
if node in traversed:
|
||||
# Ignore if already processed as a child
|
||||
# before
|
||||
continue
|
||||
|
||||
sel.clear()
|
||||
sel.add(node)
|
||||
dag = sel.getDagPath(0)
|
||||
|
||||
iterator.reset(dag)
|
||||
next(iterator) # ignore self
|
||||
while not iterator.isDone():
|
||||
|
||||
path = iterator.fullPathName()
|
||||
|
||||
if path in traversed:
|
||||
iterator.prune()
|
||||
next(iterator)
|
||||
continue
|
||||
|
||||
traversed.add(path)
|
||||
next(iterator)
|
||||
|
||||
return list(traversed)
|
||||
|
||||
|
||||
class CollectInstances(pyblish.api.ContextPlugin):
|
||||
"""Gather instances by objectSet and pre-defined attribute
|
||||
|
||||
|
|
@ -86,12 +126,8 @@ class CollectInstances(pyblish.api.ContextPlugin):
|
|||
# Collect members
|
||||
members = cmds.ls(members, long=True) or []
|
||||
|
||||
# `maya.cmds.listRelatives(noIntermediate=True)` only works when
|
||||
# `shapes=True` argument is passed, since we also want to include
|
||||
# transforms we filter afterwards.
|
||||
children = cmds.listRelatives(members,
|
||||
allDescendents=True,
|
||||
fullPath=True) or []
|
||||
dag_members = cmds.ls(members, type="dagNode", long=True)
|
||||
children = get_all_children(dag_members)
|
||||
children = cmds.ls(children, noIntermediate=True, long=True)
|
||||
|
||||
parents = []
|
||||
|
|
|
|||
|
|
@ -0,0 +1,288 @@
|
|||
import threading
|
||||
import datetime
|
||||
import copy
|
||||
import collections
|
||||
|
||||
import ftrack_api
|
||||
|
||||
from openpype.lib import get_datetime_data
|
||||
from openpype.api import get_project_settings
|
||||
from openpype_modules.ftrack.lib import ServerAction
|
||||
|
||||
|
||||
class CreateDailyReviewSessionServerAction(ServerAction):
|
||||
"""Create daily review session object per project.
|
||||
|
||||
Action creates review sessions based on settings. Settings define if is
|
||||
action enabled and what is a template for review session name. Logic works
|
||||
in a way that if review session with the name already exists then skip
|
||||
process. If review session for current day does not exist but yesterdays
|
||||
review exists and is empty then yesterdays is renamed otherwise creates
|
||||
new review session.
|
||||
|
||||
Also contains cycle creation of dailies which is triggered each morning.
|
||||
This option must be enabled in project settings. Cycle creation is also
|
||||
checked on registration of action.
|
||||
"""
|
||||
|
||||
identifier = "create.daily.review.session"
|
||||
#: Action label.
|
||||
label = "OpenPype Admin"
|
||||
variant = "- Create Daily Review Session (Server)"
|
||||
#: Action description.
|
||||
description = "Manually create daily review session"
|
||||
role_list = {"Pypeclub", "Administrator", "Project Manager"}
|
||||
|
||||
settings_key = "create_daily_review_session"
|
||||
default_template = "{yy}{mm}{dd}"
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(CreateDailyReviewSessionServerAction, self).__init__(
|
||||
*args, **kwargs
|
||||
)
|
||||
|
||||
self._cycle_timer = None
|
||||
self._last_cyle_time = None
|
||||
self._day_delta = datetime.timedelta(days=1)
|
||||
|
||||
def discover(self, session, entities, event):
|
||||
"""Show action only on AssetVersions."""
|
||||
|
||||
valid_selection = False
|
||||
for ent in event["data"]["selection"]:
|
||||
# Ignore entities that are not tasks or projects
|
||||
if ent["entityType"].lower() in (
|
||||
"show", "task", "reviewsession", "assetversion"
|
||||
):
|
||||
valid_selection = True
|
||||
break
|
||||
|
||||
if not valid_selection:
|
||||
return False
|
||||
return self.valid_roles(session, entities, event)
|
||||
|
||||
def launch(self, session, entities, event):
|
||||
project_entity = self.get_project_from_entity(entities[0], session)
|
||||
project_name = project_entity["full_name"]
|
||||
project_settings = self.get_project_settings_from_event(
|
||||
event, project_name
|
||||
)
|
||||
action_settings = self._extract_action_settings(project_settings)
|
||||
project_name_by_id = {
|
||||
project_entity["id"]: project_name
|
||||
}
|
||||
settings_by_project_id = {
|
||||
project_entity["id"]: action_settings
|
||||
}
|
||||
self._process_review_session(
|
||||
session, settings_by_project_id, project_name_by_id
|
||||
)
|
||||
return True
|
||||
|
||||
def register(self, *args, **kwargs):
|
||||
"""Override register to be able trigger """
|
||||
# Register server action as would be normally
|
||||
super(CreateDailyReviewSessionServerAction, self).register(
|
||||
*args, **kwargs
|
||||
)
|
||||
|
||||
# Create threading timer which will trigger creation of report
|
||||
# at the 00:00:01 of next day
|
||||
# - callback will trigger another timer which will have 1 day offset
|
||||
now = datetime.datetime.now()
|
||||
# Create object of today morning
|
||||
today_morning = datetime.datetime(
|
||||
now.year, now.month, now.day, 0, 0, 1
|
||||
)
|
||||
# Add a day delta (to calculate next day date)
|
||||
next_day_morning = today_morning + self._day_delta
|
||||
# Calculate first delta in seconds for first threading timer
|
||||
first_delta = (next_day_morning - now).total_seconds()
|
||||
# Store cycle time which will be used to create next timer
|
||||
self._last_cyle_time = next_day_morning
|
||||
# Create timer thread
|
||||
self._cycle_timer = threading.Timer(first_delta, self._timer_callback)
|
||||
self._cycle_timer.start()
|
||||
|
||||
self._check_review_session()
|
||||
|
||||
def _timer_callback(self):
|
||||
if (
|
||||
self._cycle_timer is not None
|
||||
and self._last_cyle_time is not None
|
||||
):
|
||||
now = datetime.datetime.now()
|
||||
while self._last_cyle_time < now:
|
||||
self._last_cyle_time = self._last_cyle_time + self._day_delta
|
||||
|
||||
delay = (self._last_cyle_time - now).total_seconds()
|
||||
|
||||
self._cycle_timer = threading.Timer(delay, self._timer_callback)
|
||||
self._cycle_timer.start()
|
||||
self._check_review_session()
|
||||
|
||||
def _check_review_session(self):
|
||||
session = ftrack_api.Session(
|
||||
server_url=self.session.server_url,
|
||||
api_key=self.session.api_key,
|
||||
api_user=self.session.api_user,
|
||||
auto_connect_event_hub=False
|
||||
)
|
||||
project_entities = session.query(
|
||||
"select id, full_name from Project"
|
||||
).all()
|
||||
project_names_by_id = {
|
||||
project_entity["id"]: project_entity["full_name"]
|
||||
for project_entity in project_entities
|
||||
}
|
||||
|
||||
action_settings_by_project_id = self._get_action_settings(
|
||||
project_names_by_id
|
||||
)
|
||||
enabled_action_settings_by_project_id = {}
|
||||
for item in action_settings_by_project_id.items():
|
||||
project_id, action_settings = item
|
||||
if action_settings.get("cycle_enabled"):
|
||||
enabled_action_settings_by_project_id[project_id] = (
|
||||
action_settings
|
||||
)
|
||||
|
||||
if not enabled_action_settings_by_project_id:
|
||||
self.log.info((
|
||||
"There are no projects that have enabled"
|
||||
" cycle review sesison creation"
|
||||
))
|
||||
|
||||
else:
|
||||
self._process_review_session(
|
||||
session,
|
||||
enabled_action_settings_by_project_id,
|
||||
project_names_by_id
|
||||
)
|
||||
|
||||
session.close()
|
||||
|
||||
def _process_review_session(
|
||||
self, session, settings_by_project_id, project_names_by_id
|
||||
):
|
||||
review_sessions = session.query((
|
||||
"select id, name, project_id"
|
||||
" from ReviewSession where project_id in ({})"
|
||||
).format(self.join_query_keys(settings_by_project_id))).all()
|
||||
|
||||
review_sessions_by_project_id = collections.defaultdict(list)
|
||||
for review_session in review_sessions:
|
||||
project_id = review_session["project_id"]
|
||||
review_sessions_by_project_id[project_id].append(review_session)
|
||||
|
||||
# Prepare fill data for today's review sesison and yesterdays
|
||||
now = datetime.datetime.now()
|
||||
today_obj = datetime.datetime(
|
||||
now.year, now.month, now.day, 0, 0, 0
|
||||
)
|
||||
yesterday_obj = today_obj - self._day_delta
|
||||
|
||||
today_fill_data = get_datetime_data(today_obj)
|
||||
yesterday_fill_data = get_datetime_data(yesterday_obj)
|
||||
|
||||
# Loop through projects and try to create daily reviews
|
||||
for project_id, action_settings in settings_by_project_id.items():
|
||||
review_session_template = (
|
||||
action_settings["review_session_template"]
|
||||
).strip() or self.default_template
|
||||
|
||||
today_project_fill_data = copy.deepcopy(today_fill_data)
|
||||
yesterday_project_fill_data = copy.deepcopy(yesterday_fill_data)
|
||||
project_name = project_names_by_id[project_id]
|
||||
today_project_fill_data["project_name"] = project_name
|
||||
yesterday_project_fill_data["project_name"] = project_name
|
||||
|
||||
today_session_name = self._fill_review_template(
|
||||
review_session_template, today_project_fill_data
|
||||
)
|
||||
yesterday_session_name = self._fill_review_template(
|
||||
review_session_template, yesterday_project_fill_data
|
||||
)
|
||||
# Skip if today's session name could not be filled
|
||||
if not today_session_name:
|
||||
continue
|
||||
|
||||
# Find matchin review session
|
||||
project_review_sessions = review_sessions_by_project_id[project_id]
|
||||
todays_session = None
|
||||
yesterdays_session = None
|
||||
for review_session in project_review_sessions:
|
||||
session_name = review_session["name"]
|
||||
if session_name == today_session_name:
|
||||
todays_session = review_session
|
||||
break
|
||||
elif session_name == yesterday_session_name:
|
||||
yesterdays_session = review_session
|
||||
|
||||
# Skip if today's session already exist
|
||||
if todays_session is not None:
|
||||
self.log.debug((
|
||||
"Todays ReviewSession \"{}\""
|
||||
" in project \"{}\" already exists"
|
||||
).format(today_session_name, project_name))
|
||||
continue
|
||||
|
||||
# Check if there is yesterday's session and is empty
|
||||
# - in that case just rename it
|
||||
if (
|
||||
yesterdays_session is not None
|
||||
and len(yesterdays_session["review_session_objects"]) == 0
|
||||
):
|
||||
self.log.debug((
|
||||
"Renaming yesterdays empty review session \"{}\" to \"{}\""
|
||||
" in project \"{}\""
|
||||
).format(
|
||||
yesterday_session_name, today_session_name, project_name
|
||||
))
|
||||
yesterdays_session["name"] = today_session_name
|
||||
session.commit()
|
||||
continue
|
||||
|
||||
# Create new review session with new name
|
||||
self.log.debug((
|
||||
"Creating new review session \"{}\" in project \"{}\""
|
||||
).format(today_session_name, project_name))
|
||||
session.create("ReviewSession", {
|
||||
"project_id": project_id,
|
||||
"name": today_session_name
|
||||
})
|
||||
session.commit()
|
||||
|
||||
def _get_action_settings(self, project_names_by_id):
|
||||
settings_by_project_id = {}
|
||||
for project_id, project_name in project_names_by_id.items():
|
||||
project_settings = get_project_settings(project_name)
|
||||
action_settings = self._extract_action_settings(project_settings)
|
||||
settings_by_project_id[project_id] = action_settings
|
||||
return settings_by_project_id
|
||||
|
||||
def _extract_action_settings(self, project_settings):
|
||||
return (
|
||||
project_settings
|
||||
.get("ftrack", {})
|
||||
.get(self.settings_frack_subkey, {})
|
||||
.get(self.settings_key)
|
||||
) or {}
|
||||
|
||||
def _fill_review_template(self, template, data):
|
||||
output = None
|
||||
try:
|
||||
output = template.format(**data)
|
||||
except Exception:
|
||||
self.log.warning(
|
||||
(
|
||||
"Failed to fill review session template {} with data {}"
|
||||
).format(template, data),
|
||||
exc_info=True
|
||||
)
|
||||
return output
|
||||
|
||||
|
||||
def register(session):
|
||||
'''Register plugin. Called when used as an plugin.'''
|
||||
CreateDailyReviewSessionServerAction(session).register()
|
||||
|
|
@ -116,6 +116,15 @@
|
|||
"Administrator",
|
||||
"Project manager"
|
||||
]
|
||||
},
|
||||
"create_daily_review_session": {
|
||||
"enabled": true,
|
||||
"role_list": [
|
||||
"Administrator",
|
||||
"Project Manager"
|
||||
],
|
||||
"cycle_enabled": false,
|
||||
"review_session_template": "{yy}{mm}{dd}"
|
||||
}
|
||||
},
|
||||
"user_handlers": {
|
||||
|
|
|
|||
|
|
@ -388,6 +388,44 @@
|
|||
"object_type": "text"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "create_daily_review_session",
|
||||
"label": "Create daily review session",
|
||||
"type": "dict",
|
||||
"is_group": true,
|
||||
"checkbox_key": "enabled",
|
||||
"children": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"key": "enabled"
|
||||
},
|
||||
{
|
||||
"type": "list",
|
||||
"key": "role_list",
|
||||
"label": "Roles",
|
||||
"object_type": "text",
|
||||
"use_label_wrap": true
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"key": "cycle_enabled",
|
||||
"label": "Create daily review session"
|
||||
},
|
||||
{
|
||||
"type": "separator"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"key": "review_session_template",
|
||||
"label": "ReviewSession template",
|
||||
"placeholder": "Default: {yy}{mm}{dd}"
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"label": "Possible formatting keys in template:<br/>- \"project_name\" - <Name of project><br/>- \"d\" - <Day of month number> in shortest possible way.<br/>- \"dd\" - <Day of month number> with 2 digits.<br/>- \"ddd\" - <Week day name> shortened week day. e.g.: `Mon`, ...<br/>- \"dddd\" - <Week day name> full name of week day. e.g.: `Monday`, ...<br/>- \"m\" - <Month number> in shortest possible way. e.g.: `1` if January<br/>- \"mm\" - <Month number> with 2 digits.<br/>- \"mmm\" - <Month name> shortened month name. e.g.: `Jan`, ...<br/>- \"mmmm\" -<Month name> full month name. e.g.: `January`, ...<br/>- \"yy\" - <Year number> shortened year. e.g.: `19`, `20`, ...<br/>- \"yyyy\" - <Year number> full year. e.g.: `2019`, `2020`, ..."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
|||
|
|
@ -205,3 +205,9 @@ class ToolsDelegate(QtWidgets.QStyledItemDelegate):
|
|||
|
||||
def setModelData(self, editor, model, index):
|
||||
model.setData(index, editor.value(), QtCore.Qt.EditRole)
|
||||
|
||||
def displayText(self, value, locale):
|
||||
if value:
|
||||
return ", ".join(value)
|
||||
else:
|
||||
return
|
||||
|
|
|
|||
|
|
@ -381,7 +381,7 @@ class HierarchyView(QtWidgets.QTreeView):
|
|||
self._source_model.delete_indexes(indexes)
|
||||
|
||||
def _on_ctrl_shift_enter_pressed(self):
|
||||
self._add_task_and_edit()
|
||||
self.add_task_and_edit()
|
||||
|
||||
def add_asset(self, parent_index=None):
|
||||
if parent_index is None:
|
||||
|
|
@ -423,9 +423,9 @@ class HierarchyView(QtWidgets.QTreeView):
|
|||
self.edit(new_index)
|
||||
|
||||
def _add_task_action(self):
|
||||
self._add_task_and_edit()
|
||||
self.add_task_and_edit()
|
||||
|
||||
def _add_task_and_edit(self):
|
||||
def add_task_and_edit(self):
|
||||
new_index = self.add_task()
|
||||
if new_index is None:
|
||||
return
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@ class ProjectManagerWindow(QtWidgets.QWidget):
|
|||
self.hierarchy_view.add_asset()
|
||||
|
||||
def _on_add_task(self):
|
||||
self.hierarchy_view.add_task()
|
||||
self.hierarchy_view.add_task_and_edit()
|
||||
|
||||
def _on_create_folders(self):
|
||||
project_name = self._current_project()
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""Package declaring Pype version."""
|
||||
__version__ = "3.11.0-nightly.1"
|
||||
__version__ = "3.11.0-nightly.2"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[tool.poetry]
|
||||
name = "OpenPype"
|
||||
version = "3.11.0-nightly.1" # OpenPype
|
||||
version = "3.11.0-nightly.2" # OpenPype
|
||||
description = "Open VFX and Animation pipeline with support."
|
||||
authors = ["OpenPype Team <info@openpype.io>"]
|
||||
license = "MIT License"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue