Image Widgets
=============
This is an infrastructure to create an image file widget that behaves
as much as possible like a normal text widget in formlib. Normally a
file widget loses its file data when a form is re-presented for
reasons of failing form validation. A ``hurry.file`` widget retains
the file, for example by storing it in a session.
In order to do this, we have a special way to store file data along with
its filename::
>>> import os
>>> from hurry.file import HurryFile
>>> testimage = os.path.join(os.path.dirname(__file__), 'sample.jpg')
>>> some_file = HurryFile('foo.jpg', open(testimage, 'rb').read())
>>> some_file.filename
'foo.jpg'
>>> 'Created with GIMP' in some_file.data
True
We can provide a download widget. In this case, there's nothing
to download::
>>> from hurry.file.browser import DownloadWidget
>>> from hurry.file.schema import File
>>> from waeup.sirp.image.schema import ImageFile
>>> from zope.publisher.browser import TestRequest
>>> field = ImageFile(__name__='foo', title=u'Foo')
>>> field = field.bind(None)
>>> request = TestRequest()
>>> widget = DownloadWidget(field, request)
>>> widget()
u'
Download not available
'
Even if there were data in the request, there'd be nothing to download::
>>> from zope.publisher.browser import FileUpload
>>> request = TestRequest(form={'field.foo': FileUpload(some_file)})
>>> widget = DownloadWidget(field, request)
>>> widget()
u'
Download not available
'
Now set a value::
>>> widget.setRenderedValue(some_file)
>>> widget()
u'foo.jpg'
Instead of downloading, we can also use a thumbnail widget:
>>> from waeup.sirp.image.browser import ThumbnailWidget
>>> request = TestRequest(form={'field.foo': FileUpload(some_file)})
>>> widget = ThumbnailWidget(field, request)
>>> widget.setRenderedValue(some_file)
>>> widget()
u''
Now on to an edit widget. First the case in an add form with no
data already available, and no data in request::
>>> #from hurry.file.browser import EncodingFileWidget
>>> from waeup.sirp.image.browser import EncodingImageFileWidget
>>> field = File(__name__='foo', title=u'Foo', required=False)
>>> field = field.bind(None)
>>> request = TestRequest()
>>> widget = EncodingImageFileWidget(field, request)
>>> def normalize(s):
... return u'\n '.join(filter(None, s.split(' ')))
>>> print normalize(widget())
Now let's try a situation where data is available in the request, but
it's an empty string for the file::
>>> request = TestRequest(form={'field.foo': u''})
>>> widget = EncodingImageFileWidget(field, request)
>>> def normalize(s):
... return '\n '.join(filter(None, s.split(' ')))
>>> print normalize(widget())
Now let's render again when there's already available data. What should show
up is an extra, hidden field which contains the file_id::
>>> widget.setRenderedValue(some_file)
>>> print normalize(widget())
(foo.jpg)
Now let's render again, this time with file data available in the request
instead. The same should happen::
>>> request = TestRequest(form={'field.foo': FileUpload(some_file)})
>>> widget = EncodingImageFileWidget(field, request)
>>> print normalize(widget())
(foo.jpg)
Now let's render again, this time not with file data available in the
request, but an id. Again, we should see the same::
>>> request = TestRequest(form={'field.foo.file_id':
... 'Zm9vLnR4dAp0aGUgY29udGVudHM='})
>>> widget = EncodingImageFileWidget(field, request)
>>> print normalize(widget())
(foo.txt)
If there is both file data and an id, something else happens. First, let's
prepare some new file::
>>> another_file = HurryFile('bar.txt', 'bar contents')
We happen to know, due to the implementation of
EncodingImageFileWidget, that the file_id is going to be
"Zm9vLnR4dAp0aGUgY29udGVudHM=". Let's make a request with the original
id, but a new file upload::
>>> request = TestRequest(form={'field.foo': FileUpload(another_file),
... 'field.foo.file_id':
... 'Zm9vLnR4dAp0aGUgY29udGVudHM='})
We expect the new file to be the one that's uploaded::
>>> widget = EncodingImageFileWidget(field, request)
>>> print normalize(widget())
(bar.txt)