From b75482b0d63759b34b1f4bc451a0077101e32914 Mon Sep 17 00:00:00 2001 From: Francesco Siddi Date: Mon, 31 Aug 2015 17:45:29 +0200 Subject: [PATCH] Work in progress with users and organizations --- attract/application/__init__.py | 6 +- attract/manage.py | 386 ++++++++++++++++++++++---------- attract/settings.py | 106 ++++++++- docker/attract-db/Dockerfile | 27 ++- 4 files changed, 401 insertions(+), 124 deletions(-) diff --git a/attract/application/__init__.py b/attract/application/__init__.py index 9daf25ff..3e4f55eb 100644 --- a/attract/application/__init__.py +++ b/attract/application/__init__.py @@ -182,7 +182,11 @@ def convert_properties(properties, node_schema): properties[prop] = datetime.strptime(prop_val, RFC1123_DATE_FORMAT) elif prop_type == 'objectid': prop_val = properties[prop] - properties[prop] = ObjectId(prop_val) + if prop_val: + properties[prop] = ObjectId(prop_val) + else: + properties[prop] = None + return properties diff --git a/attract/manage.py b/attract/manage.py index 845e5a18..1c127dae 100644 --- a/attract/manage.py +++ b/attract/manage.py @@ -247,160 +247,160 @@ def populate_db_test(): def populate_node_types(old_ids={}): shot_node_type = { - "name": "shot", - "description": "Shot Node Type, for shots", - "dyn_schema": { - "url": { - "type": "string", + 'name': 'shot', + 'description': 'Shot Node Type, for shots', + 'dyn_schema': { + 'url': { + 'type': 'string', }, - "cut_in": { - "type": "integer" + 'cut_in': { + 'type': 'integer' }, - "cut_out": { - "type": "integer" + 'cut_out': { + 'type': 'integer' }, - "status": { - "type": "string", - "allowed": [ - "on_hold", - "todo", - "in_progress", - "review", - "final" + 'status': { + 'type': 'string', + 'allowed': [ + 'on_hold', + 'todo', + 'in_progress', + 'review', + 'final' ], }, - "notes": { - "type": "string", - "maxlength": 256, + 'notes': { + 'type': 'string', + 'maxlength': 256, }, - "shot_group": { - "type": "string", - #"data_relation": { - # "resource": "nodes", - # "field": "_id", + 'shot_group': { + 'type': 'string', + #'data_relation': { + # 'resource': 'nodes', + # 'field': '_id', #}, }, }, - "form_schema": { - "url": {}, - "cut_in": {}, - "cut_out": {}, - "status": {}, - "notes": {}, - "shot_group": {} + 'form_schema': { + 'url': {}, + 'cut_in': {}, + 'cut_out': {}, + 'status': {}, + 'notes': {}, + 'shot_group': {} }, - "parent": { - "node_types": ["scene"] + 'parent': { + 'node_types': ['scene'] } } task_node_type = { - "name": "task", - "description": "Task Node Type, for tasks", - "dyn_schema": { - "status": { - "type": "string", - "allowed": [ - "todo", - "in_progress", - "on_hold", - "approved", - "cbb", - "final", - "review" + '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, + 'required': True, }, - "filepath": { - "type": "string", + 'filepath': { + 'type': 'string', }, - "revision": { - "type": "integer", + 'revision': { + 'type': 'integer', }, - "owners": { - "type": "dict", - "schema": { - "users": { - "type": "list", - "schema": { - "type": "objectid", + 'owners': { + 'type': 'dict', + 'schema': { + 'users': { + 'type': 'list', + 'schema': { + 'type': 'objectid', } }, - "groups": { - "type": "list", - "schema": { - "type": "objectid", + 'groups': { + 'type': 'list', + 'schema': { + 'type': 'objectid', } } } }, - "time": { - "type": "dict", - "schema": { - "start": { - "type": "datetime" + 'time': { + 'type': 'dict', + 'schema': { + 'start': { + 'type': 'datetime' }, - "duration": { - "type": "integer" + 'duration': { + 'type': 'integer' }, - "chunks": { - "type": "list", - "schema": { - "type": "dict", - "schema": { - "start": { - "type": "datetime", + 'chunks': { + 'type': 'list', + 'schema': { + 'type': 'dict', + 'schema': { + 'start': { + 'type': 'datetime', }, - "duration": { - "type": "integer", + 'duration': { + 'type': 'integer', } } } }, } }, - "is_conflicting" : { - "type": "boolean" + 'is_conflicting' : { + 'type': 'boolean' }, - "is_processing" : { - "type": "boolean" + 'is_processing' : { + 'type': 'boolean' }, - "is_open" : { - "type": "boolean" + 'is_open' : { + 'type': 'boolean' } }, - "form_schema": { - "status": {}, - "filepath": {}, - "revision": {}, - "owners": { - "schema": { - "users":{ - "items": [('User', 'first_name')], + 'form_schema': { + 'status': {}, + 'filepath': {}, + 'revision': {}, + 'owners': { + 'schema': { + 'users':{ + 'items': [('User', 'first_name')], }, - "groups": {} + 'groups': {} } }, - "time": { - "schema": { - "start": {}, - "duration": {}, - "chunks": { - "visible": False, - "schema": { - "start": {}, - "duration": {} + 'time': { + 'schema': { + 'start': {}, + 'duration': {}, + 'chunks': { + 'visible': False, + 'schema': { + 'start': {}, + 'duration': {} } } } }, - "is_conflicting": {}, - "is_open": {}, - "is_processing": {}, + 'is_conflicting': {}, + 'is_open': {}, + 'is_processing': {}, }, - "parent": { - "node_types": ["shot"], + 'parent': { + 'node_types': ['shot'], } } @@ -465,6 +465,127 @@ def populate_node_types(old_ids={}): } } + project_node_type = { + 'name': 'project', + 'parent': {}, + 'description': 'The official project type', + 'dyn_schema': { + 'category': { + 'type': 'string', + 'allowed': [ + '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 + } + } + } + } + }, + # Logo + 'picture_1': { + 'type': 'objectid', + 'nullable': True, + 'data_relation': { + 'resource': 'files', + 'field': '_id', + 'embeddable': True + }, + }, + # Header + 'picture_2': { + 'type': 'objectid', + 'nullable': True, + 'data_relation': { + 'resource': 'files', + 'field': '_id', + 'embeddable': True + }, + }, + }, + 'form_schema': { + 'is_private': {}, + # TODO add group parsing + 'category': {}, + 'url': {}, + 'organization': {}, + 'picture_1': {}, + 'picture_2': {}, + 'owners': { + 'schema': { + 'users':{ + 'items': [('User', 'first_name')], + }, + 'groups': { + 'items': [('Group', 'name')], + }, + } + }, + }, + } + + group_node_type = { + 'name': 'group', + 'description': 'Generic group node type', + 'dyn_schema': { + 'url': { + 'type': 'string', + }, + 'status': { + 'type': 'string', + 'allowed': [ + 'published', + 'pending' + ], + }, + 'notes': { + 'type': 'string', + 'maxlength': 256, + }, + 'parent': {} + }, + 'form_schema': { + 'url': {}, + 'status': {}, + 'notes': {}, + }, + } + from pymongo import MongoClient client = MongoClient() @@ -489,13 +610,52 @@ def populate_node_types(old_ids={}): # Insert new node_type db.node_types.insert(node_type) else: + print("Making the node") + print node_type post_item('node_types', node_type) - upgrade(shot_node_type, old_ids) - upgrade(task_node_type, old_ids) - upgrade(scene_node_type, old_ids) - upgrade(act_node_type, old_ids) - upgrade(comment_node_type, old_ids) + # upgrade(shot_node_type, old_ids) + # upgrade(task_node_type, old_ids) + # upgrade(scene_node_type, old_ids) + # upgrade(act_node_type, old_ids) + # upgrade(comment_node_type, old_ids) + upgrade(project_node_type, old_ids) + + +@manager.command +def migrate_custom(): + from pymongo import MongoClient + + client = MongoClient() + db = client.eve + + group_node_type = { + 'name': 'group', + 'description': 'Generic group node type', + 'dyn_schema': { + 'url': { + 'type': 'string', + }, + 'status': { + 'type': 'string', + 'allowed': [ + 'published', + 'pending' + ], + }, + 'notes': { + 'type': 'string', + 'maxlength': 256, + }, + 'parent': {} + }, + 'form_schema': { + 'url': {}, + 'status': {}, + 'notes': {}, + }, + } + db.node_types.insert(group_node_type) if __name__ == '__main__': diff --git a/attract/settings.py b/attract/settings.py index 4ec56942..4b805fe0 100644 --- a/attract/settings.py +++ b/attract/settings.py @@ -25,6 +25,12 @@ users_schema = { 'minlength': 1, 'maxlength': 60, }, + 'username': { + 'type': 'string', + 'minlength': 1, + 'maxlength': 60, + 'required': True, + }, 'email': { 'type': 'string', 'minlength': 1, @@ -49,6 +55,96 @@ users_schema = { } } +organizations_schema = { + 'name': { + 'type': 'string', + 'minlength': 1, + 'maxlength': 128, + 'required': True + }, + 'url': { + 'type': 'string', + 'minlength': 1, + 'maxlength': 128, + 'required': True + }, + 'description': { + 'type': 'string', + 'maxlength': 256, + }, + 'website': { + 'type': 'string', + 'maxlength': 256, + }, + 'location': { + 'type': 'string', + 'maxlength': 256, + }, + 'picture': { + 'type': 'objectid', + 'nullable': True, + 'data_relation': { + 'resource': 'files', + 'field': '_id', + 'embeddable': True + }, + }, + 'users': { + 'type': 'list', + 'default': [], + 'schema': { + 'type': 'objectid', + 'data_relation': { + 'resource': 'users', + 'field': '_id', + 'embeddable': True + } + } + }, + 'teams': { + 'type': 'list', + 'default': [], + 'schema': { + 'type': 'dict', + 'schema': { + # Team name + 'name': { + 'type': 'string', + 'minlength': 1, + 'maxlength': 128, + 'required': True + }, + # List of user ids for the team + 'users': { + 'type': 'list', + 'default': [], + 'schema': { + 'type': 'objectid', + 'data_relation': { + 'resource': 'users', + 'field': '_id', + } + } + }, + # List of groups assigned to the team (this will automatically + # update the groups property of each user in the team) + 'groups': { + 'type': 'list', + 'default': [], + 'schema': { + 'type': 'objectid', + 'data_relation': { + 'resource': 'groups', + 'field': '_id', + } + } + } + } + } + } +} + + nodes_schema = { 'name': { 'type': 'string', @@ -306,6 +402,10 @@ groups = { 'schema': groups_schema, } +organizations = { + 'schema': organizations_schema, +} + DOMAIN = { 'users': users, 'nodes': nodes, @@ -313,7 +413,8 @@ DOMAIN = { 'tokens': tokens, 'files': files, 'binary_files': binary_files, - 'groups': groups + 'groups': groups, + 'organizations': organizations } try: @@ -321,3 +422,6 @@ try: MONGO_DBNAME = 'attract_test' except: pass + +if os.environ.get('MONGO_HOST'): + MONGO_HOST = os.environ.get('MONGO_HOST') diff --git a/docker/attract-db/Dockerfile b/docker/attract-db/Dockerfile index 32695982..cc1985eb 100644 --- a/docker/attract-db/Dockerfile +++ b/docker/attract-db/Dockerfile @@ -1,17 +1,26 @@ -FROM ubuntu:14.04 -MAINTAINER Eibriel +FROM debian +MAINTAINER Francesco Siddi RUN apt-get update && apt-get install -y \ -mongodb - -#RUN mkdir /data && mkdir /data/db +python \ +python-dev \ +python-pip \ +git \ +nano RUN mkdir /data +RUN mkdir /data/www +RUN mkdir /data/www/attract_server_dev +#RUN git clone https://github.com/armadillica/attract.git /data/www/attract -VOLUME /data/db +RUN pip install virtualenv +RUN virtualenv /data/venv +#RUN . /data/venv/bin/activate +#RUN pip install -r requirements.txt -CMD ["mongod", "--smallfiles"] +VOLUME /data/www/attract_server_dev -EXPOSE 27017 +EXPOSE 5000 -#CMD ["python", "/attract/attract/manage.py", "runserver", "-DFOREGROUND"] +ENTRYPOINT . /data/venv/bin/activate; \ +cd /data/www/attract_server_dev; \