source: main/waeup.sirp/trunk/src/waeup/sirp/image/README.txt @ 7663

Last change on this file since 7663 was 7495, checked in by uli, 13 years ago

Get rid of this annoying 9/9L error.

File size: 5.6 KB
Line 
1waeup.sirp.image -- handling image files
2========================================
3
4The image file widget is built on top of the :class:`SIRPImageFile` object::
5
6  >>> from waeup.sirp.image import SIRPImageFile
7  >>> file = SIRPImageFile('foo.jpg', 'mydata')
8  >>> file.filename
9  'foo.jpg'
10  >>> file.data
11  'mydata'
12  >>> file.size
13  6
14  >>> f = file.file
15  >>> f.read()
16  'mydata'
17
18We can also create SIRPImageFile objects from file-like objects::
19
20  >>> from StringIO import StringIO
21  >>> from zope import component
22  >>> from hurry.file.interfaces import IFileRetrieval
23  >>> fileretrieval = component.getUtility(IFileRetrieval)
24  >>> file = fileretrieval.createFile('bar.jpg', StringIO('test data'))
25  >>> file.filename
26  'bar.jpg'
27  >>> file.size
28  9
29  >>> file.data
30  'test data'
31  >>> f = file.file
32  >>> f.read()
33  'test data'
34
35Tramline Support
36----------------
37
38The SIRPImageFile object normally stores the file data using ZODB
39persistence. Files can however also be stored by tramline.  If
40tramline is installed in Apache, the Tramline takes care of generating
41ids for files and storing the file on the filesystem directly. The ids
42are then passed as file data to be stored in the ZODB.
43
44Let's first enable tramline.
45
46The tramline directory structure is a directory with two subdirectories,
47one called 'repository' and the other called 'upload'::
48
49  >>> import tempfile, os
50  >>> dirpath = tempfile.mkdtemp()
51  >>> repositorypath = os.path.join(dirpath, 'repository')
52  >>> uploadpath = os.path.join(dirpath, 'upload')
53  >>> os.mkdir(repositorypath)
54  >>> os.mkdir(uploadpath)
55
56We create a TramlineFileRetrieval object knowing about this directory,
57and register it as a utility::
58
59  >>> from hurry.file.file import TramlineFileRetrievalBase
60  >>> class TramlineFileRetrieval(TramlineFileRetrievalBase):
61  ...    def getTramlinePath(self):
62  ...        return dirpath
63  >>> retrieval = TramlineFileRetrieval()
64  >>> component.provideUtility(retrieval, IFileRetrieval)
65
66Now let's store a file the way tramline would during upload::
67
68  >>> f = open(os.path.join(repositorypath, '1'), 'wb')
69  >>> f.write('test data')
70  >>> f.close()
71
72The file with underlying name '1' (the data stored in the ZODB will be
73just '1') will now be created::
74
75  >>> file = SIRPImageFile('foo.jpg', '1')
76
77The data is now '1', referring to the real file::
78
79  >>> file.data
80  '1'
81
82Retrieving the file results in the real file::
83
84  >>> f = file.file
85  >>> f.read()
86  'test data'
87
88We can also retrieve its size::
89
90  >>> int(file.size)
91  9
92
93Now let's disable tramline in our utility::
94
95  >>> class TramlineFileRetrieval(TramlineFileRetrievalBase):
96  ...     def getTramlinePath(self):
97  ...        return dirpath
98  ...     def isTramlineEnabled(self):
99  ...        return False
100  >>> component.provideUtility(TramlineFileRetrieval(), IFileRetrieval)
101
102We expect the same behavior as when tramline is not installed::
103
104  >>> file = SIRPImageFile('foo.jpg', 'data')
105  >>> f = file.file
106  >>> f.read()
107  'data'
108  >>> file.size
109  4
110
111Clean up:
112
113  >>> import shutil
114  >>> shutil.rmtree(dirpath)
115
116Support for :mod:`waeup.sirp.imagestorage`
117------------------------------------------
118
119The behaviour shown above can be used for any Zope3 application. With
120:mod:`waeup.sirp` we use a special file retrieval utility defined in
121:mod:`waeup.sirp.imagestorage`. As this utility is based on
122:mod:`waeup.sirp` internal stuff we do not show it here but in the
123tests that come with that storage type.
124
125Put roughly, an imagestorage stores file data in containers of blobs
126belonging to a certain site. See the module itself for details.
127
128`ImageFile` Field
129-----------------
130
131As every other field (most of them are defined in :mod:`zope.schema`)
132`ImageFile` can be used in interfaces to tell, that the associated
133attribute should be -- an image file.
134
135The `ImageFile` field accepts only certain content types:
136
137  >>> from waeup.sirp.image.schema import ImageFile
138  >>> from zope.publisher.browser import TestRequest
139  >>> field = ImageFile(__name__='foo', title=u'Foo')
140  >>> field.validate('asd')
141  Traceback (most recent call last):
142  ...
143  WrongType: ('asd', <class 'waeup.sirp.image.image.SIRPImageFile'>, 'foo')
144
145which means: `ImageFile` fields should better contain
146:class:`SIRPImageFile` instances.
147
148We can store normal :class:`SIRPImageFile` instances:
149
150  >>> field.validate(SIRPImageFile('bar.jpg', 'data')) is None
151  True
152
153The `ImageFile` field supports min and max values:
154
155  >>> field = ImageFile(__name__='foo', title=u'Foo')
156  >>> hasattr(field, 'min_size')
157  True
158
159  >>> hasattr(field, 'max_size')
160  True
161
162By default both attributes are set to ``None``:
163
164  >>> field.min_size is field.max_size is None
165  True
166
167But we can set them:
168
169  >>> field = ImageFile(__name__='bar', title=u'Bar',
170  ...                   min_size=5, max_size=12)
171
172and while these values are okay then:
173
174  >>> field.validate(
175  ...     SIRPImageFile('bar.jpg', '123456789012')) is None
176  True
177
178  >>> field.validate(
179  ...     SIRPImageFile('bar.jpg', '12345')) is None
180  True
181
182the following are not:
183
184  >>> field.validate(
185  ...     SIRPImageFile('bar.jpg', '1234567890123'))
186  Traceback (most recent call last):
187  ...
188  TooBig: ('bar.jpg', '13 bytes (max: 12 bytes)')
189
190  >>> field.validate(
191  ...     SIRPImageFile('bar.jpg', '1234'))
192  Traceback (most recent call last):
193  ...
194  TooSmall: ('bar.jpg', '4 bytes (min: 5 bytes)')
195
196
197Broken Unequality Comparison
198----------------------------
199
200SIRPImageFile does not reproduce the broken unequal comparison from
201its base:
202
203  >>> f1 = SIRPImageFile('bar.jpg', '123456789')
204  >>> f2 = SIRPImageFile('bar.jpg', '123456789')
205  >>> f3 = SIRPImageFile('baz.jpg', '1234')
206  >>> f1 == f2
207  True
208
209  >>> f1 != f2
210  False
211
212  >>> f1 == f3
213  False
214
215  >>> f1 != f3
216  True
Note: See TracBrowser for help on using the repository browser.