Beispiel #1
0
def posts_create(project_id):
    api = SystemUtility.attract_api()
    node_type = NodeType.find_first(
        {
            'where': '{"name" : "blog"}',
            'projection': '{"name": 1}'
        }, api=api)
    blog = Node.find_first(
        {
            'where':
            '{"node_type" : "%s", \
            "parent": "%s"}' % (node_type._id, project_id),
        },
        api=api)
    node_type = NodeType.find_first({
        'where': '{"name" : "post"}',
    }, api=api)
    form = get_node_form(node_type)
    if form.validate_on_submit():
        user_id = current_user.objectid
        if process_node_form(form, node_type=node_type, user=user_id):
            return redirect(url_for('main_blog'))
    form.parent.data = blog._id
    return render_template('nodes/custom/post/create.html',
                           node_type=node_type,
                           form=form,
                           project_id=project_id)
Beispiel #2
0
def task_add():
    api = SystemUtility.attract_api()
    shot_id = request.form["shot_id"]
    task_name = request.form["task_name"]

    node_type_list = NodeType.all({"where": "name=='task'"}, api=api)
    node_type = node_type_list["_items"][0]

    node_type_id = node_type._id
    import datetime

    RFC1123_DATE_FORMAT = "%a, %d %b %Y %H:%M:%S GMT"
    node = Node()
    prop = {}
    prop["node_type"] = node_type_id
    prop["name"] = task_name
    prop["description"] = ""
    prop["user"] = current_user.objectid
    prop["parent"] = shot_id
    prop["properties"] = {
        "status": "todo",
        "owners": {"users": [], "groups": []},
        "time": {
            "duration": 10,
            "start": datetime.datetime.strftime(datetime.datetime.now(), "%a, %d %b %Y %H:%M:%S GMT"),
        },
    }
    post = node.post(prop, api=api)
    return jsonify(node.to_dict())
Beispiel #3
0
def task_add():
    api = system_util.pillar_api()
    shot_id = request.form['shot_id']
    task_name = request.form['task_name']

    node_type_list = NodeType.all({
        'where': "name=='task'",
        }, api=api)
    node_type = node_type_list['_items'][0]

    node_type_id = node_type._id
    import datetime

    RFC1123_DATE_FORMAT = '%a, %d %b %Y %H:%M:%S GMT'
    node = Node()
    prop = {}
    prop['node_type'] = node_type_id
    prop['name'] = task_name
    prop['description'] = ''
    prop['user'] = current_user.objectid
    prop['parent'] = shot_id
    prop['properties'] = {
        'status': 'todo',
        'owners': {
            'users': [],
            'groups': []},
        'time': {
            'duration': 10,
            'start': datetime.datetime.strftime(datetime.datetime.now(), '%a, %d %b %Y %H:%M:%S GMT')}
        }
    post = node.post(prop, api=api)
    return jsonify(node.to_dict())
Beispiel #4
0
    def projects(self):
        """Get list of project for the user"""
        # Find node_type project id (this could become static)
        node_type = NodeType.find_first({
            'where': '{"name" : "project"}',
        },
                                        api=self.api)
        if not node_type: return abort(404)

        # Define key for querying for the project
        if self.is_organization:
            user_path = 'properties.organization'
        else:
            user_path = 'user'

        # Query for the project
        # TODO currently, this system is weak since we rely on the user property
        # of a node when searching for a project using the user it. This allows
        # us to find a project that belongs to an organization also by requesting
        # the user that originally created the node. This can be fixed by
        # introducing a 'user' property in the project node type.

        projects = Node.all({
            'where': '{"node_type" : "%s", "%s": "%s"}'\
                % (node_type._id, user_path, self._id),
            }, api=self.api)

        for project in projects._items:
            attach_project_pictures(project, self.api)

        return projects
Beispiel #5
0
def posts_view(project_id, url=None):
    """View individual blogpost"""
    api = SystemUtility.attract_api()
    node_type = NodeType.find_first({
        'where': '{"name" : "blog"}',
        'projection': '{"name": 1}'
        }, api=api)
    blog = Node.find_one({
        'where': '{"node_type" : "%s", \
            "parent": "%s"}' % (node_type._id, project_id),
        }, api=api)
    if url:
        try:
            post = Node.find_one({
                'where': '{"parent": "%s", "properties.url": "%s"}' % (blog._id, url),
                'embedded': '{"picture":1, "node_type": 1}',
                }, api=api)
        except ResourceNotFound:
            return abort(404)

        return render_template(
            'nodes/custom/post/view.html',
            blog=blog,
            node=post)
    else:
        # Render all posts
        posts = Node.all({
            'where': '{"parent": "%s"}' % (blog._id),
            'embedded': '{"picture":1}',
            'sort': '-_created'
            }, api=api)
        return render_template(
            'nodes/custom/blog/index.html',
            blog=blog,
            posts=posts._items)
