Blender Kitsu: Set Custom Thumbnail during Playblast #77
@ -411,6 +411,7 @@ def get_user_all_tasks() -> List[Task]:
|
||||
def _init_cache_entity(
|
||||
entity_id: str, entity_type: Any, cache_variable_name: Any, cache_name: str
|
||||
) -> None:
|
||||
|
||||
if entity_id:
|
||||
try:
|
||||
globals()[cache_variable_name] = entity_type.by_id(entity_id)
|
||||
|
@ -1,6 +1,8 @@
|
||||
import string
|
||||
import json
|
||||
|
||||
from .exception import TaskStatusNotFound
|
||||
|
||||
from . import client as raw
|
||||
from .sorting import sort_by_name
|
||||
from .helpers import (
|
||||
@ -41,7 +43,9 @@ def all_task_types_for_project(project, client=default):
|
||||
list: Task types stored in database.
|
||||
"""
|
||||
project = normalize_model_parameter(project)
|
||||
task_types = raw.fetch_all("projects/%s/task-types" % project["id"], client=client)
|
||||
task_types = raw.fetch_all(
|
||||
"projects/%s/task-types" % project["id"], client=client
|
||||
)
|
||||
return sort_by_name(task_types)
|
||||
|
||||
|
||||
@ -271,7 +275,9 @@ def all_task_types_for_asset(asset, client=default):
|
||||
list: Task types of tasks related to given asset.
|
||||
"""
|
||||
asset = normalize_model_parameter(asset)
|
||||
task_types = raw.fetch_all("assets/%s/task-types" % asset["id"], client=client)
|
||||
task_types = raw.fetch_all(
|
||||
"assets/%s/task-types" % asset["id"], client=client
|
||||
)
|
||||
return sort_by_name(task_types)
|
||||
|
||||
|
||||
@ -405,7 +411,9 @@ def get_task_type_by_name(task_type_name, client=default):
|
||||
Returns:
|
||||
dict: Task type object for given name.
|
||||
"""
|
||||
return raw.fetch_first("task-types", {"name": task_type_name}, client=client)
|
||||
return raw.fetch_first(
|
||||
"task-types", {"name": task_type_name}, client=client
|
||||
)
|
||||
|
||||
|
||||
@cache
|
||||
@ -591,7 +599,9 @@ def start_task(task, started_task_status=None, client=default):
|
||||
dict: Created comment.
|
||||
"""
|
||||
if started_task_status is None:
|
||||
started_task_status = get_task_status_by_short_name("wip", client=client)
|
||||
started_task_status = get_task_status_by_short_name(
|
||||
"wip", client=client
|
||||
)
|
||||
if started_task_status is None:
|
||||
raise TaskStatusNotFound(
|
||||
(
|
||||
@ -745,7 +755,9 @@ def add_comment(
|
||||
data["created_at"] = created_at
|
||||
|
||||
if len(attachments) == 0:
|
||||
return raw.post("actions/tasks/%s/comment" % task["id"], data, client=client)
|
||||
return raw.post(
|
||||
"actions/tasks/%s/comment" % task["id"], data, client=client
|
||||
)
|
||||
else:
|
||||
attachment = attachments.pop()
|
||||
data["checklist"] = json.dumps(checklist)
|
||||
@ -758,7 +770,9 @@ def add_comment(
|
||||
)
|
||||
|
||||
|
||||
def add_attachment_files_to_comment(task, comment, attachments=[], client=default):
|
||||
def add_attachment_files_to_comment(
|
||||
task, comment, attachments=[], client=default
|
||||
):
|
||||
"""
|
||||
Add attachments files to a given comment.
|
||||
|
||||
@ -778,7 +792,8 @@ def add_attachment_files_to_comment(task, comment, attachments=[], client=defaul
|
||||
comment = normalize_model_parameter(comment)
|
||||
attachment = attachments.pop()
|
||||
return raw.upload(
|
||||
"actions/tasks/%s/comments/%s/add-attachment" % (task["id"], comment["id"]),
|
||||
"actions/tasks/%s/comments/%s/add-attachment"
|
||||
% (task["id"], comment["id"]),
|
||||
attachment,
|
||||
extra_files=attachments,
|
||||
client=client,
|
||||
@ -830,7 +845,9 @@ def create_preview(task, comment, client=default):
|
||||
return raw.post(path, {}, client=client)
|
||||
|
||||
|
||||
def upload_preview_file(preview, file_path, normalize_movie=True, client=default):
|
||||
def upload_preview_file(
|
||||
preview, file_path, normalize_movie=True, client=default
|
||||
):
|
||||
"""
|
||||
Create a preview into given comment.
|
||||
|
||||
@ -838,7 +855,9 @@ def upload_preview_file(preview, file_path, normalize_movie=True, client=default
|
||||
task (str / dict): The task dict or the task ID.
|
||||
file_path (str): Path of the file to upload as preview.
|
||||
"""
|
||||
path = "pictures/preview-files/%s" % normalize_model_parameter(preview)["id"]
|
||||
path = (
|
||||
"pictures/preview-files/%s" % normalize_model_parameter(preview)["id"]
|
||||
)
|
||||
if not normalize_movie:
|
||||
path += "?normalize=false"
|
||||
return raw.upload(path, file_path, client=client)
|
||||
@ -877,21 +896,19 @@ def add_preview(
|
||||
)
|
||||
|
||||
|
||||
def set_main_preview(preview_file, frame_number, client=default):
|
||||
def set_main_preview(preview_file, client=default):
|
||||
"""
|
||||
Set given preview as thumbnail of given entity.
|
||||
|
||||
Args:
|
||||
preview_file (str / dict): The preview file dict or ID.
|
||||
frame_number (int): Frame of preview video to set as main preview
|
||||
|
||||
Returns:
|
||||
dict: Created preview file model.
|
||||
"""
|
||||
data = {"frame_number": frame_number} if frame_number > 1 else {}
|
||||
preview_file = normalize_model_parameter(preview_file)
|
||||
path = "actions/preview-files/%s/set-main-preview" % preview_file["id"]
|
||||
return raw.put(path, data, client=client)
|
||||
return raw.put(path, {}, client=client)
|
||||
|
||||
|
||||
@cache
|
||||
@ -983,7 +1000,9 @@ def update_task(task, client=default):
|
||||
dict: Updated task.
|
||||
"""
|
||||
if "assignees" in task:
|
||||
task["assignees"] = normalize_list_of_models_for_links(task["assignees"])
|
||||
task["assignees"] = normalize_list_of_models_for_links(
|
||||
task["assignees"]
|
||||
)
|
||||
return raw.put("data/tasks/%s" % task["id"], task, client=client)
|
||||
|
||||
|
||||
|
@ -25,8 +25,8 @@ from blender_kitsu.shot_builder.task_type import TaskType
|
||||
from blender_kitsu.shot_builder.render_settings import RenderSettings
|
||||
from blender_kitsu.shot_builder.connectors.connector import Connector
|
||||
import requests
|
||||
from blender_kitsu import cache
|
||||
from blender_kitsu.gazu.asset import all_assets_for_shot
|
||||
from blender_kitsu import cache
|
||||
from blender_kitsu.gazu.asset import all_assets_for_shot
|
||||
from blender_kitsu.gazu.shot import all_shots_for_project, all_sequences_for_project
|
||||
|
||||
import typing
|
||||
@ -43,19 +43,16 @@ class KitsuPreferences(bpy.types.PropertyGroup):
|
||||
backend: bpy.props.StringProperty( # type: ignore
|
||||
name="Server URL",
|
||||
description="Kitsu server address",
|
||||
default="https://kitsu.blender.cloud/api",
|
||||
)
|
||||
default="https://kitsu.blender.cloud/api")
|
||||
|
||||
username: bpy.props.StringProperty( # type: ignore
|
||||
name="Username",
|
||||
description="Username to connect to Kitsu",
|
||||
)
|
||||
description="Username to connect to Kitsu",)
|
||||
|
||||
password: bpy.props.StringProperty( # type: ignore
|
||||
name="Password",
|
||||
description="Password to connect to Kitsu",
|
||||
subtype='PASSWORD',
|
||||
)
|
||||
subtype='PASSWORD',)
|
||||
|
||||
def draw(self, layout: bpy.types.UILayout, context: bpy.types.Context) -> None:
|
||||
layout.label(text="Kitsu")
|
||||
@ -66,11 +63,10 @@ class KitsuPreferences(bpy.types.PropertyGroup):
|
||||
def _validate(self):
|
||||
if not (self.backend and self.username and self.password):
|
||||
raise KitsuException(
|
||||
"Kitsu connector has not been configured in the add-on preferences"
|
||||
)
|
||||
"Kitsu connector has not been configured in the add-on preferences")
|
||||
|
||||
|
||||
class KitsuDataContainer:
|
||||
class KitsuDataContainer():
|
||||
def __init__(self, data: typing.Dict[str, typing.Optional[str]]):
|
||||
self._data = data
|
||||
|
||||
@ -113,17 +109,7 @@ class KitsuSequenceRef(ShotRef):
|
||||
|
||||
|
||||
class KitsuShotRef(ShotRef):
|
||||
def __init__(
|
||||
self,
|
||||
kitsu_id: str,
|
||||
name: str,
|
||||
code: str,
|
||||
frame_start: int,
|
||||
frames: int,
|
||||
frame_end: int,
|
||||
frames_per_second: float,
|
||||
sequence: KitsuSequenceRef,
|
||||
):
|
||||
def __init__(self, kitsu_id: str, name: str, code: str, frame_start: int, frames: int, frame_end: int, frames_per_second: float, sequence: KitsuSequenceRef):
|
||||
super().__init__(name=name, code=code)
|
||||
self.kitsu_id = kitsu_id
|
||||
self.frame_start = frame_start
|
||||
@ -151,7 +137,8 @@ class KitsuConnector(Connector):
|
||||
|
||||
def __get_production_data(self) -> KitsuProject:
|
||||
production = cache.project_active_get()
|
||||
project = KitsuProject(typing.cast(typing.Dict[str, typing.Any], production))
|
||||
project = KitsuProject(typing.cast(
|
||||
typing.Dict[str, typing.Any], production))
|
||||
return project
|
||||
|
||||
def get_name(self) -> str:
|
||||
@ -162,7 +149,6 @@ class KitsuConnector(Connector):
|
||||
project = cache.project_active_get()
|
||||
task_types = project.task_types
|
||||
import pprint
|
||||
|
||||
pprint.pprint(task_types)
|
||||
return []
|
||||
|
||||
@ -170,76 +156,56 @@ class KitsuConnector(Connector):
|
||||
project = cache.project_active_get()
|
||||
kitsu_sequences = all_sequences_for_project(project.id)
|
||||
|
||||
sequence_lookup = {
|
||||
sequence_data['id']: KitsuSequenceRef(
|
||||
kitsu_id=sequence_data['id'],
|
||||
name=sequence_data['name'],
|
||||
code=sequence_data['code'],
|
||||
)
|
||||
for sequence_data in kitsu_sequences
|
||||
}
|
||||
sequence_lookup = {sequence_data['id']: KitsuSequenceRef(
|
||||
kitsu_id=sequence_data['id'],
|
||||
name=sequence_data['name'],
|
||||
code=sequence_data['code'],
|
||||
) for sequence_data in kitsu_sequences}
|
||||
|
||||
kitsu_shots = all_shots_for_project(project.id)
|
||||
shots: typing.List[ShotRef] = []
|
||||
|
||||
for shot_data in kitsu_shots:
|
||||
# Initialize default values
|
||||
|
||||
#Initialize default values
|
||||
frame_start = vars.DEFAULT_FRAME_START
|
||||
frame_end = 0
|
||||
|
||||
# shot_data['data'] can be None
|
||||
if shot_data['data']:
|
||||
# If 3d_in key not found use default start frame.
|
||||
frame_start = int(
|
||||
shot_data['data'].get('3d_in', vars.DEFAULT_FRAME_START)
|
||||
)
|
||||
frame_start = int(shot_data['data'].get('3d_in', vars.DEFAULT_FRAME_START))
|
||||
frame_end = int(shot_data['data'].get('3d_out', 0))
|
||||
|
||||
# If 3d_in and 3d_out available use that to calculate frames.
|
||||
# If not try shot_data['nb_frames'] or 0 -> invalid.
|
||||
frames = int(
|
||||
(frame_end - frame_start + 1)
|
||||
if frame_end
|
||||
else shot_data['nb_frames'] or 0
|
||||
)
|
||||
frames = int((frame_end - frame_start + 1) if frame_end else shot_data['nb_frames'] or 0)
|
||||
if frames < 0:
|
||||
logger.error(
|
||||
"%s duration is negative: %i. Check frame range information on Kitsu",
|
||||
shot_data['name'],
|
||||
frames,
|
||||
)
|
||||
logger.error("%s duration is negative: %i. Check frame range information on Kitsu", shot_data['name'], frames)
|
||||
frames = 0
|
||||
|
||||
shots.append(
|
||||
KitsuShotRef(
|
||||
kitsu_id=shot_data['id'],
|
||||
name=shot_data['name'],
|
||||
code=shot_data['code'],
|
||||
frame_start=frame_start,
|
||||
frames=frames,
|
||||
frame_end=frame_end,
|
||||
frames_per_second=24.0,
|
||||
sequence=sequence_lookup[shot_data['parent_id']],
|
||||
)
|
||||
)
|
||||
shots.append(KitsuShotRef(
|
||||
kitsu_id=shot_data['id'],
|
||||
name=shot_data['name'],
|
||||
code=shot_data['code'],
|
||||
frame_start=frame_start,
|
||||
frames=frames,
|
||||
frame_end = frame_end,
|
||||
frames_per_second=24.0,
|
||||
sequence=sequence_lookup[shot_data['parent_id']],
|
||||
))
|
||||
|
||||
return shots
|
||||
|
||||
def get_assets_for_shot(self, shot: Shot) -> typing.List[AssetRef]:
|
||||
kitsu_assets = all_assets_for_shot(shot.kitsu_id)
|
||||
|
||||
return [
|
||||
AssetRef(name=asset_data['name'], code=asset_data['code'])
|
||||
for asset_data in kitsu_assets
|
||||
]
|
||||
return [AssetRef(name=asset_data['name'], code=asset_data['code'])
|
||||
for asset_data in kitsu_assets]
|
||||
|
||||
def get_render_settings(self, shot: Shot) -> RenderSettings:
|
||||
"""
|
||||
Retrieve the render settings for the given shot.
|
||||
"""
|
||||
project = cache.project_active_get()
|
||||
return RenderSettings(
|
||||
width=int(project.resolution.split('x')[0]),
|
||||
height=int(project.resolution.split('x')[1]),
|
||||
frames_per_second=project.fps,
|
||||
)
|
||||
return RenderSettings(width=int(project.resolution.split('x')[0]), height=int(project.resolution.split('x')[1]), frames_per_second=project.fps)
|
||||
|
Loading…
Reference in New Issue
Block a user