Merge remote-tracking branch 'torchbox/stable/0.8.x'

Pulling #811 into master
pull/822/head
Karl Hobley 2014-11-18 14:35:46 +00:00
commit dc497abe87
6 zmienionych plików z 68 dodań i 9 usunięć

Wyświetl plik

@ -81,7 +81,8 @@
"audience": "public",
"location": "The North Pole",
"body": "<p>Chestnuts roasting on an open fire</p>",
"cost": "Free"
"cost": "Free",
"feed_image": 1
}
},
@ -223,7 +224,7 @@
"date_from": "2015-04-22",
"audience": "public",
"location": "Ameristralia",
"body": "<p>come celebrate the independence of Ameristralia</p>",
"body": "<p>come celebrate the independence of Ameristralia <embed embedtype=\"image\" format=\"fullwidth\" id=\"1\" alt=\"where did my image go?\" /></p>",
"cost": "Free"
}
},
@ -625,5 +626,16 @@
"page": 11,
"password": "swordfish"
}
},
{
"pk": 1,
"model": "wagtailimages.image",
"fields": {
"title": "A missing image",
"file": "original_images/missing.jpg",
"width": 1000,
"height": 1000,
"created_at": "2014-01-01T12:00:00.000Z"
}
}
]

Wyświetl plik

@ -1,4 +1,4 @@
{% load wagtailcore_tags %}
{% load wagtailcore_tags wagtailimages_tags %}
<!DOCTYPE HTML>
<html>
@ -8,6 +8,10 @@
<body>
<h1>{{ self.title }}</h1>
<h2>Event</h2>
{% if self.feed_image %}
{% image self.feed_image width-200 class="feed-image" %}
{% endif %}
{{ self.body|richtext }}
<p><a href="{% slugurl 'events' %}">Back to events index</a></p>
</body>
</html>

Wyświetl plik

@ -1,6 +1,7 @@
from django.utils.html import escape
from wagtail.utils.apps import get_app_submodules
from wagtail.wagtailimages.models import SourceImageIOError
class Format(object):
@ -25,7 +26,15 @@ class Format(object):
)
def image_to_html(self, image, alt_text, extra_attributes=''):
rendition = image.get_rendition(self.filter_spec)
try:
rendition = image.get_rendition(self.filter_spec)
except SourceImageIOError:
# Image file is (probably) missing from /media/original_images - generate a dummy
# rendition so that we just output a broken image, rather than crashing out completely
# during rendering
Rendition = image.renditions.model # pick up any custom Image / Rendition classes that may be in use
rendition = Rendition(image=image, width=0, height=0)
rendition.file.name = 'not-found'
if self.classnames:
class_attr = 'class="%s" ' % escape(self.classnames)

Wyświetl plik

@ -1,7 +1,7 @@
import os.path
import re
from six import BytesIO
from six import BytesIO, text_type
from taggit.managers import TaggableManager
@ -28,6 +28,13 @@ from wagtail.wagtailimages.rect import Rect
from wagtail.wagtailadmin.utils import get_object_usage
class SourceImageIOError(IOError):
"""
Custom exception to distinguish IOErrors that were thrown while opening the source image
"""
pass
def get_upload_to(instance, filename):
folder_name = 'original_images'
filename = instance.file.field.storage.get_valid_name(filename)
@ -178,7 +185,15 @@ class AbstractImage(models.Model, TagSearchable):
# If we have a backend attribute then pass it to process
# image - else pass 'default'
backend_name = getattr(self, 'backend', 'default')
generated_image = filter.process_image(file_field.file, backend_name=backend_name, focal_point=self.get_focal_point())
try:
image_file = file_field.file # triggers a call to self.storage.open, so IOErrors from missing files will be raised at this point
except IOError as e:
# re-throw this as a SourceImageIOError so that calling code can distinguish
# these from IOErrors elsewhere in the process
raise SourceImageIOError(text_type(e))
generated_image = filter.process_image(image_file, backend_name=backend_name, focal_point=self.get_focal_point())
# generate new filename derived from old one, inserting the filter spec and focal point key before the extension
if self.has_focal_point():

Wyświetl plik

@ -1,6 +1,6 @@
from django import template
from wagtail.wagtailimages.models import Filter
from wagtail.wagtailimages.models import Filter, SourceImageIOError
register = template.Library()
@ -53,10 +53,10 @@ class ImageNode(template.Node):
try:
rendition = image.get_rendition(self.filter)
except IOError:
except SourceImageIOError:
# It's fairly routine for people to pull down remote databases to their
# local dev versions without retrieving the corresponding image files.
# In such a case, we would get an IOError at the point where we try to
# In such a case, we would get a SourceImageIOError at the point where we try to
# create the resized version of a non-existent image. Since this is a
# bit catastrophic for a missing image, we'll substitute a dummy
# Rendition object so that we just output a broken link instead.

Wyświetl plik

@ -63,6 +63,25 @@ class TestImageTag(TestCase):
self.assertTrue('title="my wonderful title"' in result)
class TestMissingImage(TestCase):
"""
Missing image files in media/original_images should be handled gracefully, to cope with
pulling live databases to a development instance without copying the corresponding image files.
In this case, it's acceptable to render broken images, but not to fail rendering the page outright.
"""
fixtures = ['test.json']
def test_image_tag_with_missing_image(self):
# the page /events/christmas/ has a missing image as the feed image
response = self.client.get('/events/christmas/')
self.assertContains(response, '<img src="/media/not-found" width="0" height="0" alt="A missing image" class="feed-image">', html=True)
def test_rich_text_with_missing_image(self):
# the page /events/final-event/ has a missing image in the rich text body
response = self.client.get('/events/final-event/')
self.assertContains(response, '<img class="richtext-image full-width" src="/media/not-found" width="0" height="0" alt="where did my image go?">', html=True)
class TestFormat(TestCase):
def setUp(self):
# test format