changeset 50:2fec3ee1298f

Properly override pages between realms.
author Ludovic Chabant <ludovic@chabant.com>
date Fri, 22 Aug 2014 23:41:17 -0700
parents fce061f8c2ed
children 5d9d44bfc54d
files piecrust/baking/baker.py piecrust/baking/records.py piecrust/environment.py piecrust/rendering.py piecrust/sources/base.py
diffstat 5 files changed, 59 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/piecrust/baking/baker.py	Fri Aug 22 20:26:05 2014 -0700
+++ b/piecrust/baking/baker.py	Fri Aug 22 23:41:17 2014 -0700
@@ -79,8 +79,6 @@
         return os.path.normpath(os.path.join(*bake_path))
 
     def bake(self, factory, route, taxonomy_name=None, taxonomy_term=None):
-        page = factory.buildPage()
-
         pagination_filter = None
         custom_data = None
         if taxonomy_name and taxonomy_term:
@@ -110,8 +108,31 @@
             # Normal page bake.
             uri = route.getUri(factory.metadata)
 
+        override = self.record.getOverrideEntry(factory, uri)
+        if override is not None:
+            override_source = self.app.getSource(override.source_name)
+            if override_source.realm == factory.source.realm:
+                raise Exception(
+                        "Page '%s' maps to URL '%s' but is overriden by page"
+                        "'%s:%s'." % (factory.ref_spec, uri,
+                            override.source_name, override.rel_path))
+            logger.debug("'%s' [%s] is overriden by '%s:%s'. Skipping" %
+                    (factory.ref_spec, uri, override.source_name,
+                        override.rel_path))
+            entry = BakeRecordPageEntry()
+            entry.path = factory.path
+            entry.rel_path = factory.rel_path
+            entry.source_name = factory.source.name
+            entry.was_overriden = True
+
+            if self.record:
+                self.record.addEntry(entry)
+
+            return entry
+
         cur_sub = 1
         has_more_subs = True
+        page = factory.buildPage()
         cur_record_entry = BakeRecordPageEntry(page)
         cur_record_entry.taxonomy_name = taxonomy_name
         cur_record_entry.taxonomy_term = taxonomy_term
@@ -540,6 +561,8 @@
                 self.ctx.abort_event.set()
                 self.abort_exception = ex
                 logger.debug("[%d] Critical error, aborting." % self.wid)
+                if self.ctx.app.debug:
+                    logger.exception(ex)
                 break
 
     def _unsafeRun(self, job):
--- a/piecrust/baking/records.py	Fri Aug 22 20:26:05 2014 -0700
+++ b/piecrust/baking/records.py	Fri Aug 22 23:41:17 2014 -0700
@@ -28,18 +28,25 @@
 
 
 class BakeRecordPageEntry(object):
-    def __init__(self, page):
-        self.path = page.path
-        self.rel_path = page.rel_path
-        self.source_name = page.source.name
-        self.config = page.config.get()
+    def __init__(self, page=None):
+        self.path = None
+        self.rel_path = None
+        self.source_name = None
+        self.config = None
         self.taxonomy_name = None
         self.taxonomy_term = None
+        self.was_overriden = False
         self.out_uris = []
         self.out_paths = []
         self.used_source_names = set()
         self.used_taxonomy_terms = set()
 
+        if page:
+            self.path = page.path
+            self.rel_path = page.rel_path
+            self.source_name = page.source.name
+            self.config = page.config.get()
+
     @property
     def was_baked(self):
         return len(self.out_paths) > 0
@@ -88,6 +95,22 @@
     def addEntry(self, entry):
         self.current.addEntry(entry)
 
+    def getOverrideEntry(self, factory, uri):
+        for pair in self.transitions.values():
+            prev = pair[0]
+            cur = pair[1]
+            if (cur and
+                    (cur.source_name != factory.source.name or
+                        cur.rel_path != factory.rel_path) and
+                    len(cur.out_uris) > 0 and cur.out_uris[0] == uri):
+                return cur
+            if (prev and
+                    (prev.source_name != factory.source.name or
+                        prev.rel_path != factory.rel_path) and
+                    len(prev.out_uris) > 0 and prev.out_uris[0] == uri):
+                return prev
+        return None
+
     def getPreviousEntry(self, page, taxonomy_name=None, taxonomy_term=None):
         key = _get_transition_key(page.source.name, page.rel_path,
                 taxonomy_name, taxonomy_term)
@@ -105,6 +128,7 @@
                 # This page wasn't baked, so the information from last
                 # time is still valid (we didn't get any information
                 # since we didn't bake).
+                cur.was_overriden = prev.was_overriden
                 cur.out_uris = list(prev.out_uris)
                 cur.out_paths = list(prev.out_paths)
                 cur.used_source_names = set(prev.used_source_names)
--- a/piecrust/environment.py	Fri Aug 22 20:26:05 2014 -0700
+++ b/piecrust/environment.py	Fri Aug 22 23:41:17 2014 -0700
@@ -50,7 +50,8 @@
                     self.cache.put(key, item)
 
                     # Save to the file-system if needed.
-                    if self.fs_cache is not None:
+                    if (self.fs_cache is not None and
+                            fs_cache_time is not None):
                         item_raw = json.dumps(item)
                         self.fs_cache.write(fs_key, item_raw)
         return item
--- a/piecrust/rendering.py	Fri Aug 22 20:26:05 2014 -0700
+++ b/piecrust/rendering.py	Fri Aug 22 23:41:17 2014 -0700
@@ -122,7 +122,8 @@
     if repo:
         cache_key = '%s:%s' % (ctx.uri, ctx.page_num)
         return repo.get(cache_key,
-            lambda: _do_render_page_segments_from_ctx(ctx))
+            lambda: _do_render_page_segments_from_ctx(ctx),
+            fs_cache_time=ctx.page.path_mtime)
 
     return _do_render_page_segments_from_ctx(ctx)
 
--- a/piecrust/sources/base.py	Fri Aug 22 20:26:05 2014 -0700
+++ b/piecrust/sources/base.py	Fri Aug 22 23:41:17 2014 -0700
@@ -45,7 +45,7 @@
         self.rel_path = rel_path
         self.metadata = metadata
 
-    @property
+    @cached_property
     def ref_spec(self):
         return '%s:%s' % (self.source.name, self.rel_path)