misc: allow page picture to be svg (#34334)

This commit is contained in:
Frédéric Péters 2019-06-25 17:41:10 +02:00
parent 41d884e88f
commit 5b4598c901
6 changed files with 67 additions and 3 deletions

View File

@ -162,6 +162,11 @@ class Page(models.Model):
def natural_key(self):
return (self.get_online_url().strip('/'), )
def picture_extension(self):
if not self.picture:
return None
return os.path.splitext(self.picture.name)[-1]
def save(self, *args, **kwargs):
if not self.id:
self.related_cells = {'cell_types': []}

38
combo/manager/fields.py Normal file
View File

@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
#
# combo - content management system
# Copyright (C) 2015-2019 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.core import validators
from django import forms
def get_available_image_extensions():
return validators.get_available_image_extensions() + ['svg']
validate_image_file_extension = validators.FileExtensionValidator(
allowed_extensions=get_available_image_extensions(),
)
class ImageIncludingSvgField(forms.ImageField):
default_validators = [validate_image_file_extension]
def to_python(self, data):
if data.name and data.name.endswith('.svg'):
# bypass image field Pillow check
return super(forms.ImageField, self).to_python(data)
return super(ImageIncludingSvgField, self).to_python(data)

View File

@ -23,6 +23,8 @@ from django.utils.translation import ugettext_lazy as _
from combo.data.models import Page
from .fields import ImageIncludingSvgField
class PageEditTitleForm(forms.ModelForm):
class Meta:
@ -53,6 +55,9 @@ class PageEditPictureForm(forms.ModelForm):
class Meta:
model = Page
fields = ('picture',)
field_classes = {
'picture': ImageIncludingSvgField
}
class PageVisibilityForm(forms.ModelForm):

View File

@ -374,6 +374,7 @@ span.extra-info {
img.page-picture {
max-width: 100%;
max-height: 250px;
}
span.error {

View File

@ -70,10 +70,14 @@
<p>
<label>{% trans 'Picture:' %}</label>
{% if object.picture %}
{% thumbnail object.picture "320x240" crop="50% 25%" as im %}
<img class="page-picture" src="{{im.url}}"/>
{% if object.picture_extension != '.svg' %}
{% thumbnail object.picture "320x240" crop="50% 25%" as im %}
<img class="page-picture" src="{{im.url}}"/>
{% endthumbnail %}
{% else %}
<img class="page-picture" src="{{page.picture.url}}"/>
{% endif %}
(<a href="{% url 'combo-manager-page-remove-picture' pk=object.id %}">{% trans 'remove' %}</a>)
{% endthumbnail %}
{% else %}<i>{% trans 'none' %}</i>{% endif %}
(<a rel="popup" href="{% url 'combo-manager-page-edit-picture' pk=object.id %}">{% trans 'change' %}</a>)
</p>

View File

@ -170,11 +170,22 @@ def test_page_edit_picture(app, admin_user):
resp = resp.follow()
assert '<h2>Page - One</h2>' in resp.text
assert '<img' in resp.text
assert 'src="/media/cache/' in resp.text
resp = resp.click(href='.*/remove-picture/')
resp = resp.follow()
assert '<h2>Page - One</h2>' in resp.text
assert not '<img' in resp.text
resp = resp.click(href='.*/picture/')
resp.form['picture'] = Upload('black.svg',
'<svg xmlns="http://www.w3.org/2000/svg"/>', 'image/svg+xml')
resp = resp.form.submit()
assert resp.location.endswith('/manage/pages/%s/' % page.id)
resp = resp.follow()
assert '<h2>Page - One</h2>' in resp.text
assert '<img' in resp.text
assert Page.objects.get(id=page.id).picture.url in resp.text
def test_delete_page(app, admin_user):
Page.objects.all().delete()
page = Page(title='One', slug='one', template_name='standard')