Beispiel #6
0
def comments_create():
    content = request.form['content']
    parent_id = request.form.get('parent_id')

    api = SystemUtility.attract_api()
    node_type = NodeType.find_first({
        'where': '{"name" : "comment"}',
        }, api=api)

    node_asset_props = dict(
        name='Comment',
        #description=a.description,
        #picture=picture,
        user=current_user.objectid,
        node_type=node_type._id,
        #parent=node_parent,
        properties=dict(
            content=content,
            status='published',
            confidence=0,
            rating_positive=0,
            rating_negative=0))

    if parent_id:
        node_asset_props['parent'] = parent_id
    node_asset = Node(node_asset_props)
    node_asset.create(api=api)

    return jsonify(
        asset_id=node_asset._id,
        content=node_asset.properties.content)
Beispiel #7
0
    def projects(self):
        """Get list of project for the user"""
        # Find node_type project id (this could become static)
        node_type = NodeType.find_first({
            'where': '{"name" : "project"}',
            }, api=self.api)
        if not node_type: return abort(404)

        # Define key for querying for the project
        if self.is_organization:
            user_path = 'properties.organization'
        else:
            user_path = 'user'

        # Query for the project
        # TODO currently, this system is weak since we rely on the user property
        # of a node when searching for a project using the user it. This allows
        # us to find a project that belongs to an organization also by requesting
        # the user that originally created the node. This can be fixed by
        # introducing a 'user' property in the project node type.

        projects = Node.all({
            'where': '{"node_type" : "%s", "%s": "%s"}'\
                % (node_type._id, user_path, self._id),
            }, api=self.api)

        for project in projects._items:
            attach_project_pictures(project, self.api)

        return projects
Beispiel #8
0
def index():
    """Display the node types
    """
    node_types = NodeType.all()
    node_types = node_types['_items']
    return render_template('node_types/index.html',
                           title='node_types',
                           node_types=node_types)
Beispiel #9
0
def type_names():
    api = SystemUtility.attract_api()

    types = NodeType.all(api=api)['_items']
    type_names = []
    for names in types:
        type_names.append(str(names['name']))
    return type_names
Beispiel #10
0
def type_names():
    api = SystemUtility.attract_api()

    types = NodeType.all(api=api)['_items']
    type_names = []
    for names in types:
        type_names.append(str(names['name']))
    return type_names
Beispiel #11
0
def add():
    form = NodeTypeForm()
    if form.validate_on_submit():
        NodeType(name=form.name.data,
                 description=form.description.data,
                 url=form.url.data)

        return redirect(url_for('node_types.index'))
    return render_template('node_types/add.html', form=form)
Beispiel #12
0
def index():
    """Display the node types
    """
    api = system_util.pillar_api()
    node_types = NodeType.all(api=api)
    node_types = node_types['_items']
    return render_template('node_types/index.html',
                           title='node_types',
                           node_types=node_types)
