Mercurial > piecrust2
comparison piecrust/serving.py @ 190:430ee5b80962
serve: Make the server find assets generated by external tools.
When a processor is bypassing PieCrust's pipeline, we don't know what
output files they have produced, so if we don't find an asset in the record
for a given path, we quickly check the output folder for any matching file
there. If there is, just return it.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Sun, 11 Jan 2015 22:58:38 -0800 |
parents | d47d9493bb0a |
children | 76e459d48c43 |
comparison
equal
deleted
inserted
replaced
189:a333cdadf5b0 | 190:430ee5b80962 |
---|---|
133 exc = None | 133 exc = None |
134 try: | 134 try: |
135 response = self._try_serve_page(app, environ, request) | 135 response = self._try_serve_page(app, environ, request) |
136 return response(environ, start_response) | 136 return response(environ, start_response) |
137 except (RouteNotFoundError, SourceNotFoundError) as ex: | 137 except (RouteNotFoundError, SourceNotFoundError) as ex: |
138 logger.exception(ex) | |
139 exc = NotFound(str(ex)) | 138 exc = NotFound(str(ex)) |
140 except NotFound as ex: | 139 except NotFound as ex: |
141 exc = ex | 140 exc = ex |
142 except HTTPException: | 141 except HTTPException: |
143 raise | 142 raise |
164 entry = self._asset_record.findEntry(rel_req_path) | 163 entry = self._asset_record.findEntry(rel_req_path) |
165 if entry is None: | 164 if entry is None: |
166 # We don't know any asset that could have created this path. | 165 # We don't know any asset that could have created this path. |
167 # It could be a new asset that the user just created, but we'll | 166 # It could be a new asset that the user just created, but we'll |
168 # check for that later. | 167 # check for that later. |
168 # What we can do however is see if there's anything that already | |
169 # exists there, because it could have been created by a processor | |
170 # that bypasses structured processing (like e.g. the compass | |
171 # processor). In that case, just return that file, hoping it will | |
172 # be up-to-date. | |
173 full_path = os.path.join(self._out_dir, rel_req_path) | |
174 try: | |
175 response = self._make_wrapped_file_response( | |
176 environ, full_path) | |
177 logger.debug("Didn't find record entry, but found existing " | |
178 "output file at: %s" % rel_req_path) | |
179 return response | |
180 except OSError: | |
181 pass | |
169 return None | 182 return None |
170 | 183 |
171 # Yep, we know about this URL because we processed an asset that | 184 # Yep, we know about this URL because we processed an asset that |
172 # maps to it... make sure it's up to date by re-processing it | 185 # maps to it... make sure it's up to date by re-processing it |
173 # before serving. | 186 # before serving. |
185 r = pipeline.run(asset_in_path, delete=False, save_record=False, | 198 r = pipeline.run(asset_in_path, delete=False, save_record=False, |
186 previous_record=self._asset_record) | 199 previous_record=self._asset_record) |
187 assert len(r.entries) == 1 | 200 assert len(r.entries) == 1 |
188 self._asset_record.replaceEntry(r.entries[0]) | 201 self._asset_record.replaceEntry(r.entries[0]) |
189 | 202 |
190 logger.debug("Serving %s" % asset_out_path) | 203 return self._make_wrapped_file_response(environ, asset_out_path) |
191 wrapper = wrap_file(environ, open(asset_out_path, 'rb')) | |
192 response = Response(wrapper) | |
193 _, ext = os.path.splitext(rel_req_path) | |
194 response.mimetype = self._mimetype_map.get( | |
195 ext.lstrip('.'), 'text/plain') | |
196 return response | |
197 | 204 |
198 def _try_serve_new_asset(self, app, environ, request): | 205 def _try_serve_new_asset(self, app, environ, request): |
199 logger.debug("Searching for a new asset with path: %s" % request.path) | 206 logger.debug("Searching for a new asset with path: %s" % request.path) |
200 mounts = app.assets_dirs | 207 mounts = app.assets_dirs |
201 pipeline = ProcessorPipeline( | 208 pipeline = ProcessorPipeline( |
212 if entry is None: | 219 if entry is None: |
213 return None | 220 return None |
214 | 221 |
215 asset_out_path = os.path.join(self._out_dir, rel_req_path) | 222 asset_out_path = os.path.join(self._out_dir, rel_req_path) |
216 logger.debug("Found new asset: %s" % entry.path) | 223 logger.debug("Found new asset: %s" % entry.path) |
217 logger.debug("Serving %s" % asset_out_path) | 224 return self._make_wrapped_file_response(environ, asset_out_path) |
218 wrapper = wrap_file(environ, open(asset_out_path, 'rb')) | |
219 response = Response(wrapper) | |
220 _, ext = os.path.splitext(rel_req_path) | |
221 response.mimetype = self._mimetype_map.get( | |
222 ext.lstrip('.'), 'text/plain') | |
223 return response | |
224 | 225 |
225 def _try_serve_page_asset(self, app, environ, request): | 226 def _try_serve_page_asset(self, app, environ, request): |
226 if not request.path.startswith('/_asset/'): | 227 if not request.path.startswith('/_asset/'): |
227 return None | 228 return None |
228 | 229 |
229 full_path = os.path.join(app.root_dir, request.path[len('/_asset/'):]) | 230 full_path = os.path.join(app.root_dir, request.path[len('/_asset/'):]) |
230 if not os.path.isfile(full_path): | 231 if not os.path.isfile(full_path): |
231 return None | 232 return None |
232 | 233 |
233 logger.debug("Serving %s" % full_path) | 234 return self._make_wrapped_file_response(environ, full_path) |
234 wrapper = wrap_file(environ, open(full_path, 'rb')) | |
235 response = Response(wrapper) | |
236 _, ext = os.path.splitext(full_path) | |
237 response.mimetype = self._mimetype_map.get( | |
238 ext.lstrip('.'), 'text/plain') | |
239 return response | |
240 | 235 |
241 def _try_serve_page(self, app, environ, request): | 236 def _try_serve_page(self, app, environ, request): |
242 # Try to find what matches the requested URL. | 237 # Try to find what matches the requested URL. |
243 req_path = request.path | 238 req_path = request.path |
244 page_num = 1 | 239 page_num = 1 |
370 "falling back to uncompressed.") | 365 "falling back to uncompressed.") |
371 response.set_data(rp_content) | 366 response.set_data(rp_content) |
372 | 367 |
373 return response | 368 return response |
374 | 369 |
370 def _make_wrapped_file_response(self, environ, path): | |
371 logger.debug("Serving %s" % path) | |
372 wrapper = wrap_file(environ, open(path, 'rb')) | |
373 response = Response(wrapper) | |
374 _, ext = os.path.splitext(path) | |
375 response.mimetype = self._mimetype_map.get( | |
376 ext.lstrip('.'), 'text/plain') | |
377 return response | |
378 | |
375 def _handle_error(self, exception, environ, start_response): | 379 def _handle_error(self, exception, environ, start_response): |
376 path = 'error' | 380 path = 'error' |
377 if isinstance(exception, NotFound): | 381 if isinstance(exception, NotFound): |
378 path += '404' | 382 path += '404' |
379 description = str(exception) | 383 description = str(exception) |