Attract sequence strip buttons are working.
This commit is contained in:
parent
8dab01138e
commit
6fda496652
@ -36,6 +36,8 @@
|
|||||||
# "support": "TESTING"
|
# "support": "TESTING"
|
||||||
# }
|
# }
|
||||||
|
|
||||||
|
import functools
|
||||||
|
|
||||||
if "bpy" in locals():
|
if "bpy" in locals():
|
||||||
import importlib
|
import importlib
|
||||||
|
|
||||||
@ -44,13 +46,10 @@ else:
|
|||||||
from . import draw
|
from . import draw
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
from pillarsdk.api import Api
|
|
||||||
from pillarsdk.nodes import Node
|
from pillarsdk.nodes import Node
|
||||||
from pillarsdk.projects import Project
|
from pillarsdk.projects import Project
|
||||||
from pillarsdk import utils
|
|
||||||
from pillarsdk.exceptions import ResourceNotFound
|
from pillarsdk.exceptions import ResourceNotFound
|
||||||
|
|
||||||
from bpy.props import StringProperty
|
|
||||||
from bpy.types import Operator, Panel, AddonPreferences
|
from bpy.types import Operator, Panel, AddonPreferences
|
||||||
|
|
||||||
|
|
||||||
@ -95,8 +94,11 @@ class ToolsPanel(Panel):
|
|||||||
|
|
||||||
if strip.atc_is_synced:
|
if strip.atc_is_synced:
|
||||||
layout.operator('attract.shot_submit_update')
|
layout.operator('attract.shot_submit_update')
|
||||||
layout.operator('attract.shot_delete')
|
|
||||||
layout.operator('attract.strip_unlink')
|
# Group more dangerous operations.
|
||||||
|
dangerous_sub = layout.column(align=True)
|
||||||
|
dangerous_sub.operator('attract.shot_delete')
|
||||||
|
dangerous_sub.operator('attract.strip_unlink')
|
||||||
|
|
||||||
elif strip and strip.type in strip_types:
|
elif strip and strip.type in strip_types:
|
||||||
layout.operator('attract.shot_submit_new')
|
layout.operator('attract.shot_submit_new')
|
||||||
@ -113,15 +115,23 @@ class AttractOperatorMixin:
|
|||||||
self.report({'ERROR'}, 'Your Blender Cloud project is not set up for Attract.')
|
self.report({'ERROR'}, 'Your Blender Cloud project is not set up for Attract.')
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
|
||||||
|
@functools.lru_cache()
|
||||||
|
def find_project(self, project_uuid: str) -> Project:
|
||||||
|
"""Finds a single project.
|
||||||
|
|
||||||
|
Caches the result in memory to prevent more than one call to Pillar.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from .. import pillar
|
||||||
|
|
||||||
|
project = pillar.call(Project.find_one, {'where': {'_id': project_uuid}})
|
||||||
|
return project
|
||||||
|
|
||||||
def find_node_type(self, node_type_name: str) -> dict:
|
def find_node_type(self, node_type_name: str) -> dict:
|
||||||
from .. import pillar, blender
|
from .. import pillar, blender
|
||||||
|
|
||||||
prefs = blender.preferences()
|
prefs = blender.preferences()
|
||||||
|
project = self.find_project(prefs.project_uuid)
|
||||||
project = pillar.call(Project.find_one, {
|
|
||||||
'where': {'_id': prefs.project_uuid},
|
|
||||||
'projection': {'node_types': {'$elemMatch': {'name': node_type_name}}}
|
|
||||||
})
|
|
||||||
|
|
||||||
# FIXME: Eve doesn't seem to handle the $elemMatch projection properly,
|
# FIXME: Eve doesn't seem to handle the $elemMatch projection properly,
|
||||||
# even though it works fine in MongoDB itself. As a result, we have to
|
# even though it works fine in MongoDB itself. As a result, we have to
|
||||||
@ -146,7 +156,6 @@ class AttractShotSubmitNew(AttractOperatorMixin, Operator):
|
|||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
from .. import pillar, blender
|
from .. import pillar, blender
|
||||||
import blender_id
|
|
||||||
|
|
||||||
strip = active_strip(context)
|
strip = active_strip(context)
|
||||||
if strip.atc_object_id:
|
if strip.atc_object_id:
|
||||||
@ -157,6 +166,12 @@ class AttractShotSubmitNew(AttractOperatorMixin, Operator):
|
|||||||
return node_type
|
return node_type
|
||||||
|
|
||||||
# Define the shot properties
|
# Define the shot properties
|
||||||
|
user_uuid = pillar.pillar_user_uuid()
|
||||||
|
if not user_uuid:
|
||||||
|
self.report({'ERROR'}, 'Your Blender Cloud user ID is not known, '
|
||||||
|
'update your credentials.')
|
||||||
|
return {'CANCELLED'}
|
||||||
|
|
||||||
prop = {'name': strip.name,
|
prop = {'name': strip.name,
|
||||||
'description': '',
|
'description': '',
|
||||||
'properties': {'status': 'on_hold',
|
'properties': {'status': 'on_hold',
|
||||||
@ -166,7 +181,7 @@ class AttractShotSubmitNew(AttractOperatorMixin, Operator):
|
|||||||
'order': 0,
|
'order': 0,
|
||||||
'node_type': 'shot',
|
'node_type': 'shot',
|
||||||
'project': blender.preferences().project_uuid,
|
'project': blender.preferences().project_uuid,
|
||||||
'user': blender_id.get_active_user_id()}
|
'user': user_uuid}
|
||||||
|
|
||||||
# Create a Node item with the attract API
|
# Create a Node item with the attract API
|
||||||
node = Node(prop)
|
node = Node(prop)
|
||||||
@ -183,6 +198,8 @@ class AttractShotSubmitNew(AttractOperatorMixin, Operator):
|
|||||||
strip.atc_cut_in = node['properties']['cut_in']
|
strip.atc_cut_in = node['properties']['cut_in']
|
||||||
strip.atc_cut_out = node['properties']['cut_out']
|
strip.atc_cut_out = node['properties']['cut_out']
|
||||||
|
|
||||||
|
draw.tag_redraw_all_sequencer_editors()
|
||||||
|
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
@ -198,7 +215,7 @@ class AttractShotRelink(AttractOperatorMixin, Operator):
|
|||||||
try:
|
try:
|
||||||
node = pillar.call(Node.find, self.strip_atc_object_id)
|
node = pillar.call(Node.find, self.strip_atc_object_id)
|
||||||
except ResourceNotFound:
|
except ResourceNotFound:
|
||||||
self.report({'ERROR'}, 'Shot %r not found on the server, unable to relink.'
|
self.report({'ERROR'}, 'Shot %r not found on the Attract server, unable to relink.'
|
||||||
% self.strip_atc_object_id)
|
% self.strip_atc_object_id)
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
|
||||||
@ -210,6 +227,8 @@ class AttractShotRelink(AttractOperatorMixin, Operator):
|
|||||||
strip.atc_description = node.description
|
strip.atc_description = node.description
|
||||||
|
|
||||||
self.report({'INFO'}, "Shot {0} relinked".format(node.name))
|
self.report({'INFO'}, "Shot {0} relinked".format(node.name))
|
||||||
|
draw.tag_redraw_all_sequencer_editors()
|
||||||
|
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
@ -227,18 +246,22 @@ class AttractShotSubmitUpdate(AttractOperatorMixin, Operator):
|
|||||||
bl_description = 'Syncronizes local and remote changes'
|
bl_description = 'Syncronizes local and remote changes'
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
|
from .. import pillar
|
||||||
|
|
||||||
strip = active_strip(context)
|
strip = active_strip(context)
|
||||||
# Update cut_in and cut_out properties on the strip
|
# Update cut_in and cut_out properties on the strip
|
||||||
# strip.atc_cut_in = strip.frame_offset_start
|
# strip.atc_cut_in = strip.frame_offset_start
|
||||||
# strip.atc_cut_out = strip.frame_offset_start + strip.frame_final_duration
|
# strip.atc_cut_out = strip.frame_offset_start + strip.frame_final_duration
|
||||||
# print("Query Attract server with {0}".format(strip.atc_object_id))
|
# print("Query Attract server with {0}".format(strip.atc_object_id))
|
||||||
strip.atc_cut_out = strip.atc_cut_in + strip.frame_final_duration - 1
|
strip.atc_cut_out = strip.atc_cut_in + strip.frame_final_duration - 1
|
||||||
node = Node.find(strip.atc_object_id)
|
node = pillar.call(Node.find, strip.atc_object_id)
|
||||||
node.name = strip.atc_name
|
node.name = strip.atc_name
|
||||||
node.description = strip.atc_description
|
node.description = strip.atc_description
|
||||||
node.properties.cut_in = strip.atc_cut_in
|
node.properties.cut_in = strip.atc_cut_in
|
||||||
node.properties.cut_out = strip.atc_cut_out
|
node.properties.cut_out = strip.atc_cut_out
|
||||||
node.update()
|
pillar.call(node.update)
|
||||||
|
|
||||||
|
self.report({'INFO'}, 'Shot was updated on Attract')
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
@ -248,10 +271,16 @@ class AttractShotDelete(AttractOperatorMixin, Operator):
|
|||||||
bl_description = 'Remove from Attract'
|
bl_description = 'Remove from Attract'
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
|
from .. import pillar
|
||||||
|
|
||||||
strip = active_strip(context)
|
strip = active_strip(context)
|
||||||
node = Node.find(strip.atc_object_id)
|
node = pillar.call(Node.find, strip.atc_object_id)
|
||||||
if node.delete():
|
if not pillar.call(node.delete):
|
||||||
|
print('Unable to delete the strip node on Attract.')
|
||||||
|
return {'CANCELLED'}
|
||||||
|
|
||||||
remove_atc_props(strip)
|
remove_atc_props(strip)
|
||||||
|
draw.tag_redraw_all_sequencer_editors()
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
@ -262,7 +291,14 @@ class AttractStripUnlink(AttractOperatorMixin, Operator):
|
|||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
strip = active_strip(context)
|
strip = active_strip(context)
|
||||||
|
|
||||||
|
atc_object_id = getattr(strip, 'atc_object_id')
|
||||||
remove_atc_props(strip)
|
remove_atc_props(strip)
|
||||||
|
|
||||||
|
if atc_object_id:
|
||||||
|
self.report({'INFO'}, 'Shot %s has been unlinked from Attract.' % atc_object_id)
|
||||||
|
|
||||||
|
draw.tag_redraw_all_sequencer_editors()
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
@ -328,6 +364,7 @@ class AttractShotsOrderUpdate(AttractOperatorMixin, Operator):
|
|||||||
# print("Error: shot {0} not found".format(strip.atc_object_id))
|
# print("Error: shot {0} not found".format(strip.atc_object_id))
|
||||||
remove_atc_props(strip)
|
remove_atc_props(strip)
|
||||||
|
|
||||||
|
draw.tag_redraw_all_sequencer_editors()
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
|
@ -146,6 +146,13 @@ def blender_id_subclient() -> dict:
|
|||||||
return subclient
|
return subclient
|
||||||
|
|
||||||
|
|
||||||
|
def pillar_user_uuid() -> str:
|
||||||
|
"""Returns the UUID of the Pillar user."""
|
||||||
|
|
||||||
|
import blender_id
|
||||||
|
return blender_id.get_subclient_user_id(SUBCLIENT_ID)
|
||||||
|
|
||||||
|
|
||||||
def pillar_api(pillar_endpoint: str = None, caching=True) -> pillarsdk.Api:
|
def pillar_api(pillar_endpoint: str = None, caching=True) -> pillarsdk.Api:
|
||||||
"""Returns the Pillar SDK API object for the current user.
|
"""Returns the Pillar SDK API object for the current user.
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user