|
|
@@ -1,32 +1,21 @@
|
|
1
|
|
-from oscar.apps.image.dynamic.cache import NullCache, DiskCache
|
|
|
1
|
+from oscar.apps.image.dynamic.cache import DiskCache
|
|
|
2
|
+from oscar.apps.image.dynamic.exceptions import ResizerConfigurationException, \
|
|
|
3
|
+ ResizerSyntaxException, ResizerFormatException
|
|
2
|
4
|
from oscar.apps.image.dynamic.mods import AutotrimMod, CropMod, ResizeMod
|
|
|
5
|
+from oscar.apps.image.dynamic.response_backends import DirectResponse
|
|
3
|
6
|
from wsgiref.util import request_uri, application_uri
|
|
4
|
7
|
import Image
|
|
5
|
8
|
import cStringIO
|
|
6
|
|
-import sys
|
|
7
|
|
-import os
|
|
8
|
|
-import math
|
|
9
|
9
|
import datetime
|
|
10
|
|
-
|
|
|
10
|
+import math
|
|
|
11
|
+import os
|
|
|
12
|
+import sys
|
|
11
|
13
|
|
|
12
|
14
|
try:
|
|
13
|
15
|
import cStringIO as StringIO
|
|
14
|
16
|
except:
|
|
15
|
17
|
import StringIO
|
|
16
|
18
|
|
|
17
|
|
-
|
|
18
|
|
-class ResizerConfigurationException(Exception):
|
|
19
|
|
- pass
|
|
20
|
|
-
|
|
21
|
|
-
|
|
22
|
|
-class ResizerSyntaxException(Exception):
|
|
23
|
|
- pass
|
|
24
|
|
-
|
|
25
|
|
-
|
|
26
|
|
-class ResizerFormatException(Exception):
|
|
27
|
|
- pass
|
|
28
|
|
-
|
|
29
|
|
-
|
|
30
|
19
|
def get_class(kls):
|
|
31
|
20
|
try:
|
|
32
|
21
|
parts = kls.split('.')
|
|
|
@@ -90,7 +79,6 @@ class ImageModifier(object):
|
|
90
|
79
|
quality = 80
|
|
91
|
80
|
|
|
92
|
81
|
def __init__(self, url, config):
|
|
93
|
|
-
|
|
94
|
82
|
if config.get('installed_mods'):
|
|
95
|
83
|
mod_overrides = []
|
|
96
|
84
|
for v in config['installed_mods']:
|
|
|
@@ -133,8 +121,7 @@ class ImageModifier(object):
|
|
133
|
121
|
self._params = dict(
|
|
134
|
122
|
[(x.split("-")[0], x.split("-")[1]) for x in param_parts])
|
|
135
|
123
|
self._params['type'] = parts[3]
|
|
136
|
|
-
|
|
137
|
|
- except IndexError, e:
|
|
|
124
|
+ except IndexError:
|
|
138
|
125
|
raise ResizerSyntaxException("Invalid filename syntax")
|
|
139
|
126
|
else:
|
|
140
|
127
|
raise ResizerSyntaxException("Invalid filename syntax")
|
|
|
@@ -168,6 +155,9 @@ class ImageModifier(object):
|
|
168
|
155
|
|
|
169
|
156
|
def get_type(self):
|
|
170
|
157
|
return self.output_formats[self._params['type']]
|
|
|
158
|
+
|
|
|
159
|
+ def get_mime_type(self):
|
|
|
160
|
+ return self.get_type()[1]
|
|
171
|
161
|
|
|
172
|
162
|
|
|
173
|
163
|
class BaseImageHandler(object):
|
|
|
@@ -178,20 +168,10 @@ class BaseImageHandler(object):
|
|
178
|
168
|
"""
|
|
179
|
169
|
modifier = ImageModifier
|
|
180
|
170
|
cache = DiskCache
|
|
181
|
|
-
|
|
182
|
|
- def build_response(self, data, modifier, start_response):
|
|
183
|
|
- """
|
|
184
|
|
- Serves the (now) cached image off the disc. It is assumed that the file
|
|
185
|
|
- actually exists as it's non-existence should have been picked up while
|
|
186
|
|
- checking to see if the cached version is valid.
|
|
187
|
|
- """
|
|
188
|
|
- status = '200 OK'
|
|
189
|
|
-
|
|
190
|
|
- response_headers = [('Content-type', modifier.get_type()[1]),
|
|
191
|
|
- ('Content-Length', str(len(data)))]
|
|
192
|
|
- start_response(status, response_headers)
|
|
193
|
|
-
|
|
194
|
|
- return [data]
|
|
|
171
|
+ response_backend = DirectResponse
|
|
|
172
|
+
|
|
|
173
|
+ def build_sendfile_response(self, metadata, modifier, start_response):
|
|
|
174
|
+ pass
|
|
195
|
175
|
|
|
196
|
176
|
def __call__(self, environ, start_response):
|
|
197
|
177
|
path = environ.get('PATH_INFO')
|
|
|
@@ -204,6 +184,9 @@ class BaseImageHandler(object):
|
|
204
|
184
|
|
|
205
|
185
|
if config.get('cache_backend'):
|
|
206
|
186
|
self.cache = get_class(config['cache_backend'])
|
|
|
187
|
+ if config.get('response_backend'):
|
|
|
188
|
+ self.response_backend = get_class(config['response_backend'])
|
|
|
189
|
+
|
|
207
|
190
|
try:
|
|
208
|
191
|
c = self.cache(path, config)
|
|
209
|
192
|
m = self.modifier(path, config)
|
|
|
@@ -213,7 +196,7 @@ class BaseImageHandler(object):
|
|
213
|
196
|
if not c.check(m.source_path()):
|
|
214
|
197
|
data = m.generate_image()
|
|
215
|
198
|
c.write(data)
|
|
216
|
|
- return self.build_response(c.read(), m, start_response)
|
|
|
199
|
+ return self.response_backend(m.get_mime_type(),c,start_response).build_response()
|
|
217
|
200
|
except Exception, e:
|
|
218
|
201
|
return error404(path, start_response)
|
|
219
|
202
|
|
|
|
@@ -235,7 +218,7 @@ class DjangoImageHandler(BaseImageHandler):
|
|
235
|
218
|
django_response = HttpResponse()
|
|
236
|
219
|
|
|
237
|
220
|
def start_response(status, headers):
|
|
238
|
|
- status, reason = status.split(' ', 1)
|
|
|
221
|
+ status = status.split(' ', 1)[0]
|
|
239
|
222
|
django_response.status_code = int(status)
|
|
240
|
223
|
for header, value in headers:
|
|
241
|
224
|
django_response[header] = value
|