Exemple #1
0
def homepage():
    """Homepage"""

    if not current_user.is_authenticated():
        return render_template(
            'join.html',
            title="join")

    # Get latest blog posts
    api = system_util.pillar_api()
    latest_posts = Node.all({
        'projection': {'name': 1, 'project': 1, 'user': 1, 'node_type': 1,
                       'picture': 1, 'properties.status': 1, 'properties.url': 1},
        'where': {'node_type': 'post', 'properties.status': 'published'},
        'embedded': {'user': 1, 'project': 1},
        'sort': '-_created',
        'max_results': '3'
        }, api=api)

    # Append picture Files to last_posts
    for post in latest_posts._items:
        if post.picture:
            post.picture = get_file(post.picture, api=api)

    # Get latest assets added to any project
    latest_assets = Node.latest('assets', api=api)

    # Append picture Files to latest_assets
    for asset in latest_assets._items:
        if asset.picture:
            asset.picture = get_file(asset.picture, api=api)

    # Get latest comments to any node
    latest_comments = Node.latest('comments', api=api)

    # Parse results for replies
    for comment in latest_comments._items:
        if comment.properties.is_reply:
            comment.parent = Node.find(comment.parent.parent, api=api)
        else:
            comment.parent = comment.parent

    main_project = Project.find(app.config['MAIN_PROJECT_ID'], api=api)
    main_project.picture_square = get_file(main_project.picture_square, api=api)
    main_project.picture_header = get_file(main_project.picture_header, api=api)

    return render_template(
        'homepage.html',
        main_project=main_project,
        latest_posts=latest_posts._items,
        latest_assets=latest_assets._items,
        latest_comments=latest_comments._items,
        api=api)
Exemple #2
0
def _view_handler_texture(node, template_path, template_action, link_allowed):
    for f in node.properties.files:
        f.file = get_file(f.file)

        # Remove the link to the file if it's not allowed.
        if f.file and not link_allowed:
            f.file.link = None

    return template_path, template_action
Exemple #3
0
def _view_handler_texture(node, template_path, template_action, link_allowed):
    for f in node.properties.files:
        f.file = get_file(f.file)

        # Remove the link to the file if it's not allowed.
        if f.file and not link_allowed:
            f.file.link = None

    return template_path, template_action
Exemple #4
0
def posts_edit(post_id):
    api = system_util.pillar_api()

    try:
        post = Node.find(post_id, {'embedded': '{"user": 1}'}, api=api)
    except ResourceNotFound:
        return abort(404)
    # Check if user is allowed to edit the post
    if not post.has_method('PUT'):
        return abort(403)

    project = Project.find(post.project, api=api)
    attach_project_pictures(project, api)

    node_type = project.get_node_type(post.node_type)
    form = get_node_form(node_type)
    if form.validate_on_submit():
        if process_node_form(form,
                             node_id=post_id,
                             node_type=node_type,
                             user=current_user.objectid):
            # The the post is published, add it to the list
            if form.status.data == 'published':
                project_update_nodes_list(post,
                                          project_id=project._id,
                                          list_name='blog')
            return redirect(url_for_node(node=post))
    form.parent.data = post.parent
    form.name.data = post.name
    form.content.data = post.properties.content
    form.status.data = post.properties.status
    form.url.data = post.properties.url
    if post.picture:
        form.picture.data = post.picture
        # Embed picture file
        post.picture = get_file(post.picture, api=api)
    if post.properties.picture_square:
        form.picture_square.data = post.properties.picture_square
    return render_template('nodes/custom/post/edit.html',
                           node_type=node_type,
                           post=post,
                           form=form,
                           project=project,
                           api=api)
Exemple #5
0
def _view_handler_asset(node, template_path, template_action, link_allowed):
    # Attach the file document to the asset node
    node_file = get_file(node.properties.file)
    node.file = node_file

    # Remove the link to the file if it's not allowed.
    if node_file and not link_allowed:
        node.file.link = None

    if node_file and node_file.content_type is not None:
        asset_type = node_file.content_type.split('/')[0]
    else:
        asset_type = None

    if asset_type == 'video':
        # Process video type and select video template
        if link_allowed:
            sources = []
            if node_file and node_file.variations:
                for f in node_file.variations:
                    sources.append({'type': f.content_type, 'src': f.link})
                    # Build a link that triggers download with proper filename
                    # TODO: move this to Pillar
                    if f.backend == 'cdnsun':
                        f.link = "{0}&name={1}.{2}".format(
                            f.link, node.name, f.format)
            node.video_sources = json.dumps(sources)
            node.file_variations = node_file.variations
        else:
            node.video_sources = None
            node.file_variations = None
    elif asset_type != 'image':
        # Treat it as normal file (zip, blend, application, etc)
        asset_type = 'file'

    template_path = os.path.join(template_path, asset_type)

    return template_path, template_action
Exemple #6
0
def _view_handler_asset(node, template_path, template_action, link_allowed):
    # Attach the file document to the asset node
    node_file = get_file(node.properties.file)
    node.file = node_file

    # Remove the link to the file if it's not allowed.
    if node_file and not link_allowed:
        node.file.link = None

    if node_file and node_file.content_type is not None:
        asset_type = node_file.content_type.split('/')[0]
    else:
        asset_type = None

    if asset_type == 'video':
        # Process video type and select video template
        if link_allowed:
            sources = []
            if node_file and node_file.variations:
                for f in node_file.variations:
                    sources.append({'type': f.content_type, 'src': f.link})
                    # Build a link that triggers download with proper filename
                    # TODO: move this to Pillar
                    if f.backend == 'cdnsun':
                        f.link = "{0}&name={1}.{2}".format(f.link, node.name, f.format)
            node.video_sources = json.dumps(sources)
            node.file_variations = node_file.variations
        else:
            node.video_sources = None
            node.file_variations = None
    elif asset_type != 'image':
        # Treat it as normal file (zip, blend, application, etc)
        asset_type = 'file'

    template_path = os.path.join(template_path, asset_type)

    return template_path, template_action
Exemple #7
0
def posts_view(project_id, url=None):
    """View individual blogpost"""
    api = system_util.pillar_api()
    # Fetch project (for backgroud images and links generation)
    project = Project.find(project_id, api=api)
    attach_project_pictures(project, api)
    try:
        blog = Node.find_one(
            {
                'where': {
                    'node_type': 'blog',
                    'project': project_id
                },
            }, api=api)
    except ResourceNotFound:
        abort(404)
    if url:
        try:
            post = Node.find_one(
                {
                    'where':
                    '{"parent": "%s", "properties.url": "%s"}' %
                    (blog._id, url),
                    'embedded':
                    '{"node_type": 1, "user": 1}',
                },
                api=api)
            if post.picture:
                post.picture = get_file(post.picture, api=api)
        except ResourceNotFound:
            return abort(404)

        # If post is not published, check that the user is also the author of
        # the post. If not, return 404.
        if post.properties.status != "published":
            if current_user.is_authenticated():
                if not post.has_method('PUT'):
                    abort(403)
            else:
                abort(403)

        return render_template('nodes/custom/post/view.html',
                               blog=blog,
                               node=post,
                               project=project,
                               title='blog',
                               api=api)
    else:
        node_type_post = project.get_node_type('post')
        status_query = "" if blog.has_method(
            'PUT') else ', "properties.status": "published"'
        posts = Node.all(
            {
                'where': '{"parent": "%s" %s}' % (blog._id, status_query),
                'embedded': '{"user": 1}',
                'sort': '-_created'
            },
            api=api)

        for post in posts._items:
            post.picture = get_file(post.picture, api=api)

        return render_template('nodes/custom/blog/index.html',
                               node_type_post=node_type_post,
                               posts=posts._items,
                               project=project,
                               title='blog',
                               api=api)
Exemple #8
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:
            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))
                continue

            if prop_name not in form:
                continue

            try:
                db_prop_value = node_properties[prop]
            except KeyError:
                log.debug('%s not found in form for node %s', prop_name,
                          node_id)
                continue

            if schema_prop['type'] == 'datetime':
                db_prop_value = datetime.strptime(
                    db_prop_value, app.config['RFC1123_DATE_FORMAT'])

            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 db_prop_value]
                    # Choices should be a tuple with value and name

            # Assign data to the field
            if set_data:
                if prop_name == 'attachments':
                    for attachment_collection in db_prop_value:
                        for a in attachment_collection['files']:
                            attachment_form = ProceduralFileSelectForm()
                            attachment_form.file = a['file']
                            attachment_form.slug = a['slug']
                            attachment_form.size = 'm'
                            form[prop_name].append_entry(attachment_form)

                elif prop_name == 'files':
                    schema = schema_prop['schema']['schema']
                    # Extra entries are caused by min_entries=1 in the form
                    # creation.
                    field_list = form[prop_name]
                    if len(db_prop_value) > 0:
                        while len(field_list):
                            field_list.pop_entry()

                    for file_data in db_prop_value:
                        file_form_class = build_file_select_form(schema)
                        subform = file_form_class()
                        for key, value in file_data.iteritems():
                            setattr(subform, key, value)
                        field_list.append_entry(subform)

                # elif prop_name == 'tags':
                #     form[prop_name].data = ', '.join(data)
                else:
                    form[prop_name].data = db_prop_value
            else:
                # Default population of multiple file form list (only if
                # we are getting the form)
                if request.method == 'POST':
                    continue
                if prop_name == 'attachments':
                    if not db_prop_value:
                        attachment_form = ProceduralFileSelectForm()
                        attachment_form.file = 'file'
                        attachment_form.slug = ''
                        attachment_form.size = ''
                        form[prop_name].append_entry(attachment_form)

    api = system_util.pillar_api()
    node = Node.find(node_id, api=api)
    project = Project.find(node.project, api=api)
    node_type = project.get_node_type(node.node_type)
    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_properties = node.properties.to_dict()

    ensure_lists_exist_as_empty(node.to_dict(), node_type)
    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):
            # Handle the specific case of a blog post
            if node_type.name == 'post':
                project_update_nodes_list(node, list_name='blog')
            else:
                project_update_nodes_list(node)
            # Emergency hardcore cache flush
            # cache.clear()
            return redirect(
                url_for('nodes.view',
                        node_id=node_id,
                        embed=1,
                        _external=True,
                        _scheme=app.config['SCHEME']))
        else:
            log.debug('Error sending data to Pillar, see Pillar logs.')
            error = 'Server error'
    else:
        if form.errors:
            log.debug('Form errors: %s', 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 previews
    node.picture = get_file(node.picture, api=api) if node.picture else None

    # 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,
                               api=api)
    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,
                               api=api)
Exemple #9
0
def view(node_id):
    api = system_util.pillar_api()

    # Get node, we'll embed linked objects later.
    try:
        node = Node.find(node_id, api=api)
    except ResourceNotFound:
        return render_template('errors/404_embed.html')
    except ForbiddenAccess:
        return render_template('errors/403_embed.html')

    node_type_name = node.node_type

    if node_type_name == 'post':
        # Posts shouldn't be shown using this end point, redirect to the correct one.
        return redirect(url_for_node(node=node))

    # Set the default name of the template path based on the node name
    template_path = os.path.join('nodes', 'custom', node_type_name)
    # Set the default action for a template. By default is view and we override
    # it only if we are working storage nodes, where an 'index' is also possible
    template_action = 'view'

    def allow_link():
        """Helper function to cross check if the user is authenticated, and it
        is has the 'subscriber' role. Also, we check if the node has world GET
        permissions, which means it's free.
        """

        # Check if node permissions for the world exist (if node is free)
        if node.permissions and node.permissions.world:
            return 'GET' in node.permissions.world

        if current_user.is_authenticated():
            allowed_roles = {u'subscriber', u'demo', u'admin'}
            return bool(allowed_roles.intersection(current_user.roles or ()))

        return False

    link_allowed = allow_link()

    node_type_handlers = {
        'asset': _view_handler_asset,
        'storage': _view_handler_storage,
        'texture': _view_handler_texture,
    }
    if node_type_name in node_type_handlers:
        handler = node_type_handlers[node_type_name]
        template_path, template_action = handler(node, template_path,
                                                 template_action, link_allowed)

    # Fetch linked resources.
    node.picture = get_file(node.picture, api=api)
    node.user = node.user and pillarsdk.User.find(node.user, api=api)
    node.parent = node.parent and pillarsdk.Node.find(node.parent, api=api)

    # Get children
    children_projection = {
        'project': 1,
        'name': 1,
        'picture': 1,
        'parent': 1,
        'node_type': 1,
        'properties.order': 1,
        'properties.status': 1,
        'user': 1,
        'properties.content_type': 1
    }
    children_where = {'parent': node._id}

    if node_type_name == 'group':
        children_where['properties.status'] = 'published'
        children_projection['permissions.world'] = 1
    else:
        children_projection['properties.files'] = 1
        children_projection['properties.is_tileable'] = 1

    try:
        children = Node.all(
            {
                'projection': children_projection,
                'where': children_where,
                'sort': [('properties.order', 1), ('name', 1)]
            },
            api=api)
    except ForbiddenAccess:
        return render_template('errors/403_embed.html')
    children = children._items

    for child in children:
        child.picture = get_file(child.picture, api=api)

    if request.args.get('format') == 'json':
        node = node.to_dict()
        node['url_edit'] = url_for('nodes.edit', node_id=node['_id']),
        return jsonify({
            'node': node,
            'children': children.to_dict(),
            'parent': node.parent.to_dict() if node.parent else {}
        })

    # Check if template exists on the filesystem
    template_path = '{0}/{1}_embed.html'.format(template_path, template_action)
    template_path_full = os.path.join(app.config['TEMPLATES_PATH'],
                                      template_path)

    if not os.path.exists(template_path_full):
        raise NotFound("Missing template '{0}'".format(template_path))

    return render_template(template_path,
                           node_id=node._id,
                           node=node,
                           parent=node.parent,
                           children=children,
                           config=app.config,
                           api=api)
Exemple #10
0
def homepage():
    """Homepage"""

    if not current_user.is_authenticated():
        return render_template('join.html', title="join")

    # Get latest blog posts
    api = system_util.pillar_api()
    latest_posts = Node.all(
        {
            'projection': {
                'name': 1,
                'project': 1,
                'user': 1,
                'node_type': 1,
                'picture': 1,
                'properties.status': 1,
                'properties.url': 1
            },
            'where': {
                'node_type': 'post',
                'properties.status': 'published'
            },
            'embedded': {
                'user': 1,
                'project': 1
            },
            'sort': '-_created',
            'max_results': '3'
        },
        api=api)

    # Append picture Files to last_posts
    for post in latest_posts._items:
        if post.picture:
            post.picture = get_file(post.picture, api=api)

    # Get latest assets added to any project
    latest_assets = Node.latest('assets', api=api)

    # Append picture Files to latest_assets
    for asset in latest_assets._items:
        if asset.picture:
            asset.picture = get_file(asset.picture, api=api)

    # Get latest comments to any node
    latest_comments = Node.latest('comments', api=api)

    # Parse results for replies
    for comment in latest_comments._items:
        if comment.properties.is_reply:
            comment.parent = Node.find(comment.parent.parent, api=api)
        else:
            comment.parent = comment.parent

    main_project = Project.find(app.config['MAIN_PROJECT_ID'], api=api)
    main_project.picture_square = get_file(main_project.picture_square,
                                           api=api)
    main_project.picture_header = get_file(main_project.picture_header,
                                           api=api)

    return render_template('homepage.html',
                           main_project=main_project,
                           latest_posts=latest_posts._items,
                           latest_assets=latest_assets._items,
                           latest_comments=latest_comments._items,
                           api=api)
Exemple #11
0
def view(project_url):
    """Entry point to view a project"""
    api = system_util.pillar_api()
    # Fetch the Node or 404
    try:
        project = Project.find_one({'where': {"url": project_url}}, api=api)
    except ResourceNotFound:
        abort(404)
    # Set up variables for processing
    user_id = 'ANONYMOUS' if current_user.is_anonymous() else str(current_user.objectid)
    rewrite_url = None
    embedded_node_id = None

    if request.args.get('redir') and request.args.get('redir') == '1':
        # Handle special cases (will be mainly used for items that are part
        # of the blog, or attract)
        if g.get('embedded_node')['node_type'] == 'post':
            # Very special case of the post belonging to the main project,
            # which is read from the configuration.
            if project._id == app.config['MAIN_PROJECT_ID']:
                return redirect(url_for('main_blog',
                    url=g.get('embedded_node')['properties']['url']))
            else:
                return redirect(url_for('project_blog',
                    project_url=project.url,
                    url=g.get('embedded_node')['properties']['url']))
        rewrite_url = "/p/{0}/#{1}".format(project.url,
            g.get('embedded_node')['_id'])
        embedded_node_id = g.get('embedded_node')['_id']

    if request.args.get('format') == 'jstree':
        return jsonify(items=jstree_get_children(None, project._id))

    project.picture_square = project.picture_square and get_file(project.picture_square, api=api)
    project.picture_header = project.picture_header and get_file(project.picture_header, api=api)
    embed_string = ''

    if request.args.get('embed'):
        embed_string = '_embed'
        list_latest = []
        if project.nodes_latest:
            for node_id in project.nodes_latest:
                try:
                    node_item = Node.find(node_id, {
                        'projection': '{"name":1, "user":1, "node_type":1, \
                            "project": 1}',
                        'embedded': '{"user":1}',
                        }, api=api)
                    list_latest.append(node_item)
                except ForbiddenAccess:
                    pass
        project.nodes_latest = list(reversed(list_latest))

        list_featured = []
        if project.nodes_featured:
            for node_id in project.nodes_featured:
                try:
                    node_item = Node.find(node_id, {
                        'projection': '{"name":1, "user":1, "picture":1, \
                            "node_type":1, "project": 1}',
                        'embedded': '{"user":1}',
                        }, api=api)
                    if node_item.picture:
                        picture = get_file(node_item.picture, api=api)
                        # picture = File.find(node_item.picture, api=api)
                        node_item.picture = picture
                    list_featured.append(node_item)
                except ForbiddenAccess:
                    pass
        project.nodes_featured = list(reversed(list_featured))

        list_blog = []
        if project.nodes_blog:
            for node_id in project.nodes_blog:
                try:
                    node_item = Node.find(node_id, {
                        # 'projection': '{"name":1, "user":1, "node_type":1}',
                        'embedded': '{"user":1}',
                        }, api=api)
                    list_blog.append(node_item)
                except ForbiddenAccess:
                    pass
        project.nodes_blog = list(reversed(list_blog))

    return render_template("projects/view{0}.html".format(embed_string),
                           embedded_node_id=embedded_node_id,
                           rewrite_url=rewrite_url,
                           user_string_id=user_id,
                           project=project,
                           api=api)
Exemple #12
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:
            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))
                continue

            if prop_name not in form:
                continue

            try:
                db_prop_value = node_properties[prop]
            except KeyError:
                log.debug('%s not found in form for node %s', prop_name, node_id)
                continue

            if schema_prop['type'] == 'datetime':
                db_prop_value = datetime.strptime(db_prop_value,
                                                  app.config['RFC1123_DATE_FORMAT'])

            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 db_prop_value]
                    # Choices should be a tuple with value and name

            # Assign data to the field
            if set_data:
                if prop_name == 'attachments':
                    for attachment_collection in db_prop_value:
                        for a in attachment_collection['files']:
                            attachment_form = ProceduralFileSelectForm()
                            attachment_form.file = a['file']
                            attachment_form.slug = a['slug']
                            attachment_form.size = 'm'
                            form[prop_name].append_entry(attachment_form)

                elif prop_name == 'files':
                    schema = schema_prop['schema']['schema']
                    # Extra entries are caused by min_entries=1 in the form
                    # creation.
                    field_list = form[prop_name]
                    if len(db_prop_value) > 0:
                        while len(field_list):
                            field_list.pop_entry()

                    for file_data in db_prop_value:
                        file_form_class = build_file_select_form(schema)
                        subform = file_form_class()
                        for key, value in file_data.iteritems():
                            setattr(subform, key, value)
                        field_list.append_entry(subform)

                # elif prop_name == 'tags':
                #     form[prop_name].data = ', '.join(data)
                else:
                    form[prop_name].data = db_prop_value
            else:
                # Default population of multiple file form list (only if
                # we are getting the form)
                if request.method == 'POST':
                    continue
                if prop_name == 'attachments':
                    if not db_prop_value:
                        attachment_form = ProceduralFileSelectForm()
                        attachment_form.file = 'file'
                        attachment_form.slug = ''
                        attachment_form.size = ''
                        form[prop_name].append_entry(attachment_form)

    api = system_util.pillar_api()
    node = Node.find(node_id, api=api)
    project = Project.find(node.project, api=api)
    node_type = project.get_node_type(node.node_type)
    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_properties = node.properties.to_dict()

    ensure_lists_exist_as_empty(node.to_dict(), node_type)
    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):
            # Handle the specific case of a blog post
            if node_type.name == 'post':
                project_update_nodes_list(node, list_name='blog')
            else:
                project_update_nodes_list(node)
            # Emergency hardcore cache flush
            # cache.clear()
            return redirect(url_for('nodes.view', node_id=node_id, embed=1,
                                    _external=True,
                                    _scheme=app.config['SCHEME']))
        else:
            log.debug('Error sending data to Pillar, see Pillar logs.')
            error = 'Server error'
    else:
        if form.errors:
            log.debug('Form errors: %s', 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 previews
    node.picture = get_file(node.picture, api=api) if node.picture else None

    # 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,
            api=api)
    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,
            api=api)
Exemple #13
0
def view(node_id):
    api = system_util.pillar_api()

    # Get node, we'll embed linked objects later.
    try:
        node = Node.find(node_id, api=api)
    except ResourceNotFound:
        return render_template('errors/404_embed.html')
    except ForbiddenAccess:
        return render_template('errors/403_embed.html')

    node_type_name = node.node_type

    if node_type_name == 'post':
        # Posts shouldn't be shown using this end point, redirect to the correct one.
        return redirect(url_for_node(node=node))

    # Set the default name of the template path based on the node name
    template_path = os.path.join('nodes', 'custom', node_type_name)
    # Set the default action for a template. By default is view and we override
    # it only if we are working storage nodes, where an 'index' is also possible
    template_action = 'view'

    def allow_link():
        """Helper function to cross check if the user is authenticated, and it
        is has the 'subscriber' role. Also, we check if the node has world GET
        permissions, which means it's free.
        """

        # Check if node permissions for the world exist (if node is free)
        if node.permissions and node.permissions.world:
            return 'GET' in node.permissions.world

        if current_user.is_authenticated():
            allowed_roles = {u'subscriber', u'demo', u'admin'}
            return bool(allowed_roles.intersection(current_user.roles or ()))

        return False

    link_allowed = allow_link()

    node_type_handlers = {
        'asset': _view_handler_asset,
        'storage': _view_handler_storage,
        'texture': _view_handler_texture,
    }
    if node_type_name in node_type_handlers:
        handler = node_type_handlers[node_type_name]
        template_path, template_action = handler(node, template_path, template_action, link_allowed)

    # Fetch linked resources.
    node.picture = get_file(node.picture, api=api)
    node.user = node.user and pillarsdk.User.find(node.user, api=api)
    node.parent = node.parent and pillarsdk.Node.find(node.parent, api=api)

    # Get children
    children_projection = {'project': 1, 'name': 1, 'picture': 1, 'parent': 1,
                           'node_type': 1, 'properties.order': 1, 'properties.status': 1,
                           'user': 1, 'properties.content_type': 1}
    children_where = {'parent': node._id}

    if node_type_name == 'group':
        children_where['properties.status'] = 'published'
        children_projection['permissions.world'] = 1
    else:
        children_projection['properties.files'] = 1
        children_projection['properties.is_tileable'] = 1

    try:
        children = Node.all({
            'projection': children_projection,
            'where': children_where,
            'sort': [('properties.order', 1), ('name', 1)]}, api=api)
    except ForbiddenAccess:
        return render_template('errors/403_embed.html')
    children = children._items

    for child in children:
        child.picture = get_file(child.picture, api=api)

    if request.args.get('format') == 'json':
        node = node.to_dict()
        node['url_edit'] = url_for('nodes.edit', node_id=node['_id']),
        return jsonify({
            'node': node,
            'children': children.to_dict(),
            'parent': node.parent.to_dict() if node.parent else {}
        })

    # Check if template exists on the filesystem
    template_path = '{0}/{1}_embed.html'.format(template_path, template_action)
    template_path_full = os.path.join(app.config['TEMPLATES_PATH'], template_path)

    if not os.path.exists(template_path_full):
        raise NotFound("Missing template '{0}'".format(template_path))

    return render_template(template_path,
                           node_id=node._id,
                           node=node,
                           parent=node.parent,
                           children=children,
                           config=app.config,
                           api=api)
Exemple #14
0
def view(project_url):
    """Entry point to view a project"""
    api = system_util.pillar_api()
    # Fetch the Node or 404
    try:
        project = Project.find_one({'where': {"url": project_url}}, api=api)
    except ResourceNotFound:
        abort(404)
    # Set up variables for processing
    user_id = 'ANONYMOUS' if current_user.is_anonymous() else str(
        current_user.objectid)
    rewrite_url = None
    embedded_node_id = None

    if request.args.get('redir') and request.args.get('redir') == '1':
        # Handle special cases (will be mainly used for items that are part
        # of the blog, or attract)
        if g.get('embedded_node')['node_type'] == 'post':
            # Very special case of the post belonging to the main project,
            # which is read from the configuration.
            if project._id == app.config['MAIN_PROJECT_ID']:
                return redirect(
                    url_for('main_blog',
                            url=g.get('embedded_node')['properties']['url']))
            else:
                return redirect(
                    url_for('project_blog',
                            project_url=project.url,
                            url=g.get('embedded_node')['properties']['url']))
        rewrite_url = "/p/{0}/#{1}".format(project.url,
                                           g.get('embedded_node')['_id'])
        embedded_node_id = g.get('embedded_node')['_id']

    if request.args.get('format') == 'jstree':
        return jsonify(items=jstree_get_children(None, project._id))

    project.picture_square = project.picture_square and get_file(
        project.picture_square, api=api)
    project.picture_header = project.picture_header and get_file(
        project.picture_header, api=api)
    embed_string = ''

    if request.args.get('embed'):
        embed_string = '_embed'
        list_latest = []
        if project.nodes_latest:
            for node_id in project.nodes_latest:
                try:
                    node_item = Node.find(node_id, {
                        'projection': '{"name":1, "user":1, "node_type":1, \
                            "project": 1}',
                        'embedded': '{"user":1}',
                    },
                                          api=api)
                    list_latest.append(node_item)
                except ForbiddenAccess:
                    pass
        project.nodes_latest = list(reversed(list_latest))

        list_featured = []
        if project.nodes_featured:
            for node_id in project.nodes_featured:
                try:
                    node_item = Node.find(node_id, {
                        'projection': '{"name":1, "user":1, "picture":1, \
                            "node_type":1, "project": 1}',
                        'embedded': '{"user":1}',
                    },
                                          api=api)
                    if node_item.picture:
                        picture = get_file(node_item.picture, api=api)
                        # picture = File.find(node_item.picture, api=api)
                        node_item.picture = picture
                    list_featured.append(node_item)
                except ForbiddenAccess:
                    pass
        project.nodes_featured = list(reversed(list_featured))

        list_blog = []
        if project.nodes_blog:
            for node_id in project.nodes_blog:
                try:
                    node_item = Node.find(
                        node_id,
                        {
                            # 'projection': '{"name":1, "user":1, "node_type":1}',
                            'embedded': '{"user":1}',
                        },
                        api=api)
                    list_blog.append(node_item)
                except ForbiddenAccess:
                    pass
        project.nodes_blog = list(reversed(list_blog))

    return render_template("projects/view{0}.html".format(embed_string),
                           embedded_node_id=embedded_node_id,
                           rewrite_url=rewrite_url,
                           user_string_id=user_id,
                           project=project,
                           api=api)