summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrédéric Péters <fpeters@entrouvert.com>2019-06-25 15:41:10 (GMT)
committerFrédéric Péters <fpeters@entrouvert.com>2019-06-25 16:08:43 (GMT)
commit5b4598c901f361fc9d5b01920112b99a669ac9cd (patch)
treec11198390fea9de5adfbe0fa325feee5defc3074
parent41d884e88fc0cb679dce117ad2ad8fd7f9bdb6d8 (diff)
downloadcombo-5b4598c901f361fc9d5b01920112b99a669ac9cd.zip
combo-5b4598c901f361fc9d5b01920112b99a669ac9cd.tar.gz
combo-5b4598c901f361fc9d5b01920112b99a669ac9cd.tar.bz2
misc: allow page picture to be svg (#34334)v2.21
-rw-r--r--combo/data/models.py5
-rw-r--r--combo/manager/fields.py38
-rw-r--r--combo/manager/forms.py5
-rw-r--r--combo/manager/static/css/combo.manager.css1
-rw-r--r--combo/manager/templates/combo/page_view.html10
-rw-r--r--tests/test_manager.py11
6 files changed, 67 insertions, 3 deletions
diff --git a/combo/data/models.py b/combo/data/models.py
index 298dca4..968cd56 100644
--- a/combo/data/models.py
+++ b/combo/data/models.py
@@ -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': []}
diff --git a/combo/manager/fields.py b/combo/manager/fields.py
new file mode 100644
index 0000000..384bd72
--- /dev/null
+++ b/combo/manager/fields.py
@@ -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)
diff --git a/combo/manager/forms.py b/combo/manager/forms.py
index bbfd482..1767e65 100644
--- a/combo/manager/forms.py
+++ b/combo/manager/forms.py
@@ -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):
diff --git a/combo/manager/static/css/combo.manager.css b/combo/manager/static/css/combo.manager.css
index e54884a..99d49e7 100644
--- a/combo/manager/static/css/combo.manager.css
+++ b/combo/manager/static/css/combo.manager.css
@@ -374,6 +374,7 @@ span.extra-info {
img.page-picture {
max-width: 100%;
+ max-height: 250px;
}
span.error {
diff --git a/combo/manager/templates/combo/page_view.html b/combo/manager/templates/combo/page_view.html
index ec3585f..83646bc 100644
--- a/combo/manager/templates/combo/page_view.html
+++ b/combo/manager/templates/combo/page_view.html
@@ -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>
diff --git a/tests/test_manager.py b/tests/test_manager.py
index 8aafd61..e9748e6 100644
--- a/tests/test_manager.py
+++ b/tests/test_manager.py
@@ -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')