changeset 698:33ab9badfd7a

render: Change how we store render passes info. Previously we used a dictionary with integers as keys, which doesn't go well with JSON serialization. Now replace with an array of fixed length with items that are `None` by default.
author Ludovic Chabant <ludovic@chabant.com>
date Wed, 23 Mar 2016 16:39:22 -0700
parents 9e5393fcfab2
children 3e4049022869
files piecrust/baking/records.py piecrust/baking/single.py piecrust/commands/builtin/baking.py piecrust/rendering.py piecrust/serving/server.py
diffstat 5 files changed, 62 insertions(+), 58 deletions(-) [+]
line wrap: on
line diff
--- a/piecrust/baking/records.py	Wed Mar 23 12:19:35 2016 -0700
+++ b/piecrust/baking/records.py	Wed Mar 23 16:39:22 2016 -0700
@@ -21,7 +21,7 @@
 
 
 class BakeRecord(Record):
-    RECORD_VERSION = 17
+    RECORD_VERSION = 18
 
     def __init__(self):
         super(BakeRecord, self).__init__()
@@ -45,7 +45,7 @@
         self.out_path = out_path
         self.flags = self.FLAG_NONE
         self.errors = []
-        self.render_info = None
+        self.render_info = [None, None]  # Same length as RENDER_PASSES
 
     @property
     def was_clean(self):
@@ -60,14 +60,12 @@
         return self.was_baked and len(self.errors) == 0
 
     def anyPass(self, func):
-        assert self.render_info is not None
-        for p, pinfo in self.render_info.items():
-            if func(pinfo):
+        for pinfo in self.render_info:
+            if pinfo and func(pinfo):
                 return True
         return False
 
     def copyRenderInfo(self):
-        assert self.render_info
         return copy.deepcopy(self.render_info)
 
 
@@ -142,16 +140,16 @@
     def getAllUsedSourceNames(self):
         res = set()
         for o in self.subs:
-            if o.render_info is not None:
-                for p, pinfo in o.render_info.items():
+            for pinfo in o.render_info:
+                if pinfo:
                     res |= pinfo.used_source_names
         return res
 
     def getAllUsedTaxonomyTerms(self):
         res = set()
         for o in self.subs:
-            if o.render_info is not None:
-                for p, pinfo in o.render_info.items():
+            for pinfo in o.render_info:
+                if pinfo:
                     res |= pinfo.used_taxonomy_terms
         return res
 
--- a/piecrust/baking/single.py	Wed Mar 23 12:19:35 2016 -0700
+++ b/piecrust/baking/single.py	Wed Mar 23 16:39:22 2016 -0700
@@ -225,14 +225,14 @@
 def _get_dirty_source_names_and_render_passes(sub_entry, dirty_source_names):
     dirty_for_this = set()
     invalidated_render_passes = set()
-    assert sub_entry.render_info is not None
-    for p, pinfo in sub_entry.render_info.items():
-        for src_name in pinfo.used_source_names:
-            is_dirty = (src_name in dirty_source_names)
-            if is_dirty:
-                invalidated_render_passes.add(p)
-                dirty_for_this.add(src_name)
-                break
+    for p, pinfo in enumerate(sub_entry.render_info):
+        if pinfo:
+            for src_name in pinfo.used_source_names:
+                is_dirty = (src_name in dirty_source_names)
+                if is_dirty:
+                    invalidated_render_passes.add(p)
+                    dirty_for_this.add(src_name)
+                    break
     return dirty_for_this, invalidated_render_passes
 
 
--- a/piecrust/commands/builtin/baking.py	Wed Mar 23 12:19:35 2016 -0700
+++ b/piecrust/commands/builtin/baking.py	Wed Mar 23 16:39:22 2016 -0700
@@ -234,8 +234,10 @@
         # Show the bake record.
         record_cache = ctx.app.cache.getCache('baker')
         if not record_cache.has(record_name):
-            raise Exception("No record has been created for this output path. "
-                            "Did you bake there yet?")
+            logger.warning(
+                    "No page bake record has been created for this output "
+                    "path.")
+            return None
 
         record = BakeRecord.load(record_cache.getCachePath(record_name))
         logging.info("Bake record for: %s" % record.out_dir)
@@ -300,29 +302,30 @@
                         sub.out_path, record.out_dir))
                 logging.info("     flags:  %s" % _join(sub_flags))
 
-                if sub.render_info:
-                    pass_names = {
-                            PASS_FORMATTING: 'formatting pass',
-                            PASS_RENDERING: 'rendering pass'}
-                    for p, ri in sub.render_info.items():
-                        logging.info("     - %s" % pass_names[p])
-                        logging.info("       used sources:  %s" %
-                                     _join(ri.used_source_names))
-                        pgn_info = 'no'
-                        if ri.used_pagination:
-                            pgn_info = 'yes'
-                        if ri.pagination_has_more:
-                            pgn_info += ', has more'
-                        logging.info("       used pagination: %s", pgn_info)
-                        logging.info("       used assets: %s",
-                                     'yes' if ri.used_assets else 'no')
-                        logging.info("       used terms: %s" %
-                                     _join(
-                                            ['%s=%s (%s)' % (tn, t, sn)
-                                             for sn, tn, t in
-                                             ri.used_taxonomy_terms]))
-                else:
-                    logging.info("     no render info")
+                pass_names = {
+                        PASS_FORMATTING: 'formatting pass',
+                        PASS_RENDERING: 'rendering pass'}
+                for p, ri in enumerate(sub.render_info):
+                    logging.info("     - %s" % pass_names[p])
+                    if not ri:
+                        logging.info("       no info")
+                        continue
+
+                    logging.info("       used sources:  %s" %
+                                 _join(ri.used_source_names))
+                    pgn_info = 'no'
+                    if ri.used_pagination:
+                        pgn_info = 'yes'
+                    if ri.pagination_has_more:
+                        pgn_info += ', has more'
+                    logging.info("       used pagination: %s", pgn_info)
+                    logging.info("       used assets: %s",
+                                 'yes' if ri.used_assets else 'no')
+                    logging.info("       used terms: %s" %
+                                 _join(
+                                        ['%s=%s (%s)' % (tn, t, sn)
+                                         for sn, tn, t in
+                                         ri.used_taxonomy_terms]))
 
                 if sub.errors:
                     logging.error("   errors: %s" % sub.errors)
@@ -332,8 +335,10 @@
     def _showProcessingRecord(self, ctx, record_name, pattern, out_pattern):
         record_cache = ctx.app.cache.getCache('proc')
         if not record_cache.has(record_name):
-            raise Exception("No record has been created for this output path. "
-                            "Did you bake there yet?")
+            logger.warning(
+                    "No asset processing record has been created for this "
+                    "output path.")
+            return None
 
         # Show the pipeline record.
         record = ProcessorPipelineRecord.load(
--- a/piecrust/rendering.py	Wed Mar 23 12:19:35 2016 -0700
+++ b/piecrust/rendering.py	Wed Mar 23 16:39:22 2016 -0700
@@ -58,7 +58,7 @@
         self.num = num
         self.data = None
         self.content = None
-        self.render_info = None
+        self.render_info = [None, None]
 
     @property
     def app(self):
@@ -68,9 +68,9 @@
         return copy.deepcopy(self.render_info)
 
 
-PASS_NONE = 0
-PASS_FORMATTING = 1
-PASS_RENDERING = 2
+PASS_NONE = -1
+PASS_FORMATTING = 0
+PASS_RENDERING = 1
 
 
 RENDER_PASSES = [PASS_FORMATTING, PASS_RENDERING]
@@ -127,7 +127,7 @@
         self.custom_data = None
         self._current_pass = PASS_NONE
 
-        self.render_passes = {}
+        self.render_passes = [None, None]  # Same length as RENDER_PASSES
 
     @property
     def app(self):
@@ -143,11 +143,13 @@
 
     @property
     def current_pass_info(self):
-        return self.render_passes.get(self._current_pass)
+        if self._current_pass != PASS_NONE:
+            return self.render_passes[self._current_pass]
+        return None
 
     def setCurrentPass(self, rdr_pass):
         if rdr_pass != PASS_NONE:
-            self.render_passes.setdefault(rdr_pass, RenderPassInfo())
+            self.render_passes[rdr_pass] = RenderPassInfo()
         self._current_pass = rdr_pass
 
     def setPagination(self, paginator):
@@ -276,9 +278,8 @@
         rp = RenderedPage(page, ctx.uri, ctx.page_num)
         rp.data = page_data
         rp.content = layout_result['content']
-        rp.render_info = {
-                PASS_FORMATTING: RenderPassInfo._fromJson(
-                    render_result['pass_info'])}
+        rp.render_info[PASS_FORMATTING] = RenderPassInfo._fromJson(
+                    render_result['pass_info'])
         if layout_result['pass_info'] is not None:
             rp.render_info[PASS_RENDERING] = RenderPassInfo._fromJson(
                 layout_result['pass_info'])
@@ -372,7 +373,7 @@
                 content_abstract = seg_text[:offset]
                 formatted_segments['content.abstract'] = content_abstract
 
-    pass_info = cpi.render_ctx.render_passes.get(PASS_FORMATTING)
+    pass_info = cpi.render_ctx.render_passes[PASS_FORMATTING]
     res = {
             'segments': formatted_segments,
             'pass_info': pass_info._toJson()}
@@ -405,7 +406,7 @@
         msg += "Looked for: %s" % ', '.join(full_names)
         raise Exception(msg) from ex
 
-    pass_info = cpi.render_ctx.render_passes.get(PASS_RENDERING)
+    pass_info = cpi.render_ctx.render_passes[PASS_RENDERING]
     res = {'content': output, 'pass_info': pass_info._toJson()}
     return res
 
--- a/piecrust/serving/server.py	Wed Mar 23 12:19:35 2016 -0700
+++ b/piecrust/serving/server.py	Wed Mar 23 16:39:22 2016 -0700
@@ -218,7 +218,7 @@
         if entry is None:
             entry = ServeRecordPageEntry(req_page.req_path, req_page.page_num)
             self._page_record.addEntry(entry)
-        for p, pinfo in render_ctx.render_passes.items():
+        for pinfo in render_ctx.render_passes:
             entry.used_source_names |= pinfo.used_source_names
 
         # Start doing stuff.