Blender Kitsu: Move Render Review into Blender Kitsu #296

Merged
5 changed files with 45 additions and 71 deletions
Showing only changes of commit 24f22fd89a - Show all commits

View File

@ -23,7 +23,7 @@ import bpy
from . import (
util,
props,
kitsu,
core,
opsdata,
checksqe,
ops,
@ -40,7 +40,7 @@ if _need_reload:
util = importlib.reload(util)
props = importlib.reload(props)
kitsu = importlib.reload(kitsu)
core = importlib.reload(core)
opsdata = importlib.reload(opsdata)
checksqe = importlib.reload(checksqe)
ops = importlib.reload(ops)

View File

@ -18,7 +18,6 @@
#
# (c) 2021, Blender Foundation - Paul Golter
# TODO Remove duplicate code between this page and the main Blender Kitsu functions
from typing import List, Dict, Union, Any, Set, Optional
import bpy
@ -31,26 +30,11 @@ from ..logger import LoggerFactory
logger = LoggerFactory.getLogger()
def is_auth() -> bool:
return prefs.addon_prefs_get(bpy.context).session.is_auth()
def get_project() -> Optional[types.Project]:
return cache.project_active_get()
def is_active_project() -> bool:
return bool(cache.project_active_get())
def is_auth_and_project() -> bool:
return bool(is_auth() and is_active_project())
def addon_prefs() -> bpy.types.AddonPreferences:
return prefs.addon_prefs_get(bpy.context)
# TODO De-duplicate code from sqe create metastrip
def create_metadata_strip(
context: bpy.types.Context, strip: bpy.types.Sequence
) -> bpy.types.MovieSequence:
@ -87,6 +71,7 @@ def create_metadata_strip(
return metadata_strip
# TODO De-duplicate code from sqe code
def link_strip_by_name(
context: bpy.types.Context,
strip: bpy.types.Sequence,

View File

@ -28,7 +28,7 @@ from collections import OrderedDict
import bpy
from . import vars, opsdata, util, kitsu
from . import vars, opsdata, util, core
from .. import prefs, cache
from .. import types as kitsu_types
@ -145,19 +145,15 @@ class RR_OT_sqe_create_review_session(bpy.types.Operator):
prev_frame_end = strip_longest.frame_final_end
# Perform kitsu operations if enabled.
if (
addon_prefs.enable_blender_kitsu
and prefs.is_blender_kitsu_enabled()
and imported_strips
):
if kitsu.is_auth_and_project():
if prefs.session_auth(context) and imported_strips:
if core.is_active_project():
sequence_name = shot_version_folders[0].parent.parent.parent.name
# Create metadata strip.
metadata_strip = kitsu.create_metadata_strip(context, strip_longest)
metadata_strip = core.create_metadata_strip(context, strip_longest)
# Link metadata strip.
kitsu.link_strip_by_name(context, metadata_strip, shot_name, sequence_name)
core.link_strip_by_name(context, metadata_strip, shot_name, sequence_name)
else:
logger.error(
@ -167,13 +163,11 @@ class RR_OT_sqe_create_review_session(bpy.types.Operator):
# Set default scene resolution to resolution of loaded image.
render_resolution_x = vars.RESOLUTION[0]
render_resolution_y = vars.RESOLUTION[1]
project = cache.project_active_get()
# If Kitsu add-on is enabled, fetch the resolution from the online project
if (
addon_prefs.enable_blender_kitsu and prefs.is_blender_kitsu_enabled()
) and kitsu.is_active_project():
if project:
# TODO: make the resolution fetching a bit more robust
# Assume resolution is a string '<str:width>x<str:height>'
project = kitsu.get_project()
resolution = project.resolution.split('x')
render_resolution_x = int(resolution[0])
render_resolution_y = int(resolution[1])
@ -371,11 +365,8 @@ class RR_OT_setup_review_workspace(bpy.types.Operator):
area.spaces.active.show_overlays = False
def invoke(self, context, _event):
if (
not prefs.is_blender_kitsu_enabled()
or not prefs.addon_prefs_get(context).enable_blender_kitsu
or not kitsu.is_auth_and_project()
):
if not cache.project_active_get():
return self.execute(context)
return context.window_manager.invoke_props_dialog(self)
@ -544,34 +535,34 @@ class RR_OT_sqe_approve_render(bpy.types.Operator):
bpy.ops.rr.sqe_push_to_edit()
strip_dir = opsdata.get_strip_folder(active_strip)
shot_frames_dir = opsdata.get_shot_frames_dir(active_strip)
frames_root_dir = opsdata.get_frames_root_dir(active_strip)
shot_frames_backup_path = opsdata.get_shot_frames_backup_path(active_strip)
metadata_path = opsdata.get_shot_frames_metadata_path(active_strip)
# Create Shot Frames path if not exists yet.
if shot_frames_dir.exists():
if frames_root_dir.exists():
# Delete backup if exists.
if shot_frames_backup_path.exists():
shutil.rmtree(shot_frames_backup_path)
# Rename current to backup.
shot_frames_dir.rename(shot_frames_backup_path)
frames_root_dir.rename(shot_frames_backup_path)
logger.info(
"Created backup: %s > %s",
shot_frames_dir.name,
frames_root_dir.name,
shot_frames_backup_path.name,
)
else:
shot_frames_dir.mkdir(parents=True)
logger.info("Created dir in Shot Frames: %s", shot_frames_dir.as_posix())
frames_root_dir.mkdir(parents=True)
logger.info("Created dir in Shot Frames: %s", frames_root_dir.as_posix())
# Copy dir.
opsdata.copytree_verbose(
strip_dir,
shot_frames_dir,
frames_root_dir,
dirs_exist_ok=True,
)
logger.info("Copied: %s \nTo: %s", strip_dir.as_posix(), shot_frames_dir.as_posix())
logger.info("Copied: %s \nTo: %s", strip_dir.as_posix(), frames_root_dir.as_posix())
# Update metadata json.
if not metadata_path.exists():
@ -595,22 +586,22 @@ class RR_OT_sqe_approve_render(bpy.types.Operator):
util.redraw_ui()
# Log.
self.report({"INFO"}, f"Updated {shot_frames_dir.name} in Shot Frames")
self.report({"INFO"}, f"Updated {frames_root_dir.name} in Shot Frames")
logger.info("Updated metadata in: %s", metadata_path.as_posix())
return {"FINISHED"}
def invoke(self, context, event):
active_strip = context.scene.sequence_editor.active_strip
shot_frames_dir = opsdata.get_shot_frames_dir(active_strip)
width = 200 + len(shot_frames_dir.as_posix()) * 5
frames_root_dir = opsdata.get_frames_root_dir(active_strip)
width = 200 + len(frames_root_dir.as_posix()) * 5
return context.window_manager.invoke_props_dialog(self, width=width)
def draw(self, context: bpy.types.Context) -> None:
layout = self.layout
active_strip = context.scene.sequence_editor.active_strip
strip_dir = opsdata.get_strip_folder(active_strip)
shot_frames_dir = opsdata.get_shot_frames_dir(active_strip)
frames_root_dir = opsdata.get_frames_root_dir(active_strip)
layout.separator()
layout.row(align=True).label(text="From Farm Output:", icon="RENDER_ANIMATION")
@ -618,7 +609,7 @@ class RR_OT_sqe_approve_render(bpy.types.Operator):
layout.separator()
layout.row(align=True).label(text="To Shot Frames:", icon="FILE_TICK")
layout.row(align=True).label(text=shot_frames_dir.as_posix())
layout.row(align=True).label(text=frames_root_dir.as_posix())
layout.separator()
layout.row(align=True).label(text="Update Shot Frames?")

View File

@ -26,7 +26,7 @@ from typing import Set, Union, Optional, List, Dict, Any, Tuple
import bpy
from . import vars, checksqe
from .. import prefs
from .. import prefs, cache
from .exception import NoImageSequenceAvailableException
from ..logger import LoggerFactory
@ -83,7 +83,7 @@ def get_valid_cs_sequences(
else:
sequences = context.selected_sequences or context.scene.sequence_editor.sequences_all
if prefs.is_blender_kitsu_enabled():
if cache.project_active_get():
valid_sequences = [
s
@ -96,11 +96,11 @@ def get_valid_cs_sequences(
return valid_sequences
def get_shot_frames_dir(strip: bpy.types.Sequence) -> Path:
def get_frames_root_dir(strip: bpy.types.Sequence) -> Path:
# sf = shot_frames | fo = farm_output.
addon_prefs = prefs.addon_prefs_get(bpy.context)
fo_dir = get_strip_folder(strip)
sf_dir = addon_prefs.shot_frames_dir / fo_dir.parent.relative_to(fo_dir.parents[3])
sf_dir = addon_prefs.frames_root_dir / fo_dir.parent.relative_to(fo_dir.parents[3])
return sf_dir
@ -116,7 +116,7 @@ def get_shot_previews_path(strip: bpy.types.Sequence) -> Path:
# Fo > farm_output.
addon_prefs = prefs.addon_prefs_get(bpy.context)
fo_dir = get_strip_folder(strip)
shot_previews_dir = addon_prefs.shot_previews_path / fo_dir.parent.relative_to(
shot_previews_dir = addon_prefs.shot_playblast_root_dir / fo_dir.parent.relative_to(
fo_dir.parents[3]
)
@ -172,12 +172,12 @@ def get_best_preview_sequence(dir: Path) -> List[Path]:
def get_shot_frames_backup_path(strip: bpy.types.Sequence) -> Path:
fs_dir = get_shot_frames_dir(strip)
fs_dir = get_frames_root_dir(strip)
return fs_dir.parent / f"_backup.{fs_dir.name}"
def get_shot_frames_metadata_path(strip: bpy.types.Sequence) -> Path:
fs_dir = get_shot_frames_dir(strip)
fs_dir = get_frames_root_dir(strip)
return fs_dir.parent / "metadata.json"

View File

@ -34,8 +34,8 @@ from .ops import (
RR_OT_open_path,
RR_OT_sqe_push_to_edit,
)
from . import opsdata, kitsu
from .. import prefs
from . import opsdata, core
from .. import prefs, cache
class RR_PT_render_review(bpy.types.Panel):
@ -81,15 +81,14 @@ class RR_PT_render_review(bpy.types.Panel):
row.prop(addon_prefs, 'use_video_latest_only')
# Warning if kitsu on but not logged in.
if addon_prefs.enable_blender_kitsu and prefs.is_blender_kitsu_enabled():
if not kitsu.is_auth():
row = box.split(align=True, factor=0.7)
row.label(text="Kitsu enabled but not logged in", icon="ERROR")
row.operator("kitsu.session_start", text="Login")
if not prefs.session_auth(context):
row = box.split(align=True, factor=0.7)
row.label(text="Kitsu enabled but not logged in", icon="ERROR")
row.operator("kitsu.session_start", text="Login")
elif not kitsu.is_active_project():
row = box.row(align=True)
row.label(text="Kitsu enabled but no active project", icon="ERROR")
elif not core.is_active_project():
row = box.row(align=True)
row.label(text="Kitsu enabled but no active project", icon="ERROR")
sqe = context.scene.sequence_editor
if not sqe:
@ -134,7 +133,7 @@ class RR_PT_render_review(bpy.types.Panel):
row.operator(RR_OT_sqe_update_sequence_statuses.bl_idname, text="", icon="FILE_REFRESH")
# Push to edit.
if not addon_prefs.shot_previews_path:
if not addon_prefs.shot_playblast_root_dir:
shot_previews_dir = "" # ops handle invalid path
else:
shot_previews_dir = Path(opsdata.get_shot_previews_path(active_strip)).as_posix()
@ -145,9 +144,8 @@ class RR_PT_render_review(bpy.types.Panel):
shot_previews_dir
)
if prefs.is_blender_kitsu_enabled():
# Push strip to Kitsu.
box.row().operator('kitsu.sqe_push_shot', icon='URL')
# Push strip to Kitsu.
box.row().operator('kitsu.sqe_push_shot', icon='URL')
def RR_topbar_file_new_draw_handler(self: Any, context: bpy.types.Context) -> None: