def edit(project_url): api = system_util.pillar_api() # Fetch the Node or 404 try: project = Project.find_one({'where': {'url': project_url}}, api=api) # project = Project.find(project_url, api=api) except ResourceNotFound: abort(404) attach_project_pictures(project, api) form = ProjectForm( project_id=project._id, name=project.name, url=project.url, summary=project.summary, description=project.description, is_private=u'GET' not in project.permissions.world, category=project.category, status=project.status, ) if form.validate_on_submit(): project = Project.find(project._id, api=api) project.name = form.name.data project.url = form.url.data project.summary = form.summary.data project.description = form.description.data project.category = form.category.data project.status = form.status.data if form.picture_square.data: project.picture_square = form.picture_square.data if form.picture_header.data: project.picture_header = form.picture_header.data # Update world permissions from is_private checkbox if form.is_private.data: project.permissions.world = [] else: project.permissions.world = [u'GET'] project.update(api=api) # Reattach the pictures attach_project_pictures(project, api) else: if project.picture_square: form.picture_square.data = project.picture_square._id if project.picture_header: form.picture_header.data = project.picture_header._id # List of fields from the form that should be hidden to regular users if current_user.has_role('admin'): hidden_fields = [] else: hidden_fields = ['url', 'status', 'is_private', 'category'] return render_template('projects/edit.html', form=form, hidden_fields=hidden_fields, project=project, title="edit", api=api)
def sharing(project_url): api = system_util.pillar_api() # Fetch the project or 404 try: project = Project.find_one({'where': '{"url" : "%s"}' % (project_url)}, api=api) except ResourceNotFound: return abort(404) # Fetch users that are part of the admin group users = project.get_users(api=api) for user in users['_items']: user['avatar'] = gravatar(user['email']) if request.method == 'POST': user_id = request.form['user_id'] action = request.form['action'] if action == 'add': user = project.add_user(user_id, api=api) elif action == 'remove': user = project.remove_user(user_id, api=api) # Add gravatar to user user['avatar'] = gravatar(user['email']) return jsonify(user) attach_project_pictures(project, api) return render_template('projects/sharing.html', api=api, title="sharing", project=project, users=users['_items'])
def edit(project_url): api = system_util.pillar_api() # Fetch the Node or 404 try: project = Project.find_one({'where': {'url': project_url}}, api=api) # project = Project.find(project_url, api=api) except ResourceNotFound: abort(404) utils.attach_project_pictures(project, api) form = ProjectForm( project_id=project._id, name=project.name, url=project.url, summary=project.summary, description=project.description, is_private='GET' not in project.permissions.world, category=project.category, status=project.status, ) if form.validate_on_submit(): project = Project.find(project._id, api=api) project.name = form.name.data project.url = form.url.data project.summary = form.summary.data project.description = form.description.data project.category = form.category.data project.status = form.status.data if form.picture_square.data: project.picture_square = form.picture_square.data if form.picture_header.data: project.picture_header = form.picture_header.data # Update world permissions from is_private checkbox if form.is_private.data: project.permissions.world = [] else: project.permissions.world = ['GET'] project.update(api=api) # Reattach the pictures utils.attach_project_pictures(project, api) else: if project.picture_square: form.picture_square.data = project.picture_square._id if project.picture_header: form.picture_header.data = project.picture_header._id # List of fields from the form that should be hidden to regular users if current_user.has_role('admin'): hidden_fields = [] else: hidden_fields = ['url', 'status', 'is_private', 'category'] return render_template('projects/edit.html', form=form, hidden_fields=hidden_fields, project=project, ext_pages=find_extension_pages(), api=api)
def sharing(project_url): api = system_util.pillar_api() # Fetch the project or 404 try: project = Project.find_one({ 'where': '{"url" : "%s"}' % (project_url)}, api=api) except ResourceNotFound: return abort(404) # Fetch users that are part of the admin group users = project.get_users(api=api) for user in users['_items']: user['avatar'] = gravatar(user['email']) if request.method == 'POST': user_id = request.form['user_id'] action = request.form['action'] if action == 'add': user = project.add_user(user_id, api=api) elif action == 'remove': user = project.remove_user(user_id, api=api) # Add gravatar to user user['avatar'] = gravatar(user['email']) return jsonify(user) attach_project_pictures(project, api) return render_template('projects/sharing.html', api=api, title="sharing", project=project, users=users['_items'])
def project_blog(project_url, url=None): """View project blog""" api = system_util.pillar_api() try: project = Project.find_one({'where': '{"url" : "%s"}' % (project_url)}, api=api) return posts_view(project._id, url=url) except ResourceNotFound: return abort(404)
def project_blog(project_url, url=None): """View project blog""" api = system_util.pillar_api() try: project = Project.find_one({ 'where': '{"url" : "%s"}' % (project_url)}, api=api) return posts_view(project._id, url=url) except ResourceNotFound: return abort(404)
def edit_node_type(project_url, node_type_name): api = system_util.pillar_api() # Fetch the Node or 404 try: project = Project.find_one({'where': {'url': project_url}}, api=api) except ResourceNotFound: return abort(404) utils.attach_project_pictures(project, api) node_type = project.get_node_type(node_type_name) form = NodeTypeForm() if form.validate_on_submit(): # Update dynamic & form schemas dyn_schema = json.loads(form.dyn_schema.data) node_type.dyn_schema = dyn_schema form_schema = json.loads(form.form_schema.data) node_type.form_schema = form_schema node_type.description = form.description.data # Update permissions permissions = json.loads(form.permissions.data) node_type.permissions = permissions project.update(api=api) elif request.method == 'GET': form.project_id.data = project._id if node_type: form.name.data = node_type.name form.description.data = node_type.description form.parent.data = node_type.parent dyn_schema = node_type.dyn_schema.to_dict() form_schema = node_type.form_schema.to_dict() if 'permissions' in node_type: permissions = node_type.permissions.to_dict() else: permissions = {} form.form_schema.data = json.dumps(form_schema, indent=4) form.dyn_schema.data = json.dumps(dyn_schema, indent=4) form.permissions.data = json.dumps(permissions, indent=4) if request.method == 'POST': # Send back a JSON response, as this is actually called # from JS instead of rendered as page. if form.errors: resp = jsonify({'_message': str(form.errors)}) resp.status_code = 400 return resp return jsonify({'_message': 'ok'}) return render_template('projects/edit_node_type_embed.html', form=form, project=project, api=api, node_type=node_type)
def view_node(project_url, node_id): """Entry point to view a node in the context of a project""" # Some browsers mangle URLs and URL-encode /p/{p-url}/#node-id if node_id.startswith('#'): return redirect(url_for('projects.view_node', project_url=project_url, node_id=node_id[1:]), code=301) # permanent redirect theatre_mode = 't' in request.args api = system_util.pillar_api() # First we check if it's a simple string, in which case we are looking for # a static page. Maybe we could use bson.objectid.ObjectId.is_valid(node_id) if not utils.is_valid_id(node_id): # raise wz_exceptions.NotFound('No such node') project, node = render_node_page(project_url, node_id, api) else: # Fetch the node before the project. If this user has access to the # node, we should be able to get the project URL too. try: node = Node.find(node_id, api=api) except ForbiddenAccess: return render_template('errors/403.html'), 403 except ResourceNotFound: raise wz_exceptions.NotFound('No such node') try: project = Project.find_one({'where': {"url": project_url, '_id': node.project}}, api=api) except ResourceNotFound: # In theatre mode, we don't need access to the project at all. if theatre_mode: project = None else: raise wz_exceptions.NotFound('No such project') og_picture = node.picture = utils.get_file(node.picture, api=api) if project: if not node.picture: og_picture = utils.get_file(project.picture_header, api=api) project.picture_square = utils.get_file(project.picture_square, api=api) # Append _theatre to load the proper template theatre = '_theatre' if theatre_mode else '' extension_sidebar_links = current_app.extension_sidebar_links(project) return render_template('projects/view{}.html'.format(theatre), api=api, project=project, node=node, show_node=True, show_project=False, og_picture=og_picture, extension_sidebar_links=extension_sidebar_links)
def jstree(project_url): """Entry point to view a project as JSTree""" api = system_util.pillar_api() try: project = Project.find_one({ 'projection': {'_id': 1}, 'where': {'url': project_url} }, api=api) except ResourceNotFound: raise wz_exceptions.NotFound('No such project') return jsonify(items=jstree_get_children(None, project._id))
def find_project_or_404(project_url, embedded=None, api=None): """Aborts with a NotFound exception when the project cannot be found.""" params = {'where': {"url": project_url}} if embedded: params['embedded'] = embedded try: project = Project.find_one(params, api=api) except ResourceNotFound: raise wz_exceptions.NotFound('No such project') return project
def edit_node_types(project_url): api = system_util.pillar_api() # Fetch the project or 404 try: project = Project.find_one({ 'where': '{"url" : "%s"}' % (project_url)}, api=api) except ResourceNotFound: return abort(404) attach_project_pictures(project, api) return render_template('projects/edit_node_types.html', api=api, title="edit_node_types", project=project)
def edit_node_types(project_url): api = system_util.pillar_api() # Fetch the project or 404 try: project = Project.find_one({ 'where': '{"url" : "%s"}' % (project_url)}, api=api) except ResourceNotFound: return abort(404) utils.attach_project_pictures(project, api) return render_template('projects/edit_node_types.html', api=api, ext_pages=find_extension_pages(), project=project)
def edit_node_type(project_url, node_type_name): api = system_util.pillar_api() # Fetch the Node or 404 try: project = Project.find_one({ 'where': '{"url" : "%s"}' % (project_url)}, api=api) except ResourceNotFound: return abort(404) utils.attach_project_pictures(project, api) node_type = project.get_node_type(node_type_name) form = NodeTypeForm() if form.validate_on_submit(): # Update dynamic & form schemas dyn_schema = json.loads(form.dyn_schema.data) node_type.dyn_schema = dyn_schema form_schema = json.loads(form.form_schema.data) node_type.form_schema = form_schema node_type.description = form.description.data # Update permissions permissions = json.loads(form.permissions.data) node_type.permissions = permissions project.update(api=api) elif request.method == 'GET': form.project_id.data = project._id if node_type: form.name.data = node_type.name form.description.data = node_type.description form.parent.data = node_type.parent dyn_schema = node_type.dyn_schema.to_dict() form_schema = node_type.form_schema.to_dict() if 'permissions' in node_type: permissions = node_type.permissions.to_dict() else: permissions = {} form.form_schema.data = json.dumps(form_schema, indent=4) form.dyn_schema.data = json.dumps(dyn_schema, indent=4) form.permissions.data = json.dumps(permissions, indent=4) return render_template('projects/edit_node_type_embed.html', form=form, project=project, api=api, node_type=node_type)
def edit_node_type(project_url, node_type_name): api = system_util.pillar_api() # Fetch the Node or 404 try: project = Project.find_one({ 'where': '{"url" : "%s"}' % (project_url)}, api=api) except ResourceNotFound: return abort(404) attach_project_pictures(project, api) node_type = project.get_node_type(node_type_name) form = NodeTypeForm() if form.validate_on_submit(): # Update dynamic & form schemas dyn_schema = json.loads(form.dyn_schema.data) node_type.dyn_schema = dyn_schema form_schema = json.loads(form.form_schema.data) node_type.form_schema = form_schema # Update permissions permissions = json.loads(form.permissions.data) node_type.permissions = permissions project.update(api=api) else: form.project_id.data = project._id form.name.data = node_type.name form.description.data = node_type.description form.parent.data = node_type.parent form.dyn_schema.data = json.dumps( node_type.dyn_schema.to_dict(), indent=4) form.form_schema.data = json.dumps( node_type.form_schema.to_dict(), indent=4) if 'permissions' in node_type: permissions = node_type.permissions.to_dict() else: permissions = {} form.permissions.data = json.dumps(permissions, indent=4) return render_template('projects/edit_node_type.html', form=form, project=project, api=api, node_type=node_type)
def sharing(project_url): api = system_util.pillar_api() # Fetch the project or 404 try: project = Project.find_one({'where': {'url': project_url}}, api=api) except ResourceNotFound: return abort(404) # Fetch users that are part of the admin group users = project.get_users(api=api) if request.method == 'POST': user_id = request.form['user_id'] action = request.form['action'] try: if action == 'add': user = project.add_user(user_id, api=api) elif action == 'remove': user = project.remove_user(user_id, api=api) else: raise wz_exceptions.BadRequest(f'invalid action {action}') except ResourceNotFound: log.info('/p/%s/edit/sharing: User %s not found', project_url, user_id) return jsonify({ '_status': 'ERROR', 'message': 'User %s not found' % user_id }), 404 user['avatar'] = pillar.api.users.avatar.url(user) return jsonify(user) utils.attach_project_pictures(project, api) return render_template('projects/sharing.html', api=api, project=project, ext_pages=find_extension_pages(), users=users['_items'])
def sharing(project_url): api = system_util.pillar_api() # Fetch the project or 404 try: project = Project.find_one({ 'where': '{"url" : "%s"}' % (project_url)}, api=api) except ResourceNotFound: return abort(404) # Fetch users that are part of the admin group users = project.get_users(api=api) for user in users['_items']: user['avatar'] = utils.gravatar(user['email']) if request.method == 'POST': user_id = request.form['user_id'] action = request.form['action'] try: if action == 'add': user = project.add_user(user_id, api=api) elif action == 'remove': user = project.remove_user(user_id, api=api) except ResourceNotFound: log.info('/p/%s/edit/sharing: User %s not found', project_url, user_id) return jsonify({'_status': 'ERROR', 'message': 'User %s not found' % user_id}), 404 # Add gravatar to user user['avatar'] = utils.gravatar(user['email']) return jsonify(user) utils.attach_project_pictures(project, api) return render_template('projects/sharing.html', api=api, project=project, ext_pages=find_extension_pages(), users=users['_items'])
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)
def posts_view(project_id=None, project_url=None, url=None): """View individual blogpost""" if bool(project_id) == bool(project_url): raise ValueError('posts_view(): pass either project_id or project_url') api = system_util.pillar_api() # Fetch project (for backgroud images and links generation) if project_id: project = Project.find(project_id, api=api) else: project = Project.find_one({'where': {'url': project_url}}, api=api) project_id = project['_id'] attach_project_pictures(project, api) blog = Node.find_one( { 'where': { 'node_type': 'blog', 'project': project_id }, }, api=api) 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) post['properties'][ 'content'] = pillar.web.nodes.attachments.render_attachments( post, post['properties']['content']) # Use the *_main_project.html template for the main blog main_project_template = '_main_project' if project_id == current_app.config[ 'MAIN_PROJECT_ID'] else '' if url: post = Node.find_one( { 'where': { 'parent': blog._id, 'properties.url': url }, 'embedded': { 'node_type': 1, 'user': 1 }, }, api=api) if post.picture: post.picture = get_file(post.picture, api=api) # 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 not (current_user.is_authenticated and post.has_method('PUT')): abort(403) post['properties'][ 'content'] = pillar.web.nodes.attachments.render_attachments( post, post['properties']['content']) return render_template( 'nodes/custom/post/view{0}.html'.format(main_project_template), blog=blog, node=post, posts=posts._items, project=project, title='blog', api=api) else: node_type_post = project.get_node_type('post') template_path = 'nodes/custom/blog/index.html' return render_template( 'nodes/custom/blog/index{0}.html'.format(main_project_template), node_type_post=node_type_post, posts=posts._items, project=project, title='blog', api=api)
def posts_view(project_id=None, project_url=None, url=None, *, archive=False, page=1): """View individual blogpost""" if bool(project_id) == bool(project_url): raise ValueError('posts_view(): pass either project_id or project_url') if url and archive: raise ValueError('posts_view(): cannot pass both url and archive') api = system_util.pillar_api() # Fetch project (for background images and links generation) if project_id: project = Project.find(project_id, api=api) else: project = Project.find_one({'where': {'url': project_url}}, api=api) project_id = project['_id'] attach_project_pictures(project, api) blog = Node.find_one( { 'where': { 'node_type': 'blog', 'project': project_id }, }, api=api) status_query = {} if blog.has_method('PUT') else { 'properties.status': 'published' } posts = Node.all( { 'where': { 'parent': blog._id, **status_query }, 'embedded': { 'user': 1 }, 'sort': '-_created', 'max_results': 20 if archive else 5, 'page': page, }, api=api) for post in posts._items: post.picture = get_file(post.picture, api=api) post.url = url_for_node(node=post) # Use the *_main_project.html template for the main blog is_main_project = project_id == current_app.config['MAIN_PROJECT_ID'] main_project_template = '_main_project' if is_main_project else '' main_project_template = '_main_project' index_arch = 'archive' if archive else 'index' template_path = f'nodes/custom/blog/{index_arch}{main_project_template}.html', if url: template_path = f'nodes/custom/post/view{main_project_template}.html', post = Node.find_one( { 'where': { 'parent': blog._id, 'properties.url': url }, 'embedded': { 'node_type': 1, 'user': 1 }, }, api=api) if post.picture: post.picture = get_file(post.picture, api=api) post.url = url_for_node(node=post) elif posts._items: post = posts._items[0] else: post = None if post is not None: # If post is not published, check that the user is also the author of # the post. If not, return an error. if post.properties.status != "published": if not (current_user.is_authenticated and post.has_method('PUT')): abort(403) can_create_blog_posts = project.node_type_has_method('post', 'POST', api=api) # Use functools.partial so we can later pass page=X. if is_main_project: url_func = functools.partial(url_for, 'main.main_blog_archive') else: url_func = functools.partial(url_for, 'main.project_blog_archive', project_url=project.url) project.blog_archive_url = url_func() pmeta = posts._meta seen_now = pmeta['max_results'] * pmeta['page'] if pmeta['total'] > seen_now: project.blog_archive_next = url_func(page=pmeta['page'] + 1) else: project.blog_archive_next = None if pmeta['page'] > 1: project.blog_archive_prev = url_func(page=pmeta['page'] - 1) else: project.blog_archive_prev = None title = 'blog_main' if is_main_project else 'blog' pages = Node.all( { 'where': { 'project': project._id, 'node_type': 'page' }, 'projection': { 'name': 1 } }, api=api) return render_template( template_path, blog=blog, node=post, posts=posts._items, posts_meta=pmeta, more_posts_available=pmeta['total'] > pmeta['max_results'], project=project, title=title, node_type_post=project.get_node_type('post'), can_create_blog_posts=can_create_blog_posts, pages=pages._items, api=api)
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)