Sync to Blender version specific group node

This commit is contained in:
Sybren A. Stüvel 2016-06-21 17:55:18 +02:00
parent d100232428
commit ed02816872

View File

@ -66,7 +66,15 @@ class PILLAR_OT_sync(async_loop.AsyncModalOperatorMixin, bpy.types.Operator):
name='action', name='action',
description='Synchronises settings with the Blender Cloud.') description='Synchronises settings with the Blender Cloud.')
blender_version = bpy.props.StringProperty(name='blender_version',
description='Blender version to sync for',
default='%i.%i' % bpy.app.version[:2])
def invoke(self, context, event): def invoke(self, context, event):
if not self.blender_version:
self.report({'ERROR'}, 'No Blender version to sync for was given.')
return {'CANCELLED'}
async_loop.AsyncModalOperatorMixin.invoke(self, context, event) async_loop.AsyncModalOperatorMixin.invoke(self, context, event)
log.info('Starting synchronisation') log.info('Starting synchronisation')
@ -89,8 +97,10 @@ class PILLAR_OT_sync(async_loop.AsyncModalOperatorMixin, bpy.types.Operator):
try: try:
user_id = await pillar.check_pillar_credentials() user_id = await pillar.check_pillar_credentials()
except pillar.NotSubscribedToCloudError: except pillar.NotSubscribedToCloudError:
self.log.warning('Please subscribe to the blender cloud at https://cloud.blender.org/join') self.log.warning(
self.report({'INFO'}, 'Please subscribe to the blender cloud at https://cloud.blender.org/join') 'Please subscribe to the blender cloud at https://cloud.blender.org/join')
self.report({'INFO'},
'Please subscribe to the blender cloud at https://cloud.blender.org/join')
return None return None
except pillar.CredentialsNotSyncedError: except pillar.CredentialsNotSyncedError:
self.log.info('Credentials not synced, re-syncing automatically.') self.log.info('Credentials not synced, re-syncing automatically.')
@ -101,8 +111,10 @@ class PILLAR_OT_sync(async_loop.AsyncModalOperatorMixin, bpy.types.Operator):
try: try:
user_id = await pillar.refresh_pillar_credentials() user_id = await pillar.refresh_pillar_credentials()
except pillar.NotSubscribedToCloudError: except pillar.NotSubscribedToCloudError:
self.log.warning('Please subscribe to the blender cloud at https://cloud.blender.org/join') self.log.warning(
self.report({'INFO'}, 'Please subscribe to the blender cloud at https://cloud.blender.org/join') 'Please subscribe to the blender cloud at https://cloud.blender.org/join')
self.report({'INFO'},
'Please subscribe to the blender cloud at https://cloud.blender.org/join')
return None return None
except pillar.UserNotLoggedInError: except pillar.UserNotLoggedInError:
self.log.error('User not logged in on Blender ID.') self.log.error('User not logged in on Blender ID.')
@ -264,7 +276,7 @@ class PILLAR_OT_sync(async_loop.AsyncModalOperatorMixin, bpy.types.Operator):
for key, value in remembered.items(): for key, value in remembered.items():
if '.' in key: if '.' in key:
last_dot = key.rindex('.') last_dot = key.rindex('.')
parent, key = key[:last_dot], key[last_dot+1:] parent, key = key[:last_dot], key[last_dot + 1:]
set_on = up.path_resolve(parent) set_on = up.path_resolve(parent)
else: else:
set_on = up set_on = up
@ -280,36 +292,80 @@ class PILLAR_OT_sync(async_loop.AsyncModalOperatorMixin, bpy.types.Operator):
# we need to shut it down forcefully. # we need to shut it down forcefully.
async_loop.erase_async_loop() async_loop.erase_async_loop()
async def find_sync_group_id(self) -> pillarsdk.Node: async def find_or_create_node(self,
where: dict,
additional_create_props: dict,
projection: dict = None) -> (pillarsdk.Node, bool):
"""Finds a node by the `filter_props`, creates it using the additional props.
:returns: tuple (node, created), where 'created' is a bool indicating whether
a new node was created, or an exising one is returned.
"""
params = {
'where': where,
}
if projection:
params['projection'] = projection
found_node = await pillar_call(pillarsdk.Node.find_first, params, caching=False)
created = False
if found_node is None:
log.info('Creating new sync group node')
# Augment the node properties to form a complete node.
node_props = where.copy()
node_props.update(additional_create_props)
found_node = pillarsdk.Node.new(node_props)
created_ok = await pillar_call(found_node.create)
if not created_ok:
log.error('Blender Cloud addon: unable to create node on the Cloud.')
raise pillar.PillarError('Unable to create node on the Cloud')
created = True
return found_node, created
async def find_sync_group_id(self) -> str:
"""Finds the group node in which to store sync assets. """Finds the group node in which to store sync assets.
If the group node doesn't exist, it creates it. If the group node doesn't exist, it creates it.
""" """
node_props = {'project': self.home_project_id, # Find/create the top-level sync group node.
'node_type': 'group', try:
'parent': None, sync_group, created = await self.find_or_create_node(
'name': SYNC_GROUP_NODE_NAME, where={'project': self.home_project_id,
'user': self.user_id} 'node_type': 'group',
sync_group = await pillar_call(pillarsdk.Node.find_first, { 'parent': None,
'where': node_props, 'name': SYNC_GROUP_NODE_NAME,
'projection': {'_id': 1} 'user': self.user_id},
}, caching=False) additional_create_props={
'description': SYNC_GROUP_NODE_DESC,
'properties': {'status': 'published'},
},
projection={'_id': 1})
except pillar.PillarError:
raise pillar.PillarError('Unable to create sync folder on the Cloud')
if sync_group is None: # Find/create the sub-group for the requested Blender version
log.debug('Creating new sync group node') try:
sub_sync_group, created = await self.find_or_create_node(
where={'project': self.home_project_id,
'node_type': 'group',
'parent': sync_group['_id'],
'name': self.blender_version,
'user': self.user_id},
additional_create_props={
'description': 'Sync folder for Blender %s' % self.blender_version,
'properties': {'status': 'published'},
},
projection={'_id': 1})
except pillar.PillarError:
raise pillar.PillarError('Unable to create sync folder on the Cloud')
# Augment the node properties to form a complete node. return sub_sync_group['_id']
node_props['description'] = SYNC_GROUP_NODE_DESC
node_props['properties'] = {'status': 'published'}
sync_group = pillarsdk.Node.new(node_props)
created_ok = await pillar_call(sync_group.create)
if not created_ok:
log.error('Blender Cloud addon: unable to create sync folder on the Cloud.')
raise pillar.PillarError('Unable to create sync folder on the Cloud')
return sync_group['_id']
async def attach_file_to_group(self, file_path: pathlib.Path) -> pillarsdk.Node: async def attach_file_to_group(self, file_path: pathlib.Path) -> pillarsdk.Node:
"""Creates an Asset node and attaches a file document to it.""" """Creates an Asset node and attaches a file document to it."""
@ -317,33 +373,29 @@ class PILLAR_OT_sync(async_loop.AsyncModalOperatorMixin, bpy.types.Operator):
# First upload the file... # First upload the file...
file_id = await pillar.upload_file(self.home_project_id, file_path, file_id = await pillar.upload_file(self.home_project_id, file_path,
future=self.signalling_future) future=self.signalling_future)
# Then attach it to a node. # Then attach it to a node.
node_props = {'project': self.home_project_id, node, created = await self.find_or_create_node(
'node_type': 'asset', where={
'parent': self.sync_group_id, 'project': self.home_project_id,
'name': file_path.name} 'node_type': 'asset',
node = await pillar_call(pillarsdk.Node.find_first, { 'parent': self.sync_group_id,
'where': node_props, 'name': file_path.name,
}, caching=False) 'user': self.user_id},
additional_create_props={
'properties': {'file': file_id},
})
if node is None: if not created:
# We're going to create a new node, so complete it.
log.debug('Creating new asset node')
node_props['user'] = self.user_id
node_props['properties'] = {'file': file_id}
node = pillarsdk.Node.new(node_props)
created_ok = await pillar_call(node.create)
if not created_ok:
log.error('Blender Cloud addon: unable to create asset node on the Cloud for file %s.', file_path)
raise pillar.PillarError('Unable to create asset node on the Cloud for file %s' % file_path.name)
else:
# Update the existing node. # Update the existing node.
node.properties = {'file': file_id} node.properties = {'file': file_id}
updated_ok = await pillar_call(node.update) updated_ok = await pillar_call(node.update)
if not updated_ok: if not updated_ok:
log.error('Blender Cloud addon: unable to update asset node on the Cloud for file %s.', file_path) log.error(
raise pillar.PillarError('Unable to update asset node on the Cloud for file %s' % file_path.name) 'Blender Cloud addon: unable to update asset node on the Cloud for file %s.',
file_path)
raise pillar.PillarError(
'Unable to update asset node on the Cloud for file %s' % file_path.name)
return node return node