Merge branch 'projects'
This commit is contained in:
@@ -195,16 +195,16 @@ class ValidateCustomFields(Validator):
|
|||||||
return properties
|
return properties
|
||||||
|
|
||||||
def _validate_valid_properties(self, valid_properties, field, value):
|
def _validate_valid_properties(self, valid_properties, field, value):
|
||||||
node_types = app.data.driver.db['node_types']
|
projects_collection = app.data.driver.db['projects']
|
||||||
lookup = {}
|
lookup = {'_id': ObjectId(self.document['project'])}
|
||||||
lookup['_id'] = ObjectId(self.document['node_type'])
|
project = projects_collection.find_one(lookup)
|
||||||
node_type = node_types.find_one(lookup)
|
node_type = next(
|
||||||
|
(item for item in project['node_types'] if item.get('name') \
|
||||||
|
and item['name'] == self.document['node_type']), None)
|
||||||
try:
|
try:
|
||||||
value = self.convert_properties(value, node_type['dyn_schema'])
|
value = self.convert_properties(value, node_type['dyn_schema'])
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
print ("Error converting: {0}".format(e))
|
print ("Error converting: {0}".format(e))
|
||||||
#print (value)
|
|
||||||
|
|
||||||
v = Validator(node_type['dyn_schema'])
|
v = Validator(node_type['dyn_schema'])
|
||||||
val = v.validate(value)
|
val = v.validate(value)
|
||||||
@@ -309,7 +309,6 @@ def check_permissions(resource, method, append_allowed_methods=False):
|
|||||||
resource_permissions = resource['permissions']
|
resource_permissions = resource['permissions']
|
||||||
else:
|
else:
|
||||||
resource_permissions = None
|
resource_permissions = None
|
||||||
|
|
||||||
if 'node_type' in resource:
|
if 'node_type' in resource:
|
||||||
if type(resource['node_type']) is dict:
|
if type(resource['node_type']) is dict:
|
||||||
# If the node_type is embedded in the document, extract permissions
|
# If the node_type is embedded in the document, extract permissions
|
||||||
@@ -318,8 +317,18 @@ def check_permissions(resource, method, append_allowed_methods=False):
|
|||||||
else:
|
else:
|
||||||
# If the node_type is referenced with an ObjectID (was not embedded on
|
# If the node_type is referenced with an ObjectID (was not embedded on
|
||||||
# request) query for if from the database and get the permissions
|
# request) query for if from the database and get the permissions
|
||||||
node_types_collection = app.data.driver.db['node_types']
|
|
||||||
node_type = node_types_collection.find_one(resource['node_type'])
|
# node_types_collection = app.data.driver.db['node_types']
|
||||||
|
# node_type = node_types_collection.find_one(resource['node_type'])
|
||||||
|
|
||||||
|
if type(resource['project']) is dict:
|
||||||
|
project = resource['project']
|
||||||
|
else:
|
||||||
|
projects_collection = app.data.driver.db['projects']
|
||||||
|
project = projects_collection.find_one(resource['project'])
|
||||||
|
node_type = next(
|
||||||
|
(item for item in project['node_types'] if item.get('name') \
|
||||||
|
and item['name'] == resource['node_type']), None)
|
||||||
computed_permissions = node_type['permissions']
|
computed_permissions = node_type['permissions']
|
||||||
else:
|
else:
|
||||||
computed_permissions = None
|
computed_permissions = None
|
||||||
@@ -449,6 +458,8 @@ app.on_fetched_item_node_types += before_returning_item_permissions
|
|||||||
app.on_fetched_resource_node_types += before_returning_resource_permissions
|
app.on_fetched_resource_node_types += before_returning_resource_permissions
|
||||||
app.on_replace_nodes += before_replacing_node
|
app.on_replace_nodes += before_replacing_node
|
||||||
app.on_insert_nodes += before_inserting_nodes
|
app.on_insert_nodes += before_inserting_nodes
|
||||||
|
app.on_fetched_item_projects += before_returning_item_permissions
|
||||||
|
app.on_fetched_resource_projects += before_returning_resource_permissions
|
||||||
|
|
||||||
def post_GET_user(request, payload):
|
def post_GET_user(request, payload):
|
||||||
json_data = json.loads(payload.data)
|
json_data = json.loads(payload.data)
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
from __future__ import division
|
from __future__ import division
|
||||||
import os
|
import os
|
||||||
|
from bson.objectid import ObjectId
|
||||||
from eve.methods.put import put_internal
|
from eve.methods.put import put_internal
|
||||||
from eve.methods.post import post_internal
|
from eve.methods.post import post_internal
|
||||||
from flask.ext.script import Manager
|
from flask.ext.script import Manager
|
||||||
@@ -55,6 +56,8 @@ def put_item(collection, item):
|
|||||||
internal_fields = ['_id', '_etag', '_updated', '_created']
|
internal_fields = ['_id', '_etag', '_updated', '_created']
|
||||||
for field in internal_fields:
|
for field in internal_fields:
|
||||||
item.pop(field, None)
|
item.pop(field, None)
|
||||||
|
# print item
|
||||||
|
# print type(item_id)
|
||||||
p = put_internal(collection, item, **{'_id': item_id})
|
p = put_internal(collection, item, **{'_id': item_id})
|
||||||
if p[0]['_status'] == 'ERR':
|
if p[0]['_status'] == 'ERR':
|
||||||
print p
|
print p
|
||||||
@@ -224,7 +227,7 @@ def add_parent_to_nodes():
|
|||||||
"""Find the parent of any node in the nodes collection"""
|
"""Find the parent of any node in the nodes collection"""
|
||||||
import codecs
|
import codecs
|
||||||
import sys
|
import sys
|
||||||
from bson.objectid import ObjectId
|
|
||||||
UTF8Writer = codecs.getwriter('utf8')
|
UTF8Writer = codecs.getwriter('utf8')
|
||||||
sys.stdout = UTF8Writer(sys.stdout)
|
sys.stdout = UTF8Writer(sys.stdout)
|
||||||
|
|
||||||
@@ -320,7 +323,7 @@ def remove_children_files():
|
|||||||
@manager.command
|
@manager.command
|
||||||
def make_project_public(project_id):
|
def make_project_public(project_id):
|
||||||
"""Convert every node of a project from pending to public"""
|
"""Convert every node of a project from pending to public"""
|
||||||
from bson.objectid import ObjectId
|
|
||||||
DRY_RUN = False
|
DRY_RUN = False
|
||||||
nodes_collection = app.data.driver.db['nodes']
|
nodes_collection = app.data.driver.db['nodes']
|
||||||
for n in nodes_collection.find({'project': ObjectId(project_id)}):
|
for n in nodes_collection.find({'project': ObjectId(project_id)}):
|
||||||
@@ -405,11 +408,10 @@ def convert_assets_to_textures(project_id):
|
|||||||
if not DRY_RUN:
|
if not DRY_RUN:
|
||||||
p = post_internal('nodes', node)
|
p = post_internal('nodes', node)
|
||||||
if p[0]['_status'] == 'ERR':
|
if p[0]['_status'] == 'ERR':
|
||||||
print p
|
|
||||||
import pprint
|
import pprint
|
||||||
pprint.pprint(node)
|
pprint.pprint(node)
|
||||||
|
|
||||||
from bson.objectid import ObjectId
|
|
||||||
nodes_collection = app.data.driver.db['nodes']
|
nodes_collection = app.data.driver.db['nodes']
|
||||||
|
|
||||||
for n in nodes_collection.find({'project': ObjectId(project_id)}):
|
for n in nodes_collection.find({'project': ObjectId(project_id)}):
|
||||||
@@ -494,5 +496,57 @@ def files_verify_project():
|
|||||||
print i
|
print i
|
||||||
print "==="
|
print "==="
|
||||||
|
|
||||||
|
|
||||||
|
def replace_node_type(project, node_type_name, new_node_type):
|
||||||
|
"""Update or create the specified node type. We rely on the fact that
|
||||||
|
node_types have a unique name in a project.
|
||||||
|
"""
|
||||||
|
|
||||||
|
old_node_type = next(
|
||||||
|
(item for item in project['node_types'] if item.get('name') \
|
||||||
|
and item['name'] == node_type_name), None)
|
||||||
|
if old_node_type:
|
||||||
|
for i, v in enumerate(project['node_types']):
|
||||||
|
if v['name'] == node_type_name:
|
||||||
|
project['node_types'][i] = new_node_type
|
||||||
|
else:
|
||||||
|
project['node_types'].append(new_node_type)
|
||||||
|
|
||||||
|
|
||||||
|
@manager.command
|
||||||
|
def project_upgrade_node_types(project_id):
|
||||||
|
projects_collection = app.data.driver.db['projects']
|
||||||
|
project = projects_collection.find_one({'_id': ObjectId(project_id)})
|
||||||
|
replace_node_type(project, 'group', node_type_group)
|
||||||
|
replace_node_type(project, 'asset', node_type_asset)
|
||||||
|
replace_node_type(project, 'storage', node_type_storage)
|
||||||
|
replace_node_type(project, 'comment', node_type_comment)
|
||||||
|
replace_node_type(project, 'blog', node_type_blog)
|
||||||
|
replace_node_type(project, 'post', node_type_post)
|
||||||
|
replace_node_type(project, 'texture', node_type_texture)
|
||||||
|
put_item('projects', project)
|
||||||
|
|
||||||
|
|
||||||
|
@manager.command
|
||||||
|
def test_put_item(node_id):
|
||||||
|
import pprint
|
||||||
|
nodes_collection = app.data.driver.db['nodes']
|
||||||
|
node = nodes_collection.find_one(ObjectId(node_id))
|
||||||
|
pprint.pprint(node)
|
||||||
|
put_item('nodes', node)
|
||||||
|
|
||||||
|
|
||||||
|
@manager.command
|
||||||
|
def test_post_internal(node_id):
|
||||||
|
import pprint
|
||||||
|
nodes_collection = app.data.driver.db['nodes']
|
||||||
|
node = nodes_collection.find_one(ObjectId(node_id))
|
||||||
|
internal_fields = ['_id', '_etag', '_updated', '_created']
|
||||||
|
for field in internal_fields:
|
||||||
|
node.pop(field, None)
|
||||||
|
pprint.pprint(node)
|
||||||
|
print post_internal('nodes', node)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
manager.run()
|
manager.run()
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
node_type_act = {
|
node_type_act = {
|
||||||
'name': 'act',
|
'name': 'act',
|
||||||
'description': 'Act node type',
|
'description': 'Act node type',
|
||||||
'parent': {}
|
'parent': []
|
||||||
}
|
}
|
||||||
|
@@ -5,9 +5,7 @@ node_type_asset = {
|
|||||||
'description': 'Basic Asset Type',
|
'description': 'Basic Asset Type',
|
||||||
# This data type does not have parent limitations (can be child
|
# This data type does not have parent limitations (can be child
|
||||||
# of any node). An empty parent declaration is required.
|
# of any node). An empty parent declaration is required.
|
||||||
'parent': {
|
'parent': ['group',],
|
||||||
"node_types": ["group",]
|
|
||||||
},
|
|
||||||
'dyn_schema': {
|
'dyn_schema': {
|
||||||
'status': {
|
'status': {
|
||||||
'type': 'string',
|
'type': 'string',
|
||||||
|
@@ -17,9 +17,7 @@ node_type_blog = {
|
|||||||
'categories': {},
|
'categories': {},
|
||||||
'template': {},
|
'template': {},
|
||||||
},
|
},
|
||||||
'parent': {
|
'parent': ['project',],
|
||||||
'node_types': ['project',]
|
|
||||||
},
|
|
||||||
'permissions': {
|
'permissions': {
|
||||||
# 'groups': [{
|
# 'groups': [{
|
||||||
# 'group': app.config['ADMIN_USER_GROUP'],
|
# 'group': app.config['ADMIN_USER_GROUP'],
|
||||||
|
@@ -60,9 +60,7 @@ node_type_comment = {
|
|||||||
'confidence': {},
|
'confidence': {},
|
||||||
'is_reply': {}
|
'is_reply': {}
|
||||||
},
|
},
|
||||||
'parent': {
|
'parent': ['asset', 'comment'],
|
||||||
'node_types': ['asset', 'comment']
|
|
||||||
},
|
|
||||||
'permissions': {
|
'permissions': {
|
||||||
# 'groups': [{
|
# 'groups': [{
|
||||||
# 'group': app.config['ADMIN_USER_GROUP'],
|
# 'group': app.config['ADMIN_USER_GROUP'],
|
||||||
|
@@ -1,9 +1,7 @@
|
|||||||
node_type_group = {
|
node_type_group = {
|
||||||
'name': 'group',
|
'name': 'group',
|
||||||
'description': 'Generic group node type',
|
'description': 'Generic group node type edited',
|
||||||
'parent': {
|
'parent': ['group', 'project'],
|
||||||
'node_types': ['group', 'project']
|
|
||||||
},
|
|
||||||
'dyn_schema': {
|
'dyn_schema': {
|
||||||
# Used for sorting within the context of a group
|
# Used for sorting within the context of a group
|
||||||
'order': {
|
'order': {
|
||||||
|
@@ -1,9 +1,7 @@
|
|||||||
node_type_group_texture = {
|
node_type_group_texture = {
|
||||||
'name': 'group_texture',
|
'name': 'group_texture',
|
||||||
'description': 'Group for texture node type',
|
'description': 'Group for texture node type',
|
||||||
'parent': {
|
'parent': ['group_texture', 'project'],
|
||||||
'node_types': ['group_texture', 'project']
|
|
||||||
},
|
|
||||||
'dyn_schema': {
|
'dyn_schema': {
|
||||||
# Used for sorting within the context of a group
|
# Used for sorting within the context of a group
|
||||||
'order': {
|
'order': {
|
||||||
|
@@ -55,9 +55,7 @@ node_type_post = {
|
|||||||
'url': {},
|
'url': {},
|
||||||
'attachments': {'visible': False},
|
'attachments': {'visible': False},
|
||||||
},
|
},
|
||||||
'parent': {
|
'parent': ['blog',],
|
||||||
'node_types': ['blog',]
|
|
||||||
},
|
|
||||||
'permissions': {
|
'permissions': {
|
||||||
# 'groups': [{
|
# 'groups': [{
|
||||||
# 'group': app.config['ADMIN_USER_GROUP'],
|
# 'group': app.config['ADMIN_USER_GROUP'],
|
||||||
|
@@ -1,7 +1,5 @@
|
|||||||
node_type_scene = {
|
node_type_scene = {
|
||||||
'name': 'scene',
|
'name': 'scene',
|
||||||
'description': 'Scene node type',
|
'description': 'Scene node type',
|
||||||
'parent': {
|
'parent': ['act'],
|
||||||
"node_types": ["act"]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -41,7 +41,5 @@ node_type_shot = {
|
|||||||
'notes': {},
|
'notes': {},
|
||||||
'shot_group': {}
|
'shot_group': {}
|
||||||
},
|
},
|
||||||
'parent': {
|
'parent': ['scene']
|
||||||
'node_types': ['scene']
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -26,9 +26,7 @@ node_type_storage = {
|
|||||||
'project': {},
|
'project': {},
|
||||||
'backend': {}
|
'backend': {}
|
||||||
},
|
},
|
||||||
'parent': {
|
'parent': ['group', 'project'],
|
||||||
"node_types": ["group", "project"]
|
|
||||||
},
|
|
||||||
'permissions': {
|
'permissions': {
|
||||||
# 'groups': [{
|
# 'groups': [{
|
||||||
# 'group': app.config['ADMIN_USER_GROUP'],
|
# 'group': app.config['ADMIN_USER_GROUP'],
|
||||||
|
@@ -103,7 +103,5 @@ node_type_task = {
|
|||||||
'is_open': {},
|
'is_open': {},
|
||||||
'is_processing': {},
|
'is_processing': {},
|
||||||
},
|
},
|
||||||
'parent': {
|
'parent': ['shot']
|
||||||
'node_types': ['shot'],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -5,9 +5,7 @@ node_type_texture = {
|
|||||||
'description': 'Image Texture',
|
'description': 'Image Texture',
|
||||||
# This data type does not have parent limitations (can be child
|
# This data type does not have parent limitations (can be child
|
||||||
# of any node). An empty parent declaration is required.
|
# of any node). An empty parent declaration is required.
|
||||||
'parent': {
|
'parent': ['group',],
|
||||||
"node_types": ["group",]
|
|
||||||
},
|
|
||||||
'dyn_schema': {
|
'dyn_schema': {
|
||||||
'status': {
|
'status': {
|
||||||
'type': 'string',
|
'type': 'string',
|
||||||
|
@@ -11,6 +11,15 @@ ITEM_METHODS = ['GET', 'PUT', 'DELETE', 'PATCH']
|
|||||||
|
|
||||||
PAGINATION_LIMIT = 25
|
PAGINATION_LIMIT = 25
|
||||||
|
|
||||||
|
_file_embedded_schema = {
|
||||||
|
'type': 'objectid',
|
||||||
|
'data_relation': {
|
||||||
|
'resource': 'files',
|
||||||
|
'field': '_id',
|
||||||
|
'embeddable': True
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
users_schema = {
|
users_schema = {
|
||||||
'full_name': {
|
'full_name': {
|
||||||
@@ -258,7 +267,7 @@ nodes_schema = {
|
|||||||
'project': {
|
'project': {
|
||||||
'type': 'objectid',
|
'type': 'objectid',
|
||||||
'data_relation': {
|
'data_relation': {
|
||||||
'resource': 'nodes',
|
'resource': 'projects',
|
||||||
'field': '_id',
|
'field': '_id',
|
||||||
'embeddable': True
|
'embeddable': True
|
||||||
},
|
},
|
||||||
@@ -273,13 +282,8 @@ nodes_schema = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
'node_type': {
|
'node_type': {
|
||||||
'type': 'objectid',
|
'type': 'string',
|
||||||
'required': True,
|
'required': True
|
||||||
'data_relation': {
|
|
||||||
'resource': 'node_types',
|
|
||||||
'field': '_id',
|
|
||||||
'embeddable': True
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
'properties': {
|
'properties': {
|
||||||
'type' : 'dict',
|
'type' : 'dict',
|
||||||
@@ -502,6 +506,151 @@ groups_schema = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
projects_schema = {
|
||||||
|
'name': {
|
||||||
|
'type': 'string',
|
||||||
|
'minlength': 1,
|
||||||
|
'maxlength': 128,
|
||||||
|
'required': True,
|
||||||
|
},
|
||||||
|
'description': {
|
||||||
|
'type': 'string',
|
||||||
|
},
|
||||||
|
# Short summary for the project
|
||||||
|
'summary': {
|
||||||
|
'type': 'string',
|
||||||
|
'maxlength': 128
|
||||||
|
},
|
||||||
|
# Logo
|
||||||
|
'picture_square': _file_embedded_schema,
|
||||||
|
# Header
|
||||||
|
'picture_header': _file_embedded_schema,
|
||||||
|
'user': {
|
||||||
|
'type': 'objectid',
|
||||||
|
'required': True,
|
||||||
|
'data_relation': {
|
||||||
|
'resource': 'users',
|
||||||
|
'field': '_id',
|
||||||
|
'embeddable': True
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'category': {
|
||||||
|
'type': 'string',
|
||||||
|
'allowed': [
|
||||||
|
'training',
|
||||||
|
'film',
|
||||||
|
'assets',
|
||||||
|
'software',
|
||||||
|
'game'
|
||||||
|
],
|
||||||
|
'required': True,
|
||||||
|
},
|
||||||
|
'is_private': {
|
||||||
|
'type': 'boolean'
|
||||||
|
},
|
||||||
|
'url': {
|
||||||
|
'type': 'string'
|
||||||
|
},
|
||||||
|
'organization': {
|
||||||
|
'type': 'objectid',
|
||||||
|
'nullable': True,
|
||||||
|
'data_relation': {
|
||||||
|
'resource': 'organizations',
|
||||||
|
'field': '_id',
|
||||||
|
'embeddable': True
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'owners': {
|
||||||
|
'type': 'dict',
|
||||||
|
'schema': {
|
||||||
|
'users': {
|
||||||
|
'type': 'list',
|
||||||
|
'schema': {
|
||||||
|
'type': 'objectid',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'groups': {
|
||||||
|
'type': 'list',
|
||||||
|
'schema': {
|
||||||
|
'type': 'objectid',
|
||||||
|
'data_relation': {
|
||||||
|
'resource': 'groups',
|
||||||
|
'field': '_id',
|
||||||
|
'embeddable': True
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'status': {
|
||||||
|
'type': 'string',
|
||||||
|
'allowed': [
|
||||||
|
'published',
|
||||||
|
'pending',
|
||||||
|
'deleted'
|
||||||
|
],
|
||||||
|
},
|
||||||
|
# Latest nodes being edited
|
||||||
|
'nodes_latest': {
|
||||||
|
'type': 'list',
|
||||||
|
'schema': {
|
||||||
|
'type': 'objectid',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
# Featured nodes, manually added
|
||||||
|
'nodes_featured': {
|
||||||
|
'type': 'list',
|
||||||
|
'schema': {
|
||||||
|
'type': 'objectid',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
# Latest blog posts, manually added
|
||||||
|
'nodes_blog': {
|
||||||
|
'type': 'list',
|
||||||
|
'schema': {
|
||||||
|
'type': 'objectid',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
# Where Node type schemas for every projects are defined
|
||||||
|
'node_types': {
|
||||||
|
'type': 'list',
|
||||||
|
'schema': {
|
||||||
|
'type': 'dict',
|
||||||
|
'schema': {
|
||||||
|
# URL is the way we identify a node_type when calling it via
|
||||||
|
# the helper methods in the Project API.
|
||||||
|
'url': {'type': 'string'},
|
||||||
|
'name': {'type': 'string'},
|
||||||
|
'description': {'type': 'string'},
|
||||||
|
# Allowed parents for the node_type
|
||||||
|
'parent': {
|
||||||
|
'type': 'list',
|
||||||
|
'schema': {
|
||||||
|
'type': 'string'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'dyn_schema': {
|
||||||
|
'type': 'dict',
|
||||||
|
'allow_unknown': True
|
||||||
|
},
|
||||||
|
'form_schema': {
|
||||||
|
'type': 'dict',
|
||||||
|
'allow_unknown': True
|
||||||
|
},
|
||||||
|
'permissions': {
|
||||||
|
'type': 'dict',
|
||||||
|
'schema': permissions_embedded_schema
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'permissions': {
|
||||||
|
'type': 'dict',
|
||||||
|
'schema': permissions_embedded_schema
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nodes = {
|
nodes = {
|
||||||
'schema': nodes_schema,
|
'schema': nodes_schema,
|
||||||
'public_methods': ['GET'],
|
'public_methods': ['GET'],
|
||||||
@@ -559,6 +708,12 @@ organizations = {
|
|||||||
'public_methods': ['GET']
|
'public_methods': ['GET']
|
||||||
}
|
}
|
||||||
|
|
||||||
|
projects = {
|
||||||
|
'schema': projects_schema,
|
||||||
|
'public_item_methods': ['GET'],
|
||||||
|
'public_methods': ['GET']
|
||||||
|
}
|
||||||
|
|
||||||
DOMAIN = {
|
DOMAIN = {
|
||||||
'users': users,
|
'users': users,
|
||||||
'nodes': nodes,
|
'nodes': nodes,
|
||||||
@@ -566,7 +721,8 @@ DOMAIN = {
|
|||||||
'tokens': tokens,
|
'tokens': tokens,
|
||||||
'files': files,
|
'files': files,
|
||||||
'groups': groups,
|
'groups': groups,
|
||||||
'organizations': organizations
|
'organizations': organizations,
|
||||||
|
'projects': projects
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user