Beispiel #13
0
def edit(node_type_id):
    node_type = NodeType.find(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.properties:
            print field.data["id"]
    else:
        print form.errors
    return render_template("node_types/edit.html", node_type=node_type, form=form)
Beispiel #14
0
def posts_create(project_id):
    api = SystemUtility.attract_api()
    node_type = NodeType.find_first({
        'where': '{"name" : "blog"}',
        'projection': '{"name": 1}'
        }, api=api)
    blog = Node.find_first({
        'where': '{"node_type" : "%s", \
            "parent": "%s"}' % (node_type._id, project_id),
        }, api=api)
    node_type = NodeType.find_first({'where': '{"name" : "post"}',}, api=api)
    form = get_node_form(node_type)
    if form.validate_on_submit():
        user_id = current_user.objectid
        if process_node_form(
                form, node_type=node_type, user=user_id):
            return redirect(url_for('main_blog'))
    form.parent.data = blog._id
    return render_template('nodes/custom/post/create.html',
        node_type=node_type,
        form=form,
        project_id=project_id)
Beispiel #15
0
def edit(node_type_id):
    node_type = NodeType.find(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.properties:
            print field.data['id']
    else:
        print form.errors
    return render_template('node_types/edit.html',
                           node_type=node_type,
                           form=form)
Beispiel #16
0
def inject_node_types():
    if current_user.is_anonymous:
        return dict(node_types={})

    api = SystemUtility.attract_api()

    types = NodeType.all(api=api)['_items']
    node_types = []
    for t in types:
        # If we need to include more info, we can turn node_types into a dict
        # node_types[t.name] = dict(
        #     url_view=url_for('nodes.index', node_type_name=t.name))
        node_types.append(str(t['name']))

    return dict(node_types=node_types)
Beispiel #17
0
def inject_node_types():
    if current_user.is_anonymous:
        return dict(node_types={})

    api = SystemUtility.attract_api()

    types = NodeType.all(api=api)['_items']
    node_types = []
    for t in types:
        # If we need to include more info, we can turn node_types into a dict
        # node_types[t.name] = dict(
        #     url_view=url_for('nodes.index', node_type_name=t.name))
        node_types.append(str(t['name']))

    return dict(node_types=node_types)
Beispiel #18
0
def index(node_type_name=""):
    """Generic function to list all nodes
    """
    # Pagination index
    page = request.args.get('page', 1)
    max_results = 50

    api = SystemUtility.attract_api()
    if node_type_name == "":
        node_type_name = "shot"

    node_type = NodeType.find_first(
        {
            'where': '{"name" : "%s"}' % node_type_name,
        }, api=api)

    if not node_type:
        return "Empty NodeType list", 200

    nodes = Node.all(
        {
            'where': '{"node_type" : "%s"}' % (node_type._id),
            'max_results': max_results,
            'page': page,
            'embedded': '{"picture":1}',
            'sort': "order"
        },
        api=api)

    # Build the pagination object
    pagination = Pagination(int(page), max_results, nodes._meta.total)

    template = '{0}/index.html'.format(node_type_name)
    try:
        return render_template(template,
                               title=node_type_name,
                               nodes=nodes,
                               node_type=node_type,
                               type_names=type_names(),
                               pagination=pagination)
    except TemplateNotFound:
        return render_template('nodes/index.html',
                               title=node_type_name,
                               nodes=nodes,
                               node_type=node_type,
                               type_names=type_names(),
                               pagination=pagination)
Beispiel #19
0
def index():
    """Custom production stats entry point
    """
    api = SystemUtility.attract_api()
    node_type_list = NodeType.all(
        {'where': '{"name": "%s"}' % ('shot')}, api=api)

    node_type = node_type_list['_items'][0]
    nodes = Node.all({
        'where': '{"node_type": "%s"}' % (node_type['_id']),
        'max_results': 100,
        'sort' : "order"}, api=api)

    node_statuses = {}

    node_totals = {
        'count': 0,
        'frames': 0
    }

    for shot in nodes._items:
        status = shot.properties.status
        if status not in node_statuses:
            # If they key does not exist, initialize with defaults
            node_statuses[status] = {
                'count': 0,
                'frames': 0}

        # Calculate shot duration and increase status count
        frames = shot.properties.cut_out - shot.properties.cut_in
        node_statuses[status]['count'] += 1
        node_statuses[status]['frames'] += frames
        # Update the global stats
        node_totals['count'] += 1
        node_totals['frames'] += frames

    for node_status in node_statuses:
        # Calculate completion percentage based on total duration
        print node_statuses[node_status]['frames']
        print node_totals['frames']
        node_statuses[node_status]['completion'] = percentage(
            node_statuses[node_status]['frames'], node_totals['frames'])

    return render_template(
        'stats/index.html',
        node_statuses=node_statuses)
Beispiel #20
0
def add(node_type_id):
    """Generic function to add a node of any type
    """
    api = SystemUtility.attract_api()
    ntype = NodeType.find(node_type_id, api=api)
    form = get_node_form(ntype)
    user_id = current_user.objectid
    if form.validate_on_submit():
        if process_node_form(form, node_type=ntype, user=user_id):
            return redirect(url_for('nodes.index', node_type_name=ntype['name']))
    else:
        print form.errors
    return render_template('nodes/add.html',
        node_type=ntype,
        form=form,
        errors=form.errors,
        type_names=type_names())
Beispiel #21
0
def get_projects(category):
    """Utility to get projects based on category. Should be moved on the API
    and improved with more extensive filtering capabilities.
    """
    api = SystemUtility.attract_api()
    node_type = NodeType.find_first({
        'where': '{"name" : "project"}',
        'projection': '{"name": 1}'
        }, api=api)
    projects = Node.all({
        'where': '{"node_type" : "%s", \
            "properties.category": "%s"}' % (node_type._id, category),
        'embedded': '{"picture":1}',
        }, api=api)
    for project in projects._items:
        attach_project_pictures(project, api)
    return projects
Beispiel #22
0
def index(node_type_name=""):
    """Generic function to list all nodes
    """
    # Pagination index
    page = request.args.get('page', 1)
    max_results = 50

    api = SystemUtility.attract_api()
    if node_type_name == "":
        node_type_name = "shot"

    node_type = NodeType.find_first({
        'where': '{"name" : "%s"}' % node_type_name,
        }, api=api)

    if not node_type:
        return "Empty NodeType list", 200

    nodes = Node.all({
        'where': '{"node_type" : "%s"}' % (node_type._id),
        'max_results': max_results,
        'page': page,
        'embedded': '{"picture":1}',
        'sort' : "order"}, api=api)

    # Build the pagination object
    pagination = Pagination(int(page), max_results, nodes._meta.total)

    template = '{0}/index.html'.format(node_type_name)
    try:
        return render_template(
            template,
            title=node_type_name,
            nodes=nodes,
            node_type=node_type,
            type_names=type_names(),
            pagination=pagination)
    except TemplateNotFound:
        return render_template(
            'nodes/index.html',
            title=node_type_name,
            nodes=nodes,
            node_type=node_type,
            type_names=type_names(),
            pagination=pagination)
Beispiel #23
0
def delete(node_id):
    """Generic node deletion
    """
    api = SystemUtility.attract_api()
    node = Node.find(node_id, api=api)
    name = node.name
    node_type = NodeType.find(node.node_type, api=api)
    try:
        node.delete(api=api)
        forbidden = False
    except ForbiddenAccess:
        forbidden = True

    if not forbidden:
        # print (node_type['name'])
        return redirect(url_for('nodes.index', node_type_name=node_type['name']))
    else:
        return redirect(url_for('nodes.edit', node_id=node._id))
Beispiel #24
0
def add(node_type_id):
    """Generic function to add a node of any type
    """
    api = SystemUtility.attract_api()
    ntype = NodeType.find(node_type_id, api=api)
    form = get_node_form(ntype)
    user_id = current_user.objectid
    if form.validate_on_submit():
        if process_node_form(form, node_type=ntype, user=user_id):
            return redirect(
                url_for('nodes.index', node_type_name=ntype['name']))
    else:
        print form.errors
    return render_template('nodes/add.html',
                           node_type=ntype,
                           form=form,
                           errors=form.errors,
                           type_names=type_names())
Beispiel #25
0
def posts_view(project_id, url=None):
    """View individual blogpost"""
    api = SystemUtility.attract_api()
    node_type = NodeType.find_first(
        {
            'where': '{"name" : "blog"}',
            'projection': '{"name": 1}'
        }, api=api)
    blog = Node.find_one(
        {
            'where':
            '{"node_type" : "%s", \
            "parent": "%s"}' % (node_type._id, project_id),
        },
        api=api)
    if url:
        try:
            post = Node.find_one(
                {
                    'where':
                    '{"parent": "%s", "properties.url": "%s"}' %
                    (blog._id, url),
                    'embedded':
                    '{"picture":1, "node_type": 1}',
                },
                api=api)
        except ResourceNotFound:
            return abort(404)

        return render_template('nodes/custom/post/view.html',
                               blog=blog,
                               node=post)
    else:
        # Render all posts
        posts = Node.all(
            {
                'where': '{"parent": "%s"}' % (blog._id),
                'embedded': '{"picture":1}',
                'sort': '-_created'
            },
            api=api)
        return render_template('nodes/custom/blog/index.html',
                               blog=blog,
                               posts=posts._items)
Beispiel #26
0
def delete(node_id):
    """Generic node deletion
    """
    api = system_util.pillar_api()
    node = Node.find(node_id, api=api)
    name = node.name
    node_type = NodeType.find(node.node_type, api=api)
    try:
        node.delete(api=api)
        forbidden = False
    except ForbiddenAccess:
        forbidden = True

    if not forbidden:
        # print (node_type['name'])
        return redirect(
            url_for('nodes.index', node_type_name=node_type['name']))
    else:
        return redirect(url_for('nodes.edit', node_id=node._id))
Beispiel #27
0
    def project(self, project_name):
        """Get single project for one user. The project is searched by looking
        up project directly associated with that user or organization."""
        # Find node_type project id (this could become static)
        node_type = NodeType.find_first({
            'where': '{"name" : "project"}',
            }, api=self.api)
        if not node_type: return abort(404)


        # Define key for querying for the project
        if self.is_organization:
            user_path = 'properties.organization'
        else:
            user_path = 'user'

        project_node = Node.find_first({
        'where': '{"node_type" : "%s", "properties.url" : "%s", "%s": "%s"}'\
            % (node_type._id, project_name, user_path, self._id),
        }, api=self.api)
        if not project_node: return abort(404)
        return project_node
Beispiel #28
0
    def project(self, project_name):
        """Get single project for one user. The project is searched by looking
        up project directly associated with that user or organization."""
        # Find node_type project id (this could become static)
        node_type = NodeType.find_first({
            'where': '{"name" : "project"}',
        },
                                        api=self.api)
        if not node_type: return abort(404)

        # Define key for querying for the project
        if self.is_organization:
            user_path = 'properties.organization'
        else:
            user_path = 'user'

        project_node = Node.find_first({
        'where': '{"node_type" : "%s", "properties.url" : "%s", "%s": "%s"}'\
            % (node_type._id, project_name, user_path, self._id),
        }, api=self.api)
        if not project_node: return abort(404)
        return project_node
Beispiel #29
0
def get_projects(category):
    """Utility to get projects based on category. Should be moved on the API
    and improved with more extensive filtering capabilities.
    """
    api = SystemUtility.attract_api()
    node_type = NodeType.find_first(
        {
            'where': '{"name" : "project"}',
            'projection': '{"name": 1}'
        },
        api=api)
    projects = Node.all(
        {
            'where':
            '{"node_type" : "%s", \
            "properties.category": "%s"}' % (node_type._id, category),
            'embedded':
            '{"picture":1}',
        },
        api=api)
    for project in projects._items:
        attach_project_pictures(project, api)
    return projects
Beispiel #30
0
def task_add():
    api = system_util.pillar_api()
    shot_id = request.form['shot_id']
    task_name = request.form['task_name']

    node_type_list = NodeType.all({
        'where': "name=='task'",
    }, api=api)
    node_type = node_type_list['_items'][0]

    node_type_id = node_type._id
    import datetime

    RFC1123_DATE_FORMAT = '%a, %d %b %Y %H:%M:%S GMT'
    node = Node()
    prop = {}
    prop['node_type'] = node_type_id
    prop['name'] = task_name
    prop['description'] = ''
    prop['user'] = current_user.objectid
    prop['parent'] = shot_id
    prop['properties'] = {
        'status': 'todo',
        'owners': {
            'users': [],
            'groups': []
        },
        'time': {
            'duration':
            10,
            'start':
            datetime.datetime.strftime(datetime.datetime.now(),
                                       '%a, %d %b %Y %H:%M:%S GMT')
        }
    }
    post = node.post(prop, api=api)
    return jsonify(node.to_dict())
Beispiel #31
0
def comments_index():
    parent_id = request.args.get('parent_id')

    if request.args.get('format'):

        # Get data only if we format it
        api = SystemUtility.attract_api()
        node_type = NodeType.find_first({
            'where': '{"name" : "comment"}',
            }, api=api)

        nodes = Node.all({
            'where': '{"node_type" : "%s", "parent": "%s"}' % (node_type._id, parent_id),
            'embedded': '{"user":1}'}, api=api)

        comments = []
        for comment in nodes._items:

            # Query for first level children (comment replies)
            replies = Node.all({
                'where': '{"node_type" : "%s", "parent": "%s"}' % (node_type._id, comment._id),
                'embedded': '{"user":1}'}, api=api)
            replies = replies._items if replies._items else None

            if replies:
                replies = [format_comment(reply, is_reply=True) for reply in replies]

            comments.append(
                format_comment(comment, is_reply=False, replies=replies))

        if request.args.get('format') == 'json':
            return_content = jsonify(items=comments)
    else:
        # Data will be requested via javascript
        return_content = render_template('nodes/custom/_comments.html',
            parent_id=parent_id)
    return return_content
Beispiel #32
0
def edit(node_id):
    """Generic node editing form
    """
    def set_properties(dyn_schema,
                       form_schema,
                       node_properties,
                       form,
                       prefix="",
                       set_data=True):
        """Initialize custom properties for the form. We run this function once
        before validating the function with set_data=False, so that we can set
        any multiselect field that was originally specified empty and fill it
        with the current choices.
        """
        for prop in dyn_schema:
            if not prop in node_properties:
                continue
            schema_prop = dyn_schema[prop]
            form_prop = form_schema[prop]
            prop_name = "{0}{1}".format(prefix, prop)
            if schema_prop['type'] == 'dict':
                set_properties(schema_prop['schema'], form_prop['schema'],
                               node_properties[prop_name], form,
                               "{0}__".format(prop_name))
            else:
                try:
                    data = node_properties[prop]
                except KeyError:
                    print("{0} not found in form".format(prop_name))
                if schema_prop['type'] == 'datetime':
                    data = datetime.strptime(data, RFC1123_DATE_FORMAT)
                if prop_name in form:
                    # Other field types
                    if isinstance(form[prop_name], SelectMultipleField):
                        # If we are dealing with a multiselect field, check if
                        # it's empty (usually because we can't query the whole
                        # database to pick all the choices). If it's empty we
                        # populate the choices with the actual data.
                        if not form[prop_name].choices:
                            form[prop_name].choices = [(d, d) for d in data]
                            # Choices should be a tuple with value and name
                    # Assign data to the field
                    if set_data:
                        form[prop_name].data = data

    api = SystemUtility.attract_api()
    node = Node.find(node_id, api=api)
    # TODO: simply embed node_type
    node_type = NodeType.find(node.node_type, api=api)
    form = get_node_form(node_type)
    user_id = current_user.objectid
    dyn_schema = node_type['dyn_schema'].to_dict()
    form_schema = node_type['form_schema'].to_dict()
    error = ""
    node_type_name = node_type.name

    node_properties = node.properties.to_dict()

    set_properties(dyn_schema,
                   form_schema,
                   node_properties,
                   form,
                   set_data=False)

    if form.validate_on_submit():
        if process_node_form(form,
                             node_id=node_id,
                             node_type=node_type,
                             user=user_id):
            project_update_nodes_list(node_id)
            return redirect(url_for('nodes.view', node_id=node_id, embed=1))
        else:
            error = "Server error"
            print("Error sending data")
    else:
        print form.errors

    # Populate Form
    form.name.data = node.name
    form.description.data = node.description
    if 'picture' in form:
        form.picture.data = node.picture
    if node.parent:
        form.parent.data = node.parent

    set_properties(dyn_schema, form_schema, node_properties, form)

    # Get Parent
    try:
        parent = Node.find(node['parent'], api=api)
    except KeyError:
        parent = None
    except ResourceNotFound:
        parent = None

    embed_string = ''
    # Check if we want to embed the content via an AJAX call
    if request.args.get('embed'):
        if request.args.get('embed') == '1':
            # Define the prefix for the embedded template
            embed_string = '_embed'

    template = '{0}/edit{1}.html'.format(node_type['name'], embed_string)

    # We should more simply check if the template file actually exsists on
    # the filesystem level
    try:
        return render_template(template,
                               node=node,
                               parent=parent,
                               form=form,
                               errors=form.errors,
                               error=error)
    except TemplateNotFound:
        template = 'nodes/edit{1}.html'.format(node_type['name'], embed_string)
        return render_template(template,
                               node=node,
                               parent=parent,
                               form=form,
                               errors=form.errors,
                               error=error)
Beispiel #33
0
def assets_create():
    name = request.form['name']
    parent_id = request.form.get('parent_id')
    # Detect filetype by extension (improve by detectin real file type)
    root, ext = os.path.splitext(name)
    if ext in ['.jpg', '.jpeg', '.png', '.tif', '.tiff']:
        filetype = 'image'
    elif ext in ['.blend', '.txt', '.zip']:
        filetype = 'file'
    elif ext in ['.mov', '.avi', '.mp4', '.m4v']:
        filetype = 'video'
    else:
        filetype = 'file'
    # Hash name based on file name, user id and current timestamp
    hash_name = name + str(current_user.objectid) + str(round(time.time()))
    link = hashlib.sha1(hash_name).hexdigest()
    link = os.path.join(link[:2], link + ext)

    api = SystemUtility.attract_api()
    node_type = NodeType.find_first({
        'where': '{"name" : "asset"}',
    }, api=api)
    # We will create the Node object later on, after creating the file object
    node_asset_props = dict(
        name=name,
        #description=a.description,
        #picture=picture,
        user=current_user.objectid,
        node_type=node_type._id,
        #parent=node_parent,
        properties=dict(
            content_type=filetype,
            #file=a.link[4:],
            status='processing'))

    src_dir_path = os.path.join(app.config['UPLOAD_DIR'],
                                str(current_user.objectid))

    # Move the file in designated location
    destination_dir = os.path.join(app.config['SHARED_DIR'], link[:2])
    if not os.path.isdir(destination_dir):
        os.makedirs(destination_dir)
    # (TODO) Check if filename already exsits
    src_file_path = os.path.join(src_dir_path, name)
    dst_file_path = os.path.join(destination_dir, link[3:])
    # (TODO) Thread this operation

    shutil.copy(src_file_path, dst_file_path)

    if filetype == 'file':
        mime_type = 'application'
    else:
        mime_type = filetype
    content_type = "{0}/{1}".format(mime_type, ext.replace(".", ""))

    node_file = File({
        'name': link,
        'filename': name,
        'user': current_user.objectid,
        'backend': 'cdnsun',
        'md5': '',
        'content_type': content_type,
        'length': 0
    })

    node_file.create(api=api)

    node_asset_props['properties']['file'] = node_file._id
    if parent_id:
        node_asset_props['parent'] = parent_id
    node_asset = Node(node_asset_props)
    node_asset.create(api=api)

    return jsonify(link=link,
                   name=name,
                   filetype=filetype,
                   asset_id=node_asset._id)
Beispiel #34
0
def index():
    """Display the node types
    """
    node_types = NodeType.all()
    node_types = node_types["_items"]
    return render_template("node_types/index.html", title="node_types", node_types=node_types)
Beispiel #35
0
def shots_index():
    max_results = 100

    api = system_util.pillar_api()
    node_type_name = "shot"
    node_type_list = NodeType.all(
        {
            'where': '{"name" : "%s"}' % node_type_name,
        }, api=api)

    node_type = node_type_list._items[0]

    nodes = Node.all(
        {
            'where': '{"node_type" : "%s"}' % node_type._id,
            'max_results': max_results,
            'embedded': '{"picture":1}',
            'sort': "order"
        },
        api=api)

    # Get the task node type object id
    node_type_list = NodeType.all({
        'where': '{"name" : "task"}',
    }, api=api)
    node_type_task = node_type_list._items[0]

    nodes_datatables = []
    for node in nodes._items:
        tasks = Node.all({
            'where': '{"node_type" : "%s", "parent" : "%s"}'\
                    % (node_type_task._id, node._id),
            'sort' : "order"}, api=api)

        shot_status = None

        try:
            shot_status = node.properties.status
        except:
            # Notify about missing status property. This should be prominent.
            pass

        data = {
            'DT_RowId': "row_{0}".format(node._id),
            'DT_RowAttr': {
                'data-shot-status': shot_status
            },
            '_id': node._id,
            'order': node.order,
            'picture': None,
            'name': node.name,
            #'description': node.description,
            'notes': node.properties.notes,
            'timing': {
                'cut_in': node.properties.cut_in,
                'cut_out': node.properties.cut_out
            },
            'url_view': url_for('nodes.view', node_id=node._id),
            'url_edit': url_for('nodes.edit', node_id=node._id, embed=1),
            'tasks': {
                'animation': None,
                'lighting': None,
                'fx_hair': None,
                'fx_grass': None,
                'fx_smoke': None
            },
        }

        if node.picture:
            # This is an address on the Attract server, so it should be built
            # entirely here
            data['picture'] = "{0}/file_server/file/{1}".format(
                app.config['PILLAR_SERVER_ENDPOINT'], node.picture.path)
            # Get previews
            picture_node = File.find(node.picture['_id'] + \
                                    '/?embedded={"previews":1}', api=api)

            if picture_node.previews:
                for preview in picture_node.previews:
                    if preview.size == 'm':
                        data['picture_thumbnail'] = app.config[
                            'PILLAR_SERVER_ENDPOINT'] + "/file_server/file/" + preview.path
                        break
            else:
                data['picture_thumbnail'] = data['picture']

        if node.order is None:
            data['order'] = 0

        for task in tasks._items:
            # If there are tasks assigned to the shot we loop through them and
            # match them with the existing data indexes.
            if task.name in data['tasks']:
                data['tasks'][task.name] = {
                    'name': task.name,
                    'status': task.properties.status,
                    'url_view': url_for('nodes.view',
                                        node_id=task._id,
                                        embed=1),
                    'url_edit': url_for('nodes.edit',
                                        node_id=task._id,
                                        embed=1),
                    'is_conflicting': task.properties.is_conflicting,
                    'is_processing': task.properties.is_rendering,
                    'is_open': task.properties.is_open
                }

        nodes_datatables.append(data)

    return jsonify(data=nodes_datatables)
Beispiel #36
0
def shots_index():
    max_results = 100

    api = system_util.pillar_api()
    node_type_name = "shot"
    node_type_list = NodeType.all({
        'where': '{"name" : "%s"}' % node_type_name,
        }, api=api)

    node_type = node_type_list._items[0]

    nodes = Node.all({
        'where': '{"node_type" : "%s"}' % node_type._id,
        'max_results': max_results,
        'embedded': '{"picture":1}',
        'sort' : "order"}, api=api)

    # Get the task node type object id
    node_type_list = NodeType.all({
        'where': '{"name" : "task"}',
        }, api=api)
    node_type_task = node_type_list._items[0]

    nodes_datatables = []
    for node in nodes._items:
        tasks = Node.all({
            'where': '{"node_type" : "%s", "parent" : "%s"}'\
                    % (node_type_task._id, node._id),
            'sort' : "order"}, api=api)

        shot_status = None

        try:
            shot_status = node.properties.status
        except:
            # Notify about missing status property. This should be prominent.
            pass

        data = {
            'DT_RowId': "row_{0}".format(node._id),
            'DT_RowAttr': {'data-shot-status':shot_status},
            '_id': node._id,
            'order': node.order,
            'picture': None,
            'name': node.name,
            #'description': node.description,
            'notes': node.properties.notes,
            'timing': {
                'cut_in': node.properties.cut_in,
                'cut_out': node.properties.cut_out
                },
            'url_view': url_for('nodes.view', node_id=node._id),
            'url_edit': url_for('nodes.edit', node_id=node._id, embed=1),
            'tasks': {
                'animation': None,
                'lighting': None,
                'fx_hair': None,
                'fx_grass': None,
                'fx_smoke': None
                },
            }

        if node.picture:
            # This is an address on the Attract server, so it should be built
            # entirely here
            data['picture'] = "{0}/file_server/file/{1}".format(
                app.config['PILLAR_SERVER_ENDPOINT'], node.picture.path)
            # Get previews
            picture_node = File.find(node.picture['_id'] + \
                                    '/?embedded={"previews":1}', api=api)

            if picture_node.previews:
                for preview in picture_node.previews:
                    if preview.size == 'm':
                        data['picture_thumbnail'] = app.config['PILLAR_SERVER_ENDPOINT'] + "/file_server/file/" + preview.path
                        break
            else:
                data['picture_thumbnail'] = data['picture']


        if node.order is None:
            data['order'] = 0

        for task in tasks._items:
            # If there are tasks assigned to the shot we loop through them and
            # match them with the existing data indexes.
            if task.name in data['tasks']:
                data['tasks'][task.name] = {
                'name': task.name,
                'status': task.properties.status,
                'url_view': url_for('nodes.view', node_id=task._id, embed=1),
                'url_edit': url_for('nodes.edit', node_id=task._id, embed=1),
                'is_conflicting': task.properties.is_conflicting,
                'is_processing': task.properties.is_rendering,
                'is_open': task.properties.is_open
                }


        nodes_datatables.append(data)

    return jsonify(data=nodes_datatables)
Beispiel #37
0
def edit(node_id):
    """Generic node editing form
    """
    def set_properties(
            dyn_schema, form_schema, node_properties, form, prefix="", set_data=True):
        """Initialize custom properties for the form. We run this function once
        before validating the function with set_data=False, so that we can set
        any multiselect field that was originally specified empty and fill it
        with the current choices.
        """
        for prop in dyn_schema:
            if not prop in node_properties:
                continue
            schema_prop = dyn_schema[prop]
            form_prop = form_schema[prop]
            prop_name = "{0}{1}".format(prefix, prop)
            if schema_prop['type'] == 'dict':
                set_properties(
                    schema_prop['schema'],
                    form_prop['schema'],
                    node_properties[prop_name],
                    form,
                    "{0}__".format(prop_name))
            else:
                try:
                    data = node_properties[prop]
                except KeyError:
                    print ("{0} not found in form".format(prop_name))
                if schema_prop['type'] == 'datetime':
                    data = datetime.strptime(data, RFC1123_DATE_FORMAT)
                if prop_name in form:
                    # Other field types
                    if isinstance(form[prop_name], SelectMultipleField):
                        # If we are dealing with a multiselect field, check if
                        # it's empty (usually because we can't query the whole
                        # database to pick all the choices). If it's empty we
                        # populate the choices with the actual data.
                        if not form[prop_name].choices:
                            form[prop_name].choices = [(d,d) for d in data]
                            # Choices should be a tuple with value and name
                    # Assign data to the field
                    if set_data:
                        form[prop_name].data = data

    api = SystemUtility.attract_api()
    node = Node.find(node_id, api=api)
    # TODO: simply embed node_type
    node_type = NodeType.find(node.node_type, api=api)
    form = get_node_form(node_type)
    user_id = current_user.objectid
    dyn_schema = node_type['dyn_schema'].to_dict()
    form_schema = node_type['form_schema'].to_dict()
    error = ""
    node_type_name = node_type.name

    node_properties = node.properties.to_dict()

    set_properties(dyn_schema, form_schema, node_properties, form, set_data=False)

    if form.validate_on_submit():
        if process_node_form(
                form, node_id=node_id, node_type=node_type, user=user_id):
            project_update_nodes_list(node_id)
            return redirect(url_for('nodes.view', node_id=node_id, embed=1))
        else:
            error = "Server error"
            print ("Error sending data")
    else:
        print form.errors

    # Populate Form
    form.name.data = node.name
    form.description.data = node.description
    if 'picture' in form:
        form.picture.data = node.picture
    if node.parent:
        form.parent.data = node.parent

    set_properties(dyn_schema, form_schema, node_properties, form)

    # Get Parent
    try:
        parent = Node.find(node['parent'], api=api)
    except KeyError:
        parent = None
    except ResourceNotFound:
        parent = None

    embed_string = ''
    # Check if we want to embed the content via an AJAX call
    if request.args.get('embed'):
        if request.args.get('embed') == '1':
            # Define the prefix for the embedded template
            embed_string = '_embed'

    template = '{0}/edit{1}.html'.format(node_type['name'], embed_string)

    # We should more simply check if the template file actually exsists on
    # the filesystem level
    try:
        return render_template(
                template,
                node=node,
                parent=parent,
                form=form,
                errors=form.errors,
                error=error)
    except TemplateNotFound:
        template = 'nodes/edit{1}.html'.format(node_type['name'], embed_string)
        return render_template(
                template,
                node=node,
                parent=parent,
                form=form,
                errors=form.errors,
                error=error)
Beispiel #38
0
def assets_create():
    name = request.form['name']
    parent_id = request.form.get('parent_id')
    # Detect filetype by extension (improve by detectin real file type)
    root, ext = os.path.splitext(name)
    if ext in ['.jpg', '.jpeg', '.png', '.tif', '.tiff']:
        filetype = 'image'
    elif ext in ['.blend', '.txt', '.zip']:
        filetype = 'file'
    elif ext in ['.mov', '.avi', '.mp4', '.m4v']:
        filetype = 'video'
    else:
        filetype = 'file'
    # Hash name based on file name, user id and current timestamp
    hash_name = name + str(current_user.objectid) + str(round(time.time()))
    link = hashlib.sha1(hash_name).hexdigest()
    link = os.path.join(link[:2], link + ext)

    api = SystemUtility.attract_api()
    node_type = NodeType.find_first({
        'where': '{"name" : "asset"}',
        }, api=api)
    # We will create the Node object later on, after creating the file object
    node_asset_props = dict(
        name=name,
        #description=a.description,
        #picture=picture,
        user=current_user.objectid,
        node_type=node_type._id,
        #parent=node_parent,
        properties=dict(
            content_type=filetype,
            #file=a.link[4:],
            status='processing'))

    src_dir_path = os.path.join(app.config['UPLOAD_DIR'], str(current_user.objectid))

    # Move the file in designated location
    destination_dir = os.path.join(app.config['SHARED_DIR'], link[:2])
    if not os.path.isdir(destination_dir):
        os.makedirs(destination_dir)
    # (TODO) Check if filename already exsits
    src_file_path = os.path.join(src_dir_path, name)
    dst_file_path = os.path.join(destination_dir, link[3:])
    # (TODO) Thread this operation

    shutil.copy(src_file_path, dst_file_path)

    if filetype == 'file':
        mime_type = 'application'
    else:
        mime_type = filetype
    content_type = "{0}/{1}".format(mime_type, ext.replace(".", ""))

    node_file = File({
        'name': link,
        'filename': name,
        'user': current_user.objectid,
        'backend': 'cdnsun',
        'md5': '',
        'content_type': content_type,
        'length': 0
        })

    node_file.create(api=api)

    node_asset_props['properties']['file'] = node_file._id
    if parent_id:
        node_asset_props['parent'] = parent_id
    node_asset = Node(node_asset_props)
    node_asset.create(api=api)

    return jsonify(
        link=link,
        name=name,
        filetype=filetype,
        asset_id=node_asset._id)