Moved Attract stuff to Attract-Server project
This commit is contained in:
@@ -1 +0,0 @@
|
|||||||
"""Blender Cloud server."""
|
|
@@ -1,105 +0,0 @@
|
|||||||
"""Commandline interface for Attract."""
|
|
||||||
|
|
||||||
from __future__ import print_function, division
|
|
||||||
|
|
||||||
import copy
|
|
||||||
import logging
|
|
||||||
|
|
||||||
from bson import ObjectId
|
|
||||||
from eve.methods.put import put_internal
|
|
||||||
from flask import current_app
|
|
||||||
from pillar.cli import manager
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
def _get_project(project_url):
|
|
||||||
"""Find a project in the database, or SystemExit()s.
|
|
||||||
|
|
||||||
:param project_url: UUID of the project
|
|
||||||
:type: str
|
|
||||||
:return: the project
|
|
||||||
:rtype: dict
|
|
||||||
"""
|
|
||||||
|
|
||||||
projects_collection = current_app.data.driver.db['projects']
|
|
||||||
|
|
||||||
# Find the project in the database.
|
|
||||||
project = projects_collection.find_one({'url': project_url})
|
|
||||||
if not project:
|
|
||||||
log.error('Project %s does not exist.', project_url)
|
|
||||||
raise SystemExit()
|
|
||||||
|
|
||||||
return project
|
|
||||||
|
|
||||||
|
|
||||||
def _update_project(project):
|
|
||||||
"""Updates a project in the database, or SystemExit()s.
|
|
||||||
|
|
||||||
:param project: the project data, should be the entire project document
|
|
||||||
:type: dict
|
|
||||||
:return: the project
|
|
||||||
:rtype: dict
|
|
||||||
"""
|
|
||||||
|
|
||||||
from pillar.api.utils import remove_private_keys
|
|
||||||
from pillar.api.utils import authentication
|
|
||||||
|
|
||||||
authentication.force_cli_user()
|
|
||||||
|
|
||||||
project_id = ObjectId(project['_id'])
|
|
||||||
project = remove_private_keys(project)
|
|
||||||
result, _, _, status_code = put_internal('projects', project, _id=project_id)
|
|
||||||
|
|
||||||
if status_code != 200:
|
|
||||||
log.error("Can't update project %s, issues: %s", project_id, result)
|
|
||||||
raise SystemExit()
|
|
||||||
|
|
||||||
|
|
||||||
@manager.command
|
|
||||||
@manager.option('-r', '--replace', dest='replace', action='store_true', default=False)
|
|
||||||
def setup_for_attract(project_url, replace=False):
|
|
||||||
"""Adds Attract node types to the project.
|
|
||||||
|
|
||||||
Use --replace to replace pre-existing Attract node types
|
|
||||||
(by default already existing Attract node types are skipped).
|
|
||||||
"""
|
|
||||||
|
|
||||||
from .node_types import NODE_TYPES
|
|
||||||
|
|
||||||
# Copy permissions from the project, then give everyone with PUT
|
|
||||||
# access also DELETE access.
|
|
||||||
project = _get_project(project_url)
|
|
||||||
permissions = copy.deepcopy(project['permissions'])
|
|
||||||
|
|
||||||
for perms in permissions.values():
|
|
||||||
for perm in perms:
|
|
||||||
methods = set(perm['methods'])
|
|
||||||
if 'PUT' not in perm['methods']:
|
|
||||||
continue
|
|
||||||
methods.add('DELETE')
|
|
||||||
perm['methods'] = list(methods)
|
|
||||||
|
|
||||||
# Make a copy of the node types when setting the permissions, as
|
|
||||||
# we don't want to mutate the global node type objects.
|
|
||||||
node_types = (dict(permissions=permissions, **nt) for nt in NODE_TYPES)
|
|
||||||
|
|
||||||
# Add the missing node types.
|
|
||||||
for node_type in node_types:
|
|
||||||
found = [nt for nt in project['node_types']
|
|
||||||
if nt['name'] == node_type['name']]
|
|
||||||
if found:
|
|
||||||
assert len(found) == 1, 'node type name should be unique (found %ix)' % len(found)
|
|
||||||
|
|
||||||
# TODO: validate that the node type contains all the properties Attract needs.
|
|
||||||
if replace:
|
|
||||||
log.info('Replacing existing node type %s', node_type['name'])
|
|
||||||
project['node_types'].remove(found[0])
|
|
||||||
else:
|
|
||||||
continue
|
|
||||||
|
|
||||||
project['node_types'].append(node_type)
|
|
||||||
|
|
||||||
_update_project(project)
|
|
||||||
|
|
||||||
log.info('Project %s was updated for Attract.', project_url)
|
|
@@ -1,43 +0,0 @@
|
|||||||
"""Pillar extension for Attract."""
|
|
||||||
|
|
||||||
from pillar.extension import PillarExtension
|
|
||||||
|
|
||||||
|
|
||||||
class AttractExtension(PillarExtension):
|
|
||||||
@property
|
|
||||||
def name(self):
|
|
||||||
return u'Attract'
|
|
||||||
|
|
||||||
def flask_config(self):
|
|
||||||
"""Returns extension-specific defaults for the Flask configuration.
|
|
||||||
|
|
||||||
Use this to set sensible default values for configuration settings
|
|
||||||
introduced by the extension.
|
|
||||||
|
|
||||||
:rtype: dict
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Just so that it registers the management commands.
|
|
||||||
from . import cli
|
|
||||||
|
|
||||||
return {}
|
|
||||||
|
|
||||||
def blueprints(self):
|
|
||||||
"""Returns the list of top-level blueprints for the extension.
|
|
||||||
|
|
||||||
These blueprints will be mounted at the url prefix given to
|
|
||||||
app.load_extension().
|
|
||||||
|
|
||||||
:rtype: list of flask.Blueprint objects.
|
|
||||||
"""
|
|
||||||
return []
|
|
||||||
|
|
||||||
def eve_settings(self):
|
|
||||||
"""Returns extensions to the Eve settings.
|
|
||||||
|
|
||||||
Currently only the DOMAIN key is used to insert new resources into
|
|
||||||
Eve's configuration.
|
|
||||||
|
|
||||||
:rtype: dict
|
|
||||||
"""
|
|
||||||
return {}
|
|
@@ -1,7 +0,0 @@
|
|||||||
from .act import node_type_act
|
|
||||||
from .scene import node_type_scene
|
|
||||||
from .shot import node_type_shot
|
|
||||||
from .task import node_type_task
|
|
||||||
|
|
||||||
NODE_TYPES = (node_type_act, node_type_scene, node_type_shot, node_type_task)
|
|
||||||
|
|
@@ -1,5 +0,0 @@
|
|||||||
node_type_act = {
|
|
||||||
'name': 'act',
|
|
||||||
'description': 'Act node type',
|
|
||||||
'parent': []
|
|
||||||
}
|
|
@@ -1,5 +0,0 @@
|
|||||||
node_type_scene = {
|
|
||||||
'name': 'scene',
|
|
||||||
'description': 'Scene node type',
|
|
||||||
'parent': ['act'],
|
|
||||||
}
|
|
@@ -1,45 +0,0 @@
|
|||||||
node_type_shot = {
|
|
||||||
'name': 'shot',
|
|
||||||
'description': 'Shot Node Type, for shots',
|
|
||||||
'dyn_schema': {
|
|
||||||
'url': {
|
|
||||||
'type': 'string',
|
|
||||||
},
|
|
||||||
'cut_in': {
|
|
||||||
'type': 'integer'
|
|
||||||
},
|
|
||||||
'cut_out': {
|
|
||||||
'type': 'integer'
|
|
||||||
},
|
|
||||||
'status': {
|
|
||||||
'type': 'string',
|
|
||||||
'allowed': [
|
|
||||||
'on_hold',
|
|
||||||
'todo',
|
|
||||||
'in_progress',
|
|
||||||
'review',
|
|
||||||
'final'
|
|
||||||
],
|
|
||||||
},
|
|
||||||
'notes': {
|
|
||||||
'type': 'string',
|
|
||||||
'maxlength': 256,
|
|
||||||
},
|
|
||||||
'shot_group': {
|
|
||||||
'type': 'string',
|
|
||||||
#'data_relation': {
|
|
||||||
# 'resource': 'nodes',
|
|
||||||
# 'field': '_id',
|
|
||||||
#},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'form_schema': {
|
|
||||||
'url': {},
|
|
||||||
'cut_in': {},
|
|
||||||
'cut_out': {},
|
|
||||||
'status': {},
|
|
||||||
'notes': {},
|
|
||||||
'shot_group': {}
|
|
||||||
},
|
|
||||||
'parent': ['scene']
|
|
||||||
}
|
|
@@ -1,107 +0,0 @@
|
|||||||
node_type_task = {
|
|
||||||
'name': 'task',
|
|
||||||
'description': 'Task Node Type, for tasks',
|
|
||||||
'dyn_schema': {
|
|
||||||
'status': {
|
|
||||||
'type': 'string',
|
|
||||||
'allowed': [
|
|
||||||
'todo',
|
|
||||||
'in_progress',
|
|
||||||
'on_hold',
|
|
||||||
'approved',
|
|
||||||
'cbb',
|
|
||||||
'final',
|
|
||||||
'review'
|
|
||||||
],
|
|
||||||
'required': True,
|
|
||||||
},
|
|
||||||
'filepath': {
|
|
||||||
'type': 'string',
|
|
||||||
},
|
|
||||||
'revision': {
|
|
||||||
'type': 'integer',
|
|
||||||
},
|
|
||||||
'owners': {
|
|
||||||
'type': 'dict',
|
|
||||||
'schema': {
|
|
||||||
'users': {
|
|
||||||
'type': 'list',
|
|
||||||
'schema': {
|
|
||||||
'type': 'objectid',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'groups': {
|
|
||||||
'type': 'list',
|
|
||||||
'schema': {
|
|
||||||
'type': 'objectid',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'time': {
|
|
||||||
'type': 'dict',
|
|
||||||
'schema': {
|
|
||||||
'start': {
|
|
||||||
'type': 'datetime'
|
|
||||||
},
|
|
||||||
'duration': {
|
|
||||||
'type': 'integer'
|
|
||||||
},
|
|
||||||
'chunks': {
|
|
||||||
'type': 'list',
|
|
||||||
'schema': {
|
|
||||||
'type': 'dict',
|
|
||||||
'schema': {
|
|
||||||
'start': {
|
|
||||||
'type': 'datetime',
|
|
||||||
},
|
|
||||||
'duration': {
|
|
||||||
'type': 'integer',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'is_conflicting' : {
|
|
||||||
'type': 'boolean'
|
|
||||||
},
|
|
||||||
'is_processing' : {
|
|
||||||
'type': 'boolean'
|
|
||||||
},
|
|
||||||
'is_open' : {
|
|
||||||
'type': 'boolean'
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
'form_schema': {
|
|
||||||
'status': {},
|
|
||||||
'filepath': {},
|
|
||||||
'revision': {},
|
|
||||||
'owners': {
|
|
||||||
'schema': {
|
|
||||||
'users':{
|
|
||||||
'items': [('User', 'first_name')],
|
|
||||||
},
|
|
||||||
'groups': {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'time': {
|
|
||||||
'schema': {
|
|
||||||
'start': {},
|
|
||||||
'duration': {},
|
|
||||||
'chunks': {
|
|
||||||
'visible': False,
|
|
||||||
'schema': {
|
|
||||||
'start': {},
|
|
||||||
'duration': {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'is_conflicting': {},
|
|
||||||
'is_open': {},
|
|
||||||
'is_processing': {},
|
|
||||||
},
|
|
||||||
'parent': ['shot']
|
|
||||||
}
|
|
2
cloud.py
2
cloud.py
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
from pillar import PillarServer
|
from pillar import PillarServer
|
||||||
from bcloud.attract.extension import AttractExtension
|
from attract_server import AttractExtension
|
||||||
|
|
||||||
attract = AttractExtension()
|
attract = AttractExtension()
|
||||||
|
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
# Primary requirements
|
# Primary requirements
|
||||||
pillar
|
pillar
|
||||||
|
attract_server
|
||||||
|
pillarsdk
|
||||||
|
|
||||||
# Secondary requirements (i.e. pulled in from primary requirements)
|
# Secondary requirements (i.e. pulled in from primary requirements)
|
||||||
algoliasearch==1.8.0
|
algoliasearch==1.8.0
|
||||||
@@ -47,6 +49,7 @@ requests-oauthlib==0.6.2
|
|||||||
rsa==3.3
|
rsa==3.3
|
||||||
simplejson==3.8.2
|
simplejson==3.8.2
|
||||||
six==1.10.0
|
six==1.10.0
|
||||||
|
svn==0.3.42
|
||||||
WebOb==1.5.0
|
WebOb==1.5.0
|
||||||
Werkzeug==0.11.3
|
Werkzeug==0.11.3
|
||||||
WTForms==2.1
|
WTForms==2.1
|
||||||
|
Reference in New Issue
Block a user