comparison piecrust/rendering.py @ 911:f2b75e4be981

internal: Use pickle for caching things on disk. This is just easier and lets us use proper classes instead of converting to/from dictionaries.
author Ludovic Chabant <ludovic@chabant.com>
date Sun, 23 Jul 2017 18:03:21 -0700
parents cc2647360036
children 1bb704434ee2
comparison
equal deleted inserted replaced
910:371731b555ec 911:f2b75e4be981
2 import os.path 2 import os.path
3 import copy 3 import copy
4 import logging 4 import logging
5 from piecrust.data.builder import ( 5 from piecrust.data.builder import (
6 DataBuildingContext, build_page_data, add_layout_data) 6 DataBuildingContext, build_page_data, add_layout_data)
7 from piecrust.fastpickle import _pickle_object, _unpickle_object
8 from piecrust.templating.base import TemplateNotFoundError, TemplatingError 7 from piecrust.templating.base import TemplateNotFoundError, TemplatingError
9 from piecrust.sources.base import AbortedSourceUseError 8 from piecrust.sources.base import AbortedSourceUseError
10 9
11 10
12 logger = logging.getLogger(__name__) 11 logger = logging.getLogger(__name__)
200 layout_name = page.source.config.get( 199 layout_name = page.source.config.get(
201 'default_layout', 'default') 200 'default_layout', 'default')
202 null_names = ['', 'none', 'nil'] 201 null_names = ['', 'none', 'nil']
203 if layout_name not in null_names: 202 if layout_name not in null_names:
204 with stats.timerScope("BuildRenderData"): 203 with stats.timerScope("BuildRenderData"):
205 add_layout_data(page_data, render_result['segments']) 204 add_layout_data(page_data, render_result.segments)
206 205
207 with stats.timerScope("PageRenderLayout"): 206 with stats.timerScope("PageRenderLayout"):
208 layout_result = _do_render_layout( 207 layout_result = _do_render_layout(
209 layout_name, page, page_data) 208 layout_name, page, page_data)
210 else: 209 else:
211 layout_result = { 210 layout_result = RenderedLayout(
212 'content': render_result['segments']['content'], 211 render_result.segments['content'], None)
213 'pass_info': None}
214 212
215 rp = RenderedPage(page, ctx.sub_num) 213 rp = RenderedPage(page, ctx.sub_num)
216 rp.data = page_data 214 rp.data = page_data
217 rp.content = layout_result['content'] 215 rp.content = layout_result.content
218 rp.render_info[PASS_FORMATTING] = _unpickle_object( 216 rp.render_info[PASS_FORMATTING] = render_result.render_pass_info
219 render_result['pass_info']) 217 rp.render_info[PASS_RENDERING] = layout_result.render_pass_info
220 if layout_result['pass_info'] is not None:
221 rp.render_info[PASS_RENDERING] = _unpickle_object(
222 layout_result['pass_info'])
223 return rp 218 return rp
224 219
225 except AbortedSourceUseError: 220 except AbortedSourceUseError:
226 raise 221 raise
227 except Exception as ex: 222 except Exception as ex:
275 repo.put(page_uri, render_result, save_to_fs) 270 repo.put(page_uri, render_result, save_to_fs)
276 finally: 271 finally:
277 ctx.setCurrentPass(PASS_NONE) 272 ctx.setCurrentPass(PASS_NONE)
278 stack.popCtx() 273 stack.popCtx()
279 274
280 rs = RenderedSegments( 275 return render_result
281 render_result['segments'],
282 _unpickle_object(render_result['pass_info']))
283 return rs
284 276
285 277
286 def _build_render_data(ctx): 278 def _build_render_data(ctx):
287 data_ctx = DataBuildingContext(ctx.page, ctx.sub_num) 279 data_ctx = DataBuildingContext(ctx.page, ctx.sub_num)
288 data_ctx.pagination_source = ctx.pagination_source 280 data_ctx.pagination_source = ctx.pagination_source
331 offset = m.start() 323 offset = m.start()
332 content_abstract = seg_text[:offset] 324 content_abstract = seg_text[:offset]
333 formatted_segments['content.abstract'] = content_abstract 325 formatted_segments['content.abstract'] = content_abstract
334 326
335 pass_info = ctx.render_passes[PASS_FORMATTING] 327 pass_info = ctx.render_passes[PASS_FORMATTING]
336 res = { 328 res = RenderedSegments(formatted_segments, pass_info)
337 'segments': formatted_segments,
338 'pass_info': _pickle_object(pass_info)}
339 329
340 app.env.stats.stepCounter('PageRenderSegments') 330 app.env.stats.stepCounter('PageRenderSegments')
341 331
342 return res 332 return res
343 333
369 msg = "Can't find template for page: %s\n" % page.content_item.spec 359 msg = "Can't find template for page: %s\n" % page.content_item.spec
370 msg += "Looked for: %s" % ', '.join(full_names) 360 msg += "Looked for: %s" % ', '.join(full_names)
371 raise Exception(msg) from ex 361 raise Exception(msg) from ex
372 362
373 pass_info = cur_ctx.render_passes[PASS_RENDERING] 363 pass_info = cur_ctx.render_passes[PASS_RENDERING]
374 res = {'content': output, 'pass_info': _pickle_object(pass_info)} 364 res = RenderedLayout(output, pass_info)
375 365
376 app.env.stats.stepCounter('PageRenderLayout') 366 app.env.stats.stepCounter('PageRenderLayout')
377 367
378 return res 368 return res
379 369
392 if exact_format and not format_name: 382 if exact_format and not format_name:
393 raise Exception("You need to specify a format name.") 383 raise Exception("You need to specify a format name.")
394 384
395 format_count = 0 385 format_count = 0
396 format_name = format_name or app.config.get('site/default_format') 386 format_name = format_name or app.config.get('site/default_format')
387
388 auto_fmts = app.config.get('site/auto_formats')
389 redirect = auto_fmts.get(format_name)
390 if redirect is not None:
391 format_name = redirect
392
397 for fmt in app.plugin_loader.getFormatters(): 393 for fmt in app.plugin_loader.getFormatters():
398 if not fmt.enabled: 394 if not fmt.enabled:
399 continue 395 continue
400 if fmt.FORMAT_NAMES is None or format_name in fmt.FORMAT_NAMES: 396 if fmt.FORMAT_NAMES is None or format_name in fmt.FORMAT_NAMES:
401 with app.env.stats.timerScope(fmt.__class__.__name__): 397 with app.env.stats.timerScope(fmt.__class__.__name__):