2016-11-08 18:25:23 +01:00
|
|
|
from flask import Markup
|
|
|
|
|
2016-08-19 09:19:06 +02:00
|
|
|
from pillarsdk import Node
|
|
|
|
from pillarsdk.exceptions import ForbiddenAccess
|
|
|
|
from pillarsdk.exceptions import ResourceNotFound
|
2016-09-29 17:34:24 +02:00
|
|
|
from flask_login import current_user
|
2016-08-19 09:19:06 +02:00
|
|
|
|
|
|
|
from pillar.web import system_util
|
|
|
|
|
|
|
|
GROUP_NODES = {'group', 'storage', 'group_texture', 'group_hdri'}
|
|
|
|
|
|
|
|
|
|
|
|
def jstree_parse_node(node, children=None):
|
|
|
|
"""Generate JStree node from node object"""
|
2016-10-04 12:38:00 +02:00
|
|
|
from pillar.web.nodes.routes import url_for_node
|
|
|
|
|
2016-08-19 09:19:06 +02:00
|
|
|
node_type = node.node_type
|
|
|
|
# Define better the node type
|
|
|
|
if node_type == 'asset':
|
|
|
|
node_type = node.properties.content_type
|
|
|
|
parsed_node = dict(
|
|
|
|
id="n_{0}".format(node._id),
|
2016-10-04 12:38:00 +02:00
|
|
|
a_attr={ "href" : url_for_node(node=node) },
|
2016-11-11 17:10:56 +01:00
|
|
|
li_attr={ "data-node-type" : node.node_type },
|
2016-11-08 18:25:23 +01:00
|
|
|
text=Markup.escape(node.name),
|
2016-08-19 09:19:06 +02:00
|
|
|
type=node_type,
|
|
|
|
children=False)
|
|
|
|
# Append children property only if it is a directory type
|
|
|
|
if node_type in GROUP_NODES:
|
|
|
|
parsed_node['children'] = True
|
|
|
|
|
|
|
|
return parsed_node
|
|
|
|
|
|
|
|
|
|
|
|
def jstree_get_children(node_id, project_id=None):
|
|
|
|
api = system_util.pillar_api()
|
|
|
|
children_list = []
|
|
|
|
lookup = {
|
|
|
|
'projection': {
|
|
|
|
'name': 1, 'parent': 1, 'node_type': 1, 'properties.order': 1,
|
|
|
|
'properties.status': 1, 'properties.content_type': 1, 'user': 1,
|
|
|
|
'project': 1},
|
2016-09-29 17:34:24 +02:00
|
|
|
'sort': [('properties.order', 1), ('_created', 1)],
|
|
|
|
'where': {
|
|
|
|
'$and': [
|
|
|
|
{'node_type': {'$regex': '^(?!attract_)'}},
|
|
|
|
{'node_type': {'$not': {'$in': ['comment', 'post', 'blog']}}},
|
|
|
|
],
|
|
|
|
}
|
|
|
|
}
|
2016-08-19 09:19:06 +02:00
|
|
|
if node_id:
|
|
|
|
if node_id.startswith('n_'):
|
|
|
|
node_id = node_id.split('_')[1]
|
2016-09-29 17:34:24 +02:00
|
|
|
lookup['where']['parent'] = node_id
|
2016-08-19 09:19:06 +02:00
|
|
|
elif project_id:
|
2016-09-29 17:34:24 +02:00
|
|
|
lookup['where']['project'] = project_id
|
|
|
|
lookup['where']['parent'] = {'$exists': False}
|
2016-08-19 09:19:06 +02:00
|
|
|
|
|
|
|
try:
|
|
|
|
children = Node.all(lookup, api=api)
|
|
|
|
for child in children['_items']:
|
2016-09-29 17:34:24 +02:00
|
|
|
is_pub = child.properties.status == 'published'
|
|
|
|
if is_pub or (current_user.is_authenticated and child.user == current_user.objectid):
|
|
|
|
children_list.append(jstree_parse_node(child))
|
2016-08-19 09:19:06 +02:00
|
|
|
except ForbiddenAccess:
|
|
|
|
pass
|
|
|
|
return children_list
|
|
|
|
|
|
|
|
|
|
|
|
def jstree_build_children(node):
|
|
|
|
return dict(
|
|
|
|
id="n_{0}".format(node._id),
|
2016-11-08 18:25:23 +01:00
|
|
|
text=Markup.escape(node.name),
|
2016-08-19 09:19:06 +02:00
|
|
|
type=node.node_type,
|
|
|
|
children=jstree_get_children(node._id)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def jstree_build_from_node(node):
|
|
|
|
"""Give a node, traverse the tree bottom to top and expand the relevant
|
|
|
|
branches.
|
|
|
|
|
|
|
|
:param node: the base node, where tree building starts
|
|
|
|
"""
|
|
|
|
api = system_util.pillar_api()
|
|
|
|
# Parse the node and mark it as selected
|
|
|
|
child_node = jstree_parse_node(node)
|
|
|
|
child_node['state'] = dict(selected=True)
|
|
|
|
|
|
|
|
# Splice the specified child node between the other project children.
|
|
|
|
def select_node(x):
|
|
|
|
if x['id'] == child_node['id']:
|
|
|
|
return child_node
|
|
|
|
return x
|
|
|
|
|
|
|
|
# Get the parent node
|
|
|
|
parent = None
|
|
|
|
if node.parent:
|
|
|
|
try:
|
|
|
|
parent = Node.find(node.parent, {
|
|
|
|
'projection': {
|
|
|
|
'name': 1,
|
|
|
|
'node_type': 1,
|
|
|
|
'parent': 1,
|
|
|
|
'properties.content_type': 1,
|
|
|
|
}}, api=api)
|
|
|
|
# Define the child node of the tree (usually an asset)
|
|
|
|
except ResourceNotFound:
|
|
|
|
# If not found, we might be on the top level, in which case we skip the
|
|
|
|
# while loop and use child_node
|
|
|
|
pass
|
|
|
|
except ForbiddenAccess:
|
|
|
|
pass
|
|
|
|
|
|
|
|
while parent:
|
|
|
|
# Get the parent's parent
|
|
|
|
parent_parent = jstree_parse_node(parent)
|
|
|
|
# Get the parent's children (this will also include child_node)
|
|
|
|
parent_children = [select_node(x) for x in jstree_get_children(parent_parent['id'])]
|
|
|
|
parent_parent.pop('children', None)
|
|
|
|
# Overwrite children_node with the current parent
|
|
|
|
child_node = parent_parent
|
|
|
|
# Set the node to open so that jstree actually displays the nodes
|
|
|
|
child_node['state'] = dict(opened=True)
|
|
|
|
# Push in the computed children into the parent
|
|
|
|
child_node['children'] = parent_children
|
|
|
|
# If we have a parent
|
|
|
|
if parent.parent:
|
|
|
|
try:
|
|
|
|
parent = Node.find(parent.parent, {
|
|
|
|
'projection': {
|
|
|
|
'name': 1, 'parent': 1, 'project': 1, 'node_type': 1},
|
|
|
|
}, api=api)
|
|
|
|
except ResourceNotFound:
|
|
|
|
parent = None
|
|
|
|
else:
|
|
|
|
parent = None
|
|
|
|
# Get top level nodes for the project
|
|
|
|
project_children = jstree_get_children(None, node.project)
|
|
|
|
|
|
|
|
nodes_list = [select_node(x) for x in project_children]
|
|
|
|
return nodes_list
|