Introducing attachments fixes for blog posts and assets.
Requires migration of attachments schema using python manage.py maintenance upgrade_attachment_schema --all
This commit is contained in:
@@ -23,6 +23,14 @@ _attachments_embedded_schema = {
|
||||
'type': 'objectid',
|
||||
'required': True,
|
||||
},
|
||||
'link': {
|
||||
'type': 'string',
|
||||
'allowed': ['self', 'none', 'custom'],
|
||||
'default': 'self',
|
||||
},
|
||||
'link_custom': {
|
||||
'type': 'string',
|
||||
},
|
||||
'collection': {
|
||||
'type': 'string',
|
||||
'allowed': ['files'],
|
||||
|
@@ -148,7 +148,6 @@ def main_posts_create():
|
||||
@blueprint.route('/p/<project_url>/blog/<url>')
|
||||
def project_blog(project_url, url=None):
|
||||
"""View project blog"""
|
||||
|
||||
return posts_view(project_url=project_url, url=url)
|
||||
|
||||
|
||||
|
@@ -38,7 +38,6 @@ def render_attachments(node, field_value):
|
||||
att = node_attachments[slug]
|
||||
except KeyError:
|
||||
return u'[attachment "%s" not found]' % slug
|
||||
|
||||
return render_attachment(att)
|
||||
|
||||
return shortcode_re.sub(replace, field_value)
|
||||
@@ -60,14 +59,14 @@ def render_attachment(attachment):
|
||||
log.error(u'Unable to render attachment from collection %s', collection)
|
||||
return u'Unable to render attachment'
|
||||
|
||||
return renderer(oid)
|
||||
return renderer(attachment)
|
||||
|
||||
|
||||
def render_attachment_file(oid):
|
||||
def render_attachment_file(attachment):
|
||||
"""Renders a file attachment."""
|
||||
|
||||
api = system_util.pillar_api()
|
||||
sdk_file = pillarsdk.File.find(oid, api=api)
|
||||
sdk_file = pillarsdk.File.find(attachment[u'oid'], api=api)
|
||||
|
||||
file_renderers = {
|
||||
'image': render_attachment_file_image
|
||||
@@ -79,15 +78,15 @@ def render_attachment_file(oid):
|
||||
except KeyError:
|
||||
return flask.render_template('nodes/attachments/file_generic.html', file=sdk_file)
|
||||
|
||||
return renderer(sdk_file)
|
||||
return renderer(sdk_file, attachment)
|
||||
|
||||
|
||||
def render_attachment_file_image(sdk_file):
|
||||
def render_attachment_file_image(sdk_file, attachment):
|
||||
"""Renders an image file."""
|
||||
|
||||
variations = {var.size: var for var in sdk_file.variations}
|
||||
return flask.render_template('nodes/attachments/file_image.html',
|
||||
file=sdk_file, vars=variations)
|
||||
file=sdk_file, vars=variations, attachment=attachment)
|
||||
|
||||
|
||||
def attachment_form_group_create(schema_prop):
|
||||
@@ -104,6 +103,8 @@ def _attachment_build_single_field(schema_prop):
|
||||
fake_schema = {
|
||||
'slug': schema_prop['propertyschema'],
|
||||
'oid': schema_prop['valueschema']['schema']['oid'],
|
||||
'link': schema_prop['valueschema']['schema']['link'],
|
||||
'link_custom': schema_prop['valueschema']['schema']['link_custom'],
|
||||
}
|
||||
file_select_form_group = build_file_select_form(fake_schema)
|
||||
return file_select_form_group
|
||||
@@ -125,7 +126,12 @@ def attachment_form_group_set_data(db_prop_value, schema_prop, field_list):
|
||||
# Even uglier hard-coded
|
||||
subform.slug = slug
|
||||
subform.oid = att_data['oid']
|
||||
|
||||
subform.link = 'self'
|
||||
subform.link_custom = None
|
||||
if 'link' in att_data:
|
||||
subform.link = att_data['link']
|
||||
if 'link_custom' in att_data:
|
||||
subform.link_custom = att_data['link_custom']
|
||||
field_list.append_entry(subform)
|
||||
|
||||
|
||||
@@ -138,6 +144,8 @@ def attachment_form_parse_post_data(data):
|
||||
for allprops in data:
|
||||
oid = allprops['oid']
|
||||
slug = allprops['slug']
|
||||
link = allprops['link']
|
||||
link_custom = allprops['link_custom']
|
||||
|
||||
if not allprops['slug'] and not oid:
|
||||
continue
|
||||
@@ -145,5 +153,9 @@ def attachment_form_parse_post_data(data):
|
||||
if slug in attachments:
|
||||
raise ValueError('Slug "%s" is used more than once' % slug)
|
||||
attachments[slug] = {'oid': oid}
|
||||
attachments[slug]['link'] = link
|
||||
|
||||
if link == 'custom':
|
||||
attachments[slug]['link_custom'] = link_custom
|
||||
|
||||
return attachments
|
||||
|
@@ -73,7 +73,6 @@ def posts_view(project_id=None, project_url=None, url=None):
|
||||
|
||||
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,
|
||||
@@ -141,52 +140,6 @@ def posts_create(project_id):
|
||||
api=api)
|
||||
|
||||
|
||||
@blueprint.route("/posts/<post_id>/edit", methods=['GET', 'POST'])
|
||||
@login_required
|
||||
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)
|
||||
|
||||
|
||||
|
||||
def setup_app(app):
|
||||
global posts_view
|
||||
|
||||
|
@@ -28,9 +28,9 @@ from pillar.web.nodes.forms import process_node_form
|
||||
from pillar.web.nodes.custom.storage import StorageNode
|
||||
from pillar.web.projects.routes import project_update_nodes_list
|
||||
from pillar.web.utils import get_file
|
||||
from pillar.web.utils import attach_project_pictures
|
||||
from pillar.web.utils.jstree import jstree_build_children
|
||||
from pillar.web.utils.jstree import jstree_build_from_node
|
||||
from pillar.web.utils.forms import ProceduralFileSelectForm
|
||||
from pillar.web.utils.forms import build_file_select_form
|
||||
from pillar.web import system_util
|
||||
|
||||
@@ -120,8 +120,9 @@ def view(node_id):
|
||||
|
||||
node_type_name = node.node_type
|
||||
|
||||
if node_type_name == 'post':
|
||||
# Posts shouldn't be shown at this route, redirect to the correct one.
|
||||
if node_type_name == 'post' and not request.args.get('embed'):
|
||||
# Posts shouldn't be shown at this route (unless viewed embedded, tipically
|
||||
# after an edit. 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
|
||||
@@ -353,12 +354,14 @@ def edit(node_id):
|
||||
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
|
||||
|
||||
if not set_data:
|
||||
continue
|
||||
|
||||
# Assign data to the field
|
||||
if prop_name == 'attachments':
|
||||
# If attachments is an empty list, do not append data
|
||||
if not db_prop_value:
|
||||
continue
|
||||
attachments.attachment_form_group_set_data(db_prop_value, schema_prop,
|
||||
form[prop_name])
|
||||
elif prop_name == 'files':
|
||||
@@ -391,7 +394,6 @@ def edit(node_id):
|
||||
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)
|
||||
@@ -405,8 +407,6 @@ def edit(node_id):
|
||||
project_update_nodes_list(node, project_id=project._id, list_name='blog')
|
||||
else:
|
||||
project_update_nodes_list(node, project_id=project._id)
|
||||
# Emergency hardcore cache flush
|
||||
# cache.clear()
|
||||
return redirect(url_for('nodes.view', node_id=node_id, embed=1,
|
||||
_external=True,
|
||||
_scheme=current_app.config['SCHEME']))
|
||||
@@ -416,7 +416,6 @@ def edit(node_id):
|
||||
else:
|
||||
if form.errors:
|
||||
log.debug('Form errors: %s', form.errors)
|
||||
|
||||
# Populate Form
|
||||
form.name.data = node.name
|
||||
form.description.data = node.description
|
||||
@@ -424,7 +423,6 @@ def edit(node_id):
|
||||
form.picture.data = node.picture
|
||||
if node.parent:
|
||||
form.parent.data = node.parent
|
||||
|
||||
set_properties(dyn_schema, form_schema, node_properties, form, set_data=True)
|
||||
|
||||
# Get previews
|
||||
@@ -443,9 +441,10 @@ def edit(node_id):
|
||||
if request.args.get('embed') == '1':
|
||||
# Define the prefix for the embedded template
|
||||
embed_string = '_embed'
|
||||
else:
|
||||
attach_project_pictures(project, api)
|
||||
|
||||
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:
|
||||
@@ -459,6 +458,7 @@ def edit(node_id):
|
||||
api=api)
|
||||
except TemplateNotFound:
|
||||
template = 'nodes/edit{1}.html'.format(node_type['name'], embed_string)
|
||||
is_embedded_edit = True if embed_string else False
|
||||
return render_template(
|
||||
template,
|
||||
node=node,
|
||||
@@ -466,7 +466,10 @@ def edit(node_id):
|
||||
form=form,
|
||||
errors=form.errors,
|
||||
error=error,
|
||||
api=api)
|
||||
api=api,
|
||||
project=project,
|
||||
is_embedded_edit=is_embedded_edit,
|
||||
)
|
||||
|
||||
|
||||
def ensure_lists_exist_as_empty(node_doc, node_type):
|
||||
|
@@ -108,12 +108,6 @@ class FileSelectField(StringField):
|
||||
self.widget = CustomFileSelectWidget(file_format=file_format)
|
||||
|
||||
|
||||
class ProceduralFileSelectForm(Form):
|
||||
file = FileSelectField('file')
|
||||
size = StringField()
|
||||
slug = StringField()
|
||||
|
||||
|
||||
def build_file_select_form(schema):
|
||||
class FileSelectForm(Form):
|
||||
pass
|
||||
|
Reference in New Issue
Block a user