From 025202df3f1b5e4eb4e1cb0fcb0b8a0141eaf527 Mon Sep 17 00:00:00 2001 From: Eibriel Date: Wed, 11 Mar 2015 16:03:19 +0100 Subject: [PATCH] Initial Cleanup --- .gitignore | 1 + attract/application/__init__.py | 70 ++++---- attract/application/helpers/__init__.py | 0 attract/application/modules/__init__.py | 0 attract/application/modules/main/__init__.py | 7 - attract/application/modules/nodes/__init__.py | 167 ------------------ attract/application/modules/nodes/forms.py | 160 ----------------- attract/application/modules/nodes/models.py | 95 ---------- .../application/modules/projects/__init__.py | 30 ---- attract/application/modules/shots/__init__.py | 111 ------------ attract/application/modules/shots/forms.py | 24 --- attract/application/modules/shots/models.py | 53 ------ attract/application/templates/layout.html | 102 ----------- .../application/templates/node_types/add.html | 96 ---------- .../templates/node_types/edit.html | 100 ----------- .../templates/node_types/index.html | 51 ------ attract/application/templates/nodes/add.html | 28 --- attract/application/templates/nodes/edit.html | 32 ---- .../application/templates/nodes/index.html | 47 ----- attract/application/templates/shots/add.html | 35 ---- attract/application/templates/shots/edit.html | 39 ---- .../application/templates/shots/index.html | 63 ------- attract/application/templates/shots/view.html | 23 --- attract/settings.py | 83 +++++++-- 24 files changed, 97 insertions(+), 1320 deletions(-) delete mode 100644 attract/application/helpers/__init__.py delete mode 100644 attract/application/modules/__init__.py delete mode 100644 attract/application/modules/main/__init__.py delete mode 100644 attract/application/modules/nodes/__init__.py delete mode 100644 attract/application/modules/nodes/forms.py delete mode 100644 attract/application/modules/nodes/models.py delete mode 100644 attract/application/modules/projects/__init__.py delete mode 100644 attract/application/modules/shots/__init__.py delete mode 100644 attract/application/modules/shots/forms.py delete mode 100644 attract/application/modules/shots/models.py delete mode 100644 attract/application/templates/layout.html delete mode 100644 attract/application/templates/node_types/add.html delete mode 100644 attract/application/templates/node_types/edit.html delete mode 100644 attract/application/templates/node_types/index.html delete mode 100644 attract/application/templates/nodes/add.html delete mode 100644 attract/application/templates/nodes/edit.html delete mode 100644 attract/application/templates/nodes/index.html delete mode 100644 attract/application/templates/shots/add.html delete mode 100644 attract/application/templates/shots/edit.html delete mode 100644 attract/application/templates/shots/index.html delete mode 100644 attract/application/templates/shots/view.html diff --git a/.gitignore b/.gitignore index 4c4f6a0c..5cb06d41 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ config.py +.ropeproject/* diff --git a/attract/application/__init__.py b/attract/application/__init__.py index 09715bc6..b3d015c2 100644 --- a/attract/application/__init__.py +++ b/attract/application/__init__.py @@ -1,51 +1,43 @@ from eve import Eve +from eve.auth import TokenAuth -# import config -# from flask import Flask, Blueprint -# from flask.ext.mail import Mail -# from flask.ext.sqlalchemy import SQLAlchemy -# from flask.ext.thumbnails import Thumbnail -# from flask.ext.assets import Environment, Bundle - -# Initialize the Flask all object +import random +import string from eve.io.mongo import Validator class ValidateCustomFields(Validator): - def _validate_validcf(self, validcf, field, value): - if validcf: - print self.document['node_type'] - if value == 'hi': - return True - else: - self._error(field, "Must be hi") + def _validate_valid_properties(self, valid_properties, field, value): + node_types = app.data.driver.db['ntypes'] + lookup = {} + lookup['_id'] = self.document['node_type'] + node_type = node_types.find_one(lookup) + + v = Validator(node_type['dyn_schema']) + val = v.validate(value) + if val: + return True + else: + self._error(field, "Must be hi") -app = Eve(validator=ValidateCustomFields) +class RolesAuth(TokenAuth): + def check_auth(self, token, allowed_roles, resource, method): + accounts = app.data.driver.db['users'] + lookup = {'token': token} + if allowed_roles: + lookup['role'] = {'$in': allowed_roles} + account = accounts.find_one(lookup) + return account -# Filemanager used by Flask-Admin extension -# filemanager = Blueprint('filemanager', __name__, static_folder='static/files') +def add_token(documents): + # Don't use this in production: + # You should at least make sure that the token is unique. + for document in documents: + document["token"] = (''.join(random.choice(string.ascii_uppercase) + for x in range(10))) -# # Choose the configuration to load -# app.config.from_object(config.Development) +app = Eve(validator=ValidateCustomFields, auth=RolesAuth) +app.on_insert_users += add_token -# # Initialized the available extensions -# mail = Mail(app) -# db = SQLAlchemy(app) -# thumb = Thumbnail(app) -# assets = Environment(app) - -# # Import controllers -# from application.modules.nodes import node_types -# from application.modules.nodes import nodes -# from application.modules.main import homepage -# from application.modules.shots import shots -# from application.modules.projects import projects - -# # Register blueprints for the imported controllers -# app.register_blueprint(filemanager) -# app.register_blueprint(shots, url_prefix='/shots') -# app.register_blueprint(projects, url_prefix='/projects') -# app.register_blueprint(node_types, url_prefix='/node-types') -# app.register_blueprint(nodes, url_prefix='/nodes') diff --git a/attract/application/helpers/__init__.py b/attract/application/helpers/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/attract/application/modules/__init__.py b/attract/application/modules/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/attract/application/modules/main/__init__.py b/attract/application/modules/main/__init__.py deleted file mode 100644 index 94bf4fe7..00000000 --- a/attract/application/modules/main/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -from application import app -from application.modules.shots import index - -@app.route("/") -def homepage(): - """Very minimal setup that returns the shot index view""" - return index() \ No newline at end of file diff --git a/attract/application/modules/nodes/__init__.py b/attract/application/modules/nodes/__init__.py deleted file mode 100644 index 8b0ed52e..00000000 --- a/attract/application/modules/nodes/__init__.py +++ /dev/null @@ -1,167 +0,0 @@ -from flask import abort -from flask import Blueprint -from flask import jsonify -from flask import render_template -from flask import redirect -from flask import request -from flask import flash -from flask import url_for - -from application import db - -from application.modules.nodes.models import Node, NodeType -from application.modules.nodes.forms import NodeTypeForm -from application.modules.nodes.forms import CustomFieldForm -from application.modules.nodes.forms import get_node_form -from application.modules.nodes.forms import process_node_form - - -# Name of the Blueprint -node_types = Blueprint('node_types', __name__) -nodes = Blueprint('nodes', __name__) - -@node_types.route("/") -def index(): - """Display the node types - """ - node_types = [t for t in NodeType.query.all()] - - return render_template('node_types/index.html', - title='node_types', - node_types=node_types) - - shots = [] - for shot in Node.query.\ - join(NodeType).\ - filter(NodeType.url == 'shot'): - status = None - if shot.status: - status = shot.status.name - shots.append(dict( - id=shot.id, - name=shot.name, - description=shot.description, - duration=shot.node_shot[0].duration, - status=status, - notes=shot.node_shot[0].notes)) - return render_template('shots/index.html', - title='shots', - shots=shots) - - -@node_types.route("/add", methods=['GET', 'POST']) -def add(): - form = NodeTypeForm() - - if form.validate_on_submit(): - node_type = NodeType( - name=form.name.data, - description=form.description.data, - url=form.url.data) - - db.session.add(node_type) - db.session.commit() - - return redirect(url_for('node_types.index')) - return render_template('node_types/add.html', form=form) - - -@node_types.route("//edit", methods=['GET', 'POST']) -def edit(node_type_id): - node_type = NodeType.query.get_or_404(node_type_id) - - form = NodeTypeForm(obj=node_type) - - if form.validate_on_submit(): - node_type.name = form.name.data - node_type.description = form.description.data - node_type.url = form.url.data - # Processing custom fields - for field in form.custom_fields: - print field.data['id'] - - db.session.commit() - else: - print form.errors - - - # if form.validate_on_submit(): - # node_type = NodeType( - # name=form.name.data, - # description=form.description.data, - # url=form.url.data) - - # db.session.add(node_type) - # db.session.commit() - - # return redirect(url_for('node_types.index')) - return render_template('node_types/edit.html', - node_type=node_type, - form=form) - - - -@nodes.route("/", methods=['GET', 'POST']) -def index(): - """Generic function to list all nodes - """ - nodes = Node.query.all() - return render_template('nodes/index.html', - nodes=nodes) - - -@nodes.route("//add", methods=['GET', 'POST']) -def add(node_type): - """Generic function to add a node of any type - """ - form = get_node_form(node_type) - if form.validate_on_submit(): - if process_node_form(form): - return redirect('/') - else: - print form.errors - return render_template('nodes/add.html', - node_type=node_type, - form=form) - - -@nodes.route("//edit", methods=['GET', 'POST']) -def edit(node_id): - """Generic node editing form - """ - node = Node.query.get_or_404(node_id) - form = get_node_form(node.node_type.url) - - if form.validate_on_submit(): - if process_node_form(form, node_id): - return redirect(url_for('node.edit', node_id=node_id)) - - form.name.data = node.name - form.description.data = node.description - - # We populate the form, basing ourselves on the default node properties - for node_property in node.properties: - for field in form: - if field.name == node_property.custom_field.name_url: - value = node_property.value - # We cast values into the right type - if node_property.custom_field.field_type == 'integer': - value = int(value) - if node_property.custom_field.field_type == 'select': - value = int(value) - field.data = value - - - return render_template('nodes/edit.html', - node=node, - form=form) - - -@nodes.route("//delete", methods=['GET', 'POST']) -def delete(node_id): - """Generic node deletion - """ - node = Node.query.get_or_404(node_id) - db.session.delete(node) - db.session.commit() - return 'ok' diff --git a/attract/application/modules/nodes/forms.py b/attract/application/modules/nodes/forms.py deleted file mode 100644 index 90889729..00000000 --- a/attract/application/modules/nodes/forms.py +++ /dev/null @@ -1,160 +0,0 @@ -from flask_wtf import Form -from wtforms import TextField -from wtforms import BooleanField -from wtforms import SelectField -from wtforms import TextAreaField -from wtforms import IntegerField -from wtforms import HiddenField -from wtforms import FieldList -from wtforms import FormField -from wtforms import Form as BasicForm - -from application.modules.nodes.models import CustomFields -from wtforms.validators import DataRequired - -from application import db - -from application.modules.nodes.models import Node, NodeType, NodeProperties - -class CustomFieldForm(BasicForm): - id = HiddenField() - field_type = TextField('Field Type', validators=[DataRequired()]) - name = TextField('Name', validators=[DataRequired()]) - name_url = TextField('Url', validators=[DataRequired()]) - description = TextAreaField('Description') - is_required = BooleanField('Is extended') - def __init__(self, csrf_enabled=False, *args, **kwargs): - super(CustomFieldForm, self).__init__(csrf_enabled=False, *args, **kwargs) - -class ModelFieldList(FieldList): - def __init__(self, *args, **kwargs): - self.model = kwargs.pop("model", None) - super(ModelFieldList, self).__init__(*args, **kwargs) - if not self.model: - raise ValueError("ModelFieldList requires model to be set") - - def populate_obj(self, obj, name): - while len(getattr(obj, name)) < len(self.entries): - newModel = self.model() - db.session.add(newModel) - getattr(obj, name).append(newModel) - while len(getattr(obj, name)) > len(self.entries): - db.session.delete(getattr(obj, name).pop()) - super(ModelFieldList, self).populate_obj(obj, name) - -class ChildInline(Form): - title = TextField('Title',) - -class NodeTypeForm(Form): - name = TextField('Name', validators=[DataRequired()]) - url = TextField('Url', validators=[DataRequired()]) - description = TextAreaField('Description', validators=[DataRequired()]) - is_extended = BooleanField('Is extended') - custom_fields = ModelFieldList(FormField(CustomFieldForm), model=CustomFields) - - -class IMForm(Form): - protocol = SelectField(choices=[('aim', 'AIM'), ('msn', 'MSN')]) - username = TextField() - -class ContactForm(Form): - first_name = TextField() - last_name = TextField() - im_accounts = FieldList(BooleanField('Is extended'),) - - -def get_node_form(node_type): - node_type = NodeType.query.filter_by(url=node_type).first() - class ProceduralForm(Form): - pass - - setattr(ProceduralForm, - 'name', - TextField('Name', validators=[DataRequired()])) - setattr(ProceduralForm, - 'url', - TextField('Url')) - setattr(ProceduralForm, - 'description', - TextAreaField('Description', validators=[DataRequired()])) - setattr(ProceduralForm, - 'node_type_id', - HiddenField(default=node_type.id)) - - for custom_field in CustomFields.query\ - .join(NodeType)\ - .filter(NodeType.url == node_type.url): - - if custom_field.field_type == 'text': - field_properties = TextAreaField(custom_field.name, - validators=[DataRequired()]) - elif custom_field.field_type == 'string': - field_properties = TextField(custom_field.name, - validators=[DataRequired()]) - elif custom_field.field_type == 'integer': - field_properties = IntegerField(custom_field.name, - validators=[DataRequired()]) - elif custom_field.field_type == 'select': - options = Node.query\ - .join(NodeType)\ - .filter(NodeType.url==custom_field.name_url)\ - .all() - field_properties = SelectField(custom_field.name, - coerce=int, - choices=[(option.id, option.name) for option in options] ) - - setattr(ProceduralForm, custom_field.name_url, field_properties) - - return ProceduralForm() - - -def process_node_form(form, node_id=None): - """Generic function used to process new nodes, as well as edits - """ - if form.validate_on_submit(): - node_type = NodeType.query.get(form.node_type_id.data) - if node_id: - node = Node.query.get(node_id) - node.name = form.name.data - node.description = form.description.data - else: - node = Node( - name=form.name.data, - description=form.description.data, - node_type_id=form.node_type_id.data) - db.session.add(node) - db.session.commit() - - for custom_field in CustomFields.query\ - .join(NodeType)\ - .filter(NodeType.url == node_type.url): - - for field in form: - if field.name == custom_field.name_url: - if node_id: - # Query for the indivitual property - # TODO: collect all properties and loop through them - node_property = NodeProperties.query\ - .filter_by(node_id=node_id)\ - .filter_by(custom_field_id=custom_field.id)\ - .first() - if node_property: - # Update the value of the property - node_property.value = field.data - else: - # If the property is missing we add it - node_property = NodeProperties( - node_id=node.id, - custom_field_id=custom_field.id, - value=field.data) - db.session.add(node_property) - else: - node_property = NodeProperties( - node_id=node.id, - custom_field_id=custom_field.id, - value=field.data) - db.session.add(node_property) - db.session.commit() - return True - else: - return False diff --git a/attract/application/modules/nodes/models.py b/attract/application/modules/nodes/models.py deleted file mode 100644 index 199b97dd..00000000 --- a/attract/application/modules/nodes/models.py +++ /dev/null @@ -1,95 +0,0 @@ -from application import app -from application import db - -import os -import os.path as op -import datetime - -import hashlib -import time - -from werkzeug import secure_filename - - -def prefix_name(obj, file_data): - # Collect name and extension - parts = op.splitext(file_data.filename) - # Get current time (for unique hash) - timestamp = str(round(time.time())) - # Has filename only (not extension) - file_name = secure_filename(timestamp + '%s' % parts[0]) - # Put them together - full_name = hashlib.md5(file_name).hexdigest() + parts[1] - return full_name - - -# Create directory for file fields to use -file_path = op.join(op.dirname(__file__), 'static/files',) -try: - os.mkdir(file_path) -except OSError: - pass - - -class NodeType(db.Model): - id = db.Column(db.Integer, primary_key = True) - name = db.Column(db.String(120), nullable=False) - description = db.Column(db.Text) - url = db.Column(db.String(120), nullable=False) - - custom_fields = db.relationship('CustomFields', backref='NodeType', - cascade="all, delete, delete-orphan") - - def __str__(self): - return self.name - - -class Node(db.Model): - id = db.Column(db.Integer, primary_key = True) - name = db.Column(db.String(120), nullable=False) - url = db.Column(db.String(120)) - description = db.Column(db.Text) - main_picture = db.Column(db.String(80)) - order = db.Column(db.Integer) - creation_date = db.Column(db.DateTime(), default=datetime.datetime.now) - edit_date = db.Column(db.DateTime()) - - parent_id = db.Column(db.Integer, db.ForeignKey('node.id')) - parent = db.relationship('Node', remote_side=[id]) - - node_type_id = db.Column(db.Integer(), db.ForeignKey(NodeType.id)) - node_type = db.relationship(NodeType, backref='Node') - - properties = db.relationship('NodeProperties', backref='Node', - cascade="all, delete, delete-orphan") - - def get_property(self, name): - for p in self.properties: - if p.custom_field.name_url == name: - return p - print 'p' - return None - - def __str__(self): - return self.name - - -class CustomFields(db.Model): - id = db.Column(db.Integer, primary_key = True) - node_type_id = db.Column(db.Integer(), db.ForeignKey(NodeType.id)) - - field_type = db.Column(db.String(128)) - order = db.Column(db.Integer()) - name = db.Column(db.String(128)) - name_url = db.Column(db.String(128)) - description = db.Column(db.Text()) - - -class NodeProperties(db.Model): - id = db.Column(db.Integer, primary_key = True) - node_id = db.Column(db.Integer(), db.ForeignKey(Node.id)) - - custom_field_id = db.Column(db.Integer(), db.ForeignKey(CustomFields.id)) - custom_field = db.relationship(CustomFields, backref='NodeProperties') - - value = db.Column(db.Text()) diff --git a/attract/application/modules/projects/__init__.py b/attract/application/modules/projects/__init__.py deleted file mode 100644 index 01640e6b..00000000 --- a/attract/application/modules/projects/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -from flask import (abort, - Blueprint, - jsonify, - render_template, - redirect, - request) - -from flask.ext.thumbnails import Thumbnail -from flask.ext.sqlalchemy import SQLAlchemy -from sqlalchemy.orm import aliased - -from application.modules.shots import Node -from application.modules.shots import NodeType - -# Name of the Blueprint -projects = Blueprint('projects', __name__) - -@projects.route("/") -def index(): - projects = {} - for project in Node.query.\ - join(NodeType).\ - filter(NodeType.url == 'project'): - status = None - if project.status: - status = project.status.name - projects[project.id] = dict( - name=project.name, - status=status) - return jsonify(projects=projects) diff --git a/attract/application/modules/shots/__init__.py b/attract/application/modules/shots/__init__.py deleted file mode 100644 index f844aae9..00000000 --- a/attract/application/modules/shots/__init__.py +++ /dev/null @@ -1,111 +0,0 @@ -from flask import (abort, - Blueprint, - jsonify, - render_template, - redirect, - request, - flash) - -from flask.ext.thumbnails import Thumbnail -from flask.ext.sqlalchemy import SQLAlchemy -from sqlalchemy.orm import aliased - -from application import db - -from application.modules.shots.forms import ShotForm -from application.modules.nodes.models import Node, NodeType, NodeProperties -from application.modules.shots.models import NodeShot - - -# Name of the Blueprint -shots = Blueprint('shots', __name__) - -@shots.route("/") -def index(): - shots = [] - - for shot in Node.query.\ - join(NodeType).\ - filter(NodeType.url == 'shot'): - status = None - # if shot.status: - # status = shot.status.name - s = dict( - id=shot.id, - name=shot.name, - description=shot.description) - for node_property in shot.properties: - s[node_property.custom_field.name_url] = node_property.value - shots.append(s) - return render_template('shots/index.html', - title='shots', - shots=shots) - - -@shots.route("/view/") -def view(shot_id): - shot = Node.query.get(shot_id) - if shot and shot.node_type.url == 'shot': - return render_template('shots/view.html', - title='shots', - shot=shot, - notes=shot.get_property('notes')) - else: - abort(404) - - -@shots.route("/add", methods=('GET', 'POST')) -def add(): - form = ShotForm() - - if form.validate_on_submit(): - shot_type = NodeType.query.filter_by(url='shot').first() - shot = Node( - name=form.name.data, - description=form.description.data, - node_type_id=shot_type.id, - status_id=form.status_id.data) - # Create entry in the attached node table - shot.node_shot = [NodeShot( - duration=form.duration.data, - notes=form.notes.data)] - - db.session.add(shot) - db.session.commit() - return redirect('/') - return render_template('shots/add.html', form=form) - - -@shots.route("/edit/", methods=('GET', 'POST')) -def edit(shot_id): - shot = Node.query.get(shot_id) - - form = ShotForm( - name=shot.name, - description=shot.description, - duration=shot.node_shot[0].duration, - note=shot.node_shot[0].notes) - - if form.validate_on_submit(): - shot.name = form.name.data - shot.description = form.description.data - shot.node_shot[0].duration = form.duration.data - shot.status_id = form.status_id.data - shot.node_shot[0].notes = form.notes.data - db.session.commit() - return redirect('/') - return render_template( - 'shots/edit.html', - form=form, - shot_id=shot_id) - - -@shots.route("/delete/") -def delete(shot_id): - shot = Node.query.get(shot_id) - if shot: - db.session.delete(shot) - db.session.commit() - return redirect('/') - else: - abort(404) diff --git a/attract/application/modules/shots/forms.py b/attract/application/modules/shots/forms.py deleted file mode 100644 index 74089751..00000000 --- a/attract/application/modules/shots/forms.py +++ /dev/null @@ -1,24 +0,0 @@ -from flask_wtf import Form -from wtforms import TextField -from wtforms import BooleanField -from wtforms import SelectField -from wtforms import TextAreaField -from wtforms import IntegerField - -from wtforms.validators import DataRequired - -from application.modules.nodes.models import Node, NodeType - -class ShotForm(Form): - statuses = Node.query\ - .join(NodeType)\ - .filter(NodeType.url == 'shot_status')\ - .all() - - name = TextField('Shot Name', validators=[DataRequired()]) - description = TextAreaField('Description', validators=[DataRequired()]) - status_id = SelectField('Status', - coerce=int, - choices=[(status.id, status.name) for status in statuses]) - duration = IntegerField('Duration') - notes = TextAreaField('Notes') diff --git a/attract/application/modules/shots/models.py b/attract/application/modules/shots/models.py deleted file mode 100644 index 9f1c23ac..00000000 --- a/attract/application/modules/shots/models.py +++ /dev/null @@ -1,53 +0,0 @@ -from application import app -from application import db - -from application.modules.nodes.models import Node - -class NodeShot(db.Model): - """docstring for NodeShot""" - id = db.Column(db.Integer, primary_key = True) - duration = db.Column(db.Integer, nullable=False) - notes = db.Column(db.Text) - - node_id = db.Column(db.Integer, db.ForeignKey(Node.id)) - node = db.relationship(Node, backref='node_shot', uselist=False) - - - -# Create Many to Many table -""" -assets_tags_table = db.Table('assets_tags', db.Model.metadata, - db.Column('asset_id', db.Integer, db.ForeignKey('asset.id')), - db.Column('tag_id', db.Integer, db.ForeignKey('tag.id')) - ) -""" - -# class Asset(db.Model): -# id = db.Column(db.Integer, primary_key=True) -# name = db.Column(db.String(120), nullable=False) -# description = db.Column(db.Text, nullable=False) -# link = db.Column(db.String(512)) -# picture = db.Column(db.String(80)) -# size = db.Column(db.String(7)) -# format = db.Column(db.String(15)) -# duration = db.Column(db.String(15)) - -# nodes = db.relationship('Node', secondary=nodes_assets_table) - -# #tags = db.relationship('Tag', secondary=assets_tags_table) - -# def __str__(self): -# return self.name - -""" - -class Tag(db.Model): - id = db.Column(db.Integer, primary_key=True) - name = db.Column(db.Unicode(64)) - - def __str__(self): - return self.name - -""" - - diff --git a/attract/application/templates/layout.html b/attract/application/templates/layout.html deleted file mode 100644 index 1f0414ab..00000000 --- a/attract/application/templates/layout.html +++ /dev/null @@ -1,102 +0,0 @@ - - - - - Attract - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- {% block sidebar %} -
-
- Shots - Assets -
-
- {% endblock %} - {% block body %} - {% endblock %} -
-
- -
-

Attract 3 - Python powered

-
- -
- - {% assets filters="jsmin", - output="assets/packed/attract.js", - "assets/js/jquery.min.js", - "assets/js/bootstrap.min.js", - "assets/js/jquery.dataTables.min.js", - "assets/js/jquery.dataTables.fnGetColumnData.js", - "assets/js/jquery.dataTables.fnFilterClear.js", - "assets/js/jquery.dataTables.bootstrap.js", - "assets/js/jquery.chosen.min.js", - "assets/js/bootstrap-markdown.js", - "assets/js/markdown.js", - "assets/js/jquery.attract.js" %} - - {% endassets %} - {% block footer_scripts %} - {% endblock %} - - - - diff --git a/attract/application/templates/node_types/add.html b/attract/application/templates/node_types/add.html deleted file mode 100644 index 984ca400..00000000 --- a/attract/application/templates/node_types/add.html +++ /dev/null @@ -1,96 +0,0 @@ -{% extends 'layout.html' %} - -{% block body %} -
-

Add Node type

-
-
-
- {{ form.hidden_tag() }} -
- {{ form.name.label }} - {{ form.name(size=20, class='form-control') }} -
-
- {{ form.description.label }} - {{ form.description(size=20, class='form-control') }} -
-
- {{ form.url.label }} - {{ form.url(size=20, class='form-control') }} -
-
- {{ form.is_extended.label }} - {{ form.is_extended(class='form-control') }} -
- -
- {{ form.custom_fields.label }} - - - - - - - - - {% for custom_field in form.custom_fields %} - - - {% for field in custom_field %} - {% if field.type == 'HiddenField' %} - {{field}} - {% else %} - - {% endif %} - {% endfor %} - - - {% endfor %} -
NameUrlDescriptionIs required
{{field}}
-
- - -
-
-
-
-{% endblock %} - -{% block footer_scripts %} - - -{% endblock %} diff --git a/attract/application/templates/node_types/edit.html b/attract/application/templates/node_types/edit.html deleted file mode 100644 index 568f9dff..00000000 --- a/attract/application/templates/node_types/edit.html +++ /dev/null @@ -1,100 +0,0 @@ -{% extends 'layout.html' %} - -{% block body %} -
-

Edit Node type

-
-
-
- {{ form.hidden_tag() }} -
- {{ form.name.label }} - {{ form.name(size=20, class='form-control') }} -
-
- {{ form.description.label }} - {{ form.description(size=20, class='form-control') }} -
-
- {{ form.url.label }} - {{ form.url(size=20, class='form-control') }} -
-
- {{ form.is_extended.label }} - {{ form.is_extended(class='form-control') }} -
- -
- {{ form.custom_fields.label }} - - - - - - - - - - - - - {% for custom_field in form.custom_fields %} - - - {% for field in custom_field %} - {% if field.type == 'HiddenField' %} - {{field}} - {% else %} - - {% endif %} - {% endfor %} - - - {% endfor %} -
TypeNameUrlDescriptionIs required
{{field}}
-
- - -
-
-
-
-{% endblock %} - -{% block footer_scripts %} - - -{% endblock %} diff --git a/attract/application/templates/node_types/index.html b/attract/application/templates/node_types/index.html deleted file mode 100644 index 0588fa7f..00000000 --- a/attract/application/templates/node_types/index.html +++ /dev/null @@ -1,51 +0,0 @@ -{% extends 'layout.html' %} - -{% block body %} -
-
-
- - - - - - - - - - - {% for node_type in node_types %} - - - - - - - {% endfor %} - - - - - - - - - - - -
Node NameUrlDescription
{{node_type.name}}{{node_type.url}} - {% if node_type.description %} - {{node_type.description|truncate(25)}} - {% endif %} - - Edit -
Node NameUrlDescription
-
-
-
-
- Add -
-
-
-{% endblock %} diff --git a/attract/application/templates/nodes/add.html b/attract/application/templates/nodes/add.html deleted file mode 100644 index 2245cf18..00000000 --- a/attract/application/templates/nodes/add.html +++ /dev/null @@ -1,28 +0,0 @@ -{% extends 'layout.html' %} - -{% block body %} -
-

Add {{ node_type }}

-
-
-
- {% for field in form %} - {% if field.name == 'csrf_token' %} - {{ field }} - {% else %} - {% if field.type == "HiddenField" %} - {{ field }} - {% else %} -
- {{ field.label }} - {{ field(class='form-control') }} -
- {% endif %} - {% endif %} - {% endfor %} - -
-
-
-
-{% endblock %} diff --git a/attract/application/templates/nodes/edit.html b/attract/application/templates/nodes/edit.html deleted file mode 100644 index 97198593..00000000 --- a/attract/application/templates/nodes/edit.html +++ /dev/null @@ -1,32 +0,0 @@ -{% extends 'layout.html' %} - -{% block body %} -
-

Edit {{ node.node_type.name }}

-
-
-
- {% for field in form %} - {% if field.name == 'csrf_token' %} - {{ field }} - {% else %} - {% if field.type == "HiddenField" %} - {{ field }} - {% else %} -
- {{ field.label }} - {{ field(class='form-control') }} -
- {% endif %} - {% endif %} - {% endfor %} - -
- Cancel - Delete -
-
-
-
-
-{% endblock %} diff --git a/attract/application/templates/nodes/index.html b/attract/application/templates/nodes/index.html deleted file mode 100644 index d2aa93f3..00000000 --- a/attract/application/templates/nodes/index.html +++ /dev/null @@ -1,47 +0,0 @@ -{% extends 'layout.html' %} - -{% block body %} -
-
-
- - - - - - - - - - {% for node in nodes %} - - - - - - {% endfor %} - - - - - - - - - -
NameDescription
{{node.name}} - {% if node.description %} - {{node.description|truncate(25)}} - {% endif %} - - Edit -
NameDescription
-
-
-
-
- Add -
-
-
-{% endblock %} diff --git a/attract/application/templates/shots/add.html b/attract/application/templates/shots/add.html deleted file mode 100644 index 1808ff2e..00000000 --- a/attract/application/templates/shots/add.html +++ /dev/null @@ -1,35 +0,0 @@ -{% extends 'layout.html' %} - -{% block body %} -
-

Add shot

-
-
-
- {{ form.hidden_tag() }} -
- {{ form.name.label }} - {{ form.name(size=20, class='form-control') }} -
-
- {{ form.description.label }} - {{ form.description(size=20, class='form-control') }} -
-
- {{ form.duration.label }} - {{ form.duration(size=20, class='form-control') }} -
-
- {{ form.status_id.label }} - {{ form.status_id(class='form-control') }} -
-
- {{ form.notes.label }} - {{ form.notes(class='form-control') }} -
- -
-
-
-
-{% endblock %} diff --git a/attract/application/templates/shots/edit.html b/attract/application/templates/shots/edit.html deleted file mode 100644 index 8f8886bd..00000000 --- a/attract/application/templates/shots/edit.html +++ /dev/null @@ -1,39 +0,0 @@ -{% extends 'layout.html' %} - -{% block body %} -
-

Edit shot

-
-
-
- {{ form.hidden_tag() }} -
- {{ form.name.label }} - {{ form.name(size=20, class='form-control') }} -
-
- {{ form.description.label }} - {{ form.description(size=20, class='form-control') }} -
-
- {{ form.duration.label }} - {{ form.duration(size=20, class='form-control') }} -
-
- {{ form.status_id.label }} - {{ form.status_id(class='form-control') }} -
-
- {{ form.notes.label }} - {{ form.notes(class='form-control') }} -
- -
- Cancel - Delete -
-
-
-
-
-{% endblock %} diff --git a/attract/application/templates/shots/index.html b/attract/application/templates/shots/index.html deleted file mode 100644 index 61d92db5..00000000 --- a/attract/application/templates/shots/index.html +++ /dev/null @@ -1,63 +0,0 @@ -{% extends 'layout.html' %} - -{% block body %} -
-
-
- - - - - - - - - - - - - - {% for shot in shots %} - - - - - - - - - - {% endfor %} - - - - - - - - - - - - - -
Shot NameDescriptionDurationStatusTasksNotes
{{shot['name']}} - {% if shot['description'] %} - {{shot['description']|truncate(25)}} - {% endif %} - {{shot['duration']}} - {% if shot['notes'] %} - {{shot['notes']|truncate(25)}} - {% endif %} - - Edit -
Shot NameDescriptionDurationStatusTasksNotes
-
-
-
-
- Add -
-
-
-{% endblock %} diff --git a/attract/application/templates/shots/view.html b/attract/application/templates/shots/view.html deleted file mode 100644 index eee49b4d..00000000 --- a/attract/application/templates/shots/view.html +++ /dev/null @@ -1,23 +0,0 @@ -{% extends 'layout.html' %} - -{% block body %} -
-

{{shot['name']}}

-
-
-

Picture goes here

-
-
-

{{shot['description']}}

-

- {% if notes %} - {{notes.value}} - {% else %} - No notes at the moment - {% endif %} -

-
-
-
- -{% endblock %} \ No newline at end of file diff --git a/attract/settings.py b/attract/settings.py index d16c7214..657c7e55 100644 --- a/attract/settings.py +++ b/attract/settings.py @@ -8,7 +8,7 @@ RESOURCE_METHODS = ['GET', 'POST', 'DELETE'] ITEM_METHODS = ['GET', 'PATCH', 'PUT', 'DELETE'] -schema = { +users_schema = { # Schema definition, based on Cerberus grammar. Check the Cerberus project # (https://github.com/nicolaiarocci/cerberus) for details. 'firstname': { @@ -26,9 +26,11 @@ schema = { 'unique': True, }, # 'role' is a list, and can only contain values from 'allowed'. + # changed to string 'role': { - 'type': 'list', + 'type': 'string', 'allowed': ["author", "contributor", "copy"], + 'required': True, }, # An embedded 'strongly-typed' dictionary. 'location': { @@ -36,7 +38,7 @@ schema = { 'schema': { 'address': {'type': 'string'}, 'city': {'type': 'string'} - }, + } }, 'born': { 'type': 'datetime', @@ -48,21 +50,52 @@ nodes_schema = { 'type': 'string', 'minlength': 1, 'maxlength': 128, + 'required': True, + }, + 'description': { + 'type': 'string', + 'minlength': 1, + 'maxlength': 128, + }, + 'thumbnail': { + 'type': 'string', + 'minlength': 1, + 'maxlength': 128, }, 'parent': { 'type': 'objectid', - # 'data_relation': { - # 'resource': 'node', - # 'field': '_id', - # }, + 'data_relation': { + 'resource': 'nodes', + 'field': '_id', + }, }, 'node_type' : { 'type' : 'string', - 'validcf' : True, + 'required': True, + 'data_relation': { + 'resource': 'node_types', + 'field': '_id', + }, }, - # 'custom_fields' : { - # 'type' : 'dict' - # } + 'properties' : { + 'type' : 'dict', + 'valid_properties' : True, + 'required': True, + } +} + + +node_types_schema = { + 'name': { + 'type': 'string', + 'minlength': 1, + 'maxlength': 128, + 'required': True, + }, + 'dyn_schema': { + 'type': 'dict', + 'required': True, + } } @@ -74,15 +107,22 @@ nodes = { # most global settings can be overridden at resource level 'resource_methods': ['GET', 'POST'], + 'allowed_roles': ['author', 'contributor'], + 'schema': nodes_schema } +node_types = { -people = { - # 'title' tag used in item links. Defaults to the resource title minus - # the final, plural 's' (works fine in most cases but not for 'people') - 'item_title': 'person', + 'resource_methods': ['GET', 'POST'], + + 'schema' : node_types_schema, +} + + +users = { + 'item_title': 'user', # by default the standard item entry point is defined as # '/people/'. We leave it untouched, and we also enable an @@ -100,12 +140,19 @@ people = { # most global settings can be overridden at resource level 'resource_methods': ['GET', 'POST'], - 'schema': schema + # Allow 'token' to be returned with POST responses + 'extra_response_fields': ['token'], + + 'public_methods': ['GET', 'POST'], + # 'public_item_methods': ['GET'], + + 'schema': users_schema } DOMAIN = { - 'people': people, - 'nodes' : nodes + 'users': users, + 'nodes' : nodes, + 'node_types': node_types, }