changeset 430:21e26ed867b6

internal: Create full route metadata in one place. Instead of combining things at different moments to make up route metadata, build it once and for all up-front and use that.
author Ludovic Chabant <ludovic@chabant.com>
date Sat, 27 Jun 2015 08:27:35 -0700
parents ca5a3c970263
children bdeeee777f85
files piecrust/baking/baker.py piecrust/baking/single.py piecrust/baking/worker.py piecrust/data/base.py piecrust/processing/sitemap.py piecrust/rendering.py piecrust/routing.py
diffstat 7 files changed, 44 insertions(+), 46 deletions(-) [+]
line wrap: on
line diff
--- a/piecrust/baking/baker.py	Sat Jun 27 00:03:56 2015 -0700
+++ b/piecrust/baking/baker.py	Sat Jun 27 08:27:35 2015 -0700
@@ -13,6 +13,7 @@
         JOB_LOAD, JOB_RENDER_FIRST, JOB_BAKE)
 from piecrust.chefutil import (
         format_timed_scope, format_timed)
+from piecrust.routing import create_route_metadata
 from piecrust.sources.base import (
         REALM_NAMES, REALM_USER, REALM_THEME)
 
@@ -485,7 +486,8 @@
             return False
 
         # Build the route metadata and find the appropriate route.
-        route_metadata = copy.deepcopy(fac.metadata)
+        page = fac.buildPage()
+        route_metadata = create_route_metadata(page)
         if tax_info is not None:
             tax = self.app.getTaxonomy(tax_info.taxonomy_name)
             route = self.app.getTaxonomyRoute(tax_info.taxonomy_name,
@@ -501,8 +503,7 @@
         # Figure out if this page is overriden by another previously
         # baked page. This happens for example when the user has
         # made a page that has the same page/URL as a theme page.
-        page = fac.buildPage()
-        uri = route.getUri(route_metadata, provider=page)
+        uri = route.getUri(route_metadata)
         override_entry = record.getOverrideEntry(page.path, uri)
         if override_entry is not None:
             override_source = self.app.getSource(
--- a/piecrust/baking/single.py	Sat Jun 27 00:03:56 2015 -0700
+++ b/piecrust/baking/single.py	Sat Jun 27 08:27:35 2015 -0700
@@ -14,14 +14,6 @@
 logger = logging.getLogger(__name__)
 
 
-def copy_public_page_config(config):
-    res = config.getDeepcopy()
-    for k in list(res.keys()):
-        if k.startswith('__'):
-            del res[k]
-    return res
-
-
 class BakingError(Exception):
     pass
 
@@ -50,11 +42,8 @@
 
         return os.path.normpath(os.path.join(*bake_path))
 
-    def bake(self, factory, route, route_metadata, prev_entry,
-             dirty_source_names, tax_info=None):
-        # Get the page.
-        page = factory.buildPage()
-
+    def bake(self, qualified_page, prev_entry, dirty_source_names,
+             tax_info=None):
         # Start baking the sub-pages.
         cur_sub = 1
         has_more_subs = True
@@ -62,8 +51,7 @@
 
         while has_more_subs:
             # Get the URL and path for this sub-page.
-            sub_uri = route.getUri(route_metadata, sub_num=cur_sub,
-                                   provider=page)
+            sub_uri = qualified_page.getUri(cur_sub)
             logger.debug("Baking '%s' [%d]..." % (sub_uri, cur_sub))
             out_path = self.getOutputPath(sub_uri)
 
@@ -88,7 +76,7 @@
             do_bake = True
             if not force_this_sub:
                 try:
-                    in_path_time = page.path_mtime
+                    in_path_time = qualified_page.path_mtime
                     out_path_time = os.path.getmtime(out_path)
                     if out_path_time >= in_path_time:
                         do_bake = False
@@ -122,10 +110,11 @@
                         SubPageBakeInfo.FLAG_FORMATTING_INVALIDATED
 
                 logger.debug("  p%d -> %s" % (cur_sub, out_path))
-                qp = QualifiedPage(page, route, route_metadata)
-                rp = self._bakeSingle(qp, cur_sub, out_path, tax_info)
+                rp = self._bakeSingle(qualified_page, cur_sub, out_path,
+                                      tax_info)
             except Exception as ex:
-                page_rel_path = os.path.relpath(page.path, self.app.root_dir)
+                page_rel_path = os.path.relpath(qualified_page.path,
+                                                self.app.root_dir)
                 raise BakingError("%s: error baking '%s'." %
                                   (page_rel_path, sub_uri)) from ex
 
@@ -147,8 +136,8 @@
                 logger.debug("Copying page assets to: %s" % out_assets_dir)
                 _ensure_dir_exists(out_assets_dir)
 
-                page_dirname = os.path.dirname(page.path)
-                page_pathname, _ = os.path.splitext(page.path)
+                page_dirname = os.path.dirname(qualified_page.path)
+                page_pathname, _ = os.path.splitext(qualified_page.path)
                 in_assets_dir = page_pathname + ASSET_DIR_SUFFIX
                 for fn in os.listdir(in_assets_dir):
                     full_fn = os.path.join(page_dirname, fn)
--- a/piecrust/baking/worker.py	Sat Jun 27 00:03:56 2015 -0700
+++ b/piecrust/baking/worker.py	Sat Jun 27 08:27:35 2015 -0700
@@ -6,6 +6,7 @@
 from piecrust.baking.single import PageBaker, BakingError
 from piecrust.rendering import (
         QualifiedPage, PageRenderingContext, render_page_segments)
+from piecrust.routing import create_route_metadata
 from piecrust.sources.base import PageFactory
 
 
@@ -218,7 +219,7 @@
         assert route is not None
 
         page = fac.buildPage()
-        route_metadata = copy.deepcopy(fac.metadata)
+        route_metadata = create_route_metadata(page)
         qp = QualifiedPage(page, route, route_metadata)
         ctx = PageRenderingContext(qp)
 
@@ -254,14 +255,16 @@
                                       skip_taxonomies=True)
         assert route is not None
 
+        page = fac.buildPage()
+        qp = QualifiedPage(page, route, route_metadata)
+
         result = BakeJobResult(fac.path, tax_info)
         previous_entry = job.payload.previous_entry
         dirty_source_names = job.payload.dirty_source_names
         logger.debug("Baking page: %s" % fac.ref_spec)
         try:
             sub_entries = self.page_baker.bake(
-                    fac, route, route_metadata, previous_entry,
-                    dirty_source_names, tax_info)
+                    qp, previous_entry, dirty_source_names, tax_info)
             result.sub_entries = sub_entries
 
         except BakingError as ex:
--- a/piecrust/data/base.py	Sat Jun 27 00:03:56 2015 -0700
+++ b/piecrust/data/base.py	Sat Jun 27 08:27:35 2015 -0700
@@ -2,6 +2,7 @@
 import time
 import logging
 from piecrust.data.assetor import Assetor
+from piecrust.routing import create_route_metadata
 from piecrust.uriutil import split_uri
 
 
@@ -154,12 +155,12 @@
         if self._route is None:
             # TODO: this is not quite correct, as we're missing parts of the
             #       route metadata if the current page is a taxonomy page.
-            self._route = page.app.getRoute(page.source.name,
-                                            page.source_metadata)
-            self._route_metadata = copy.deepcopy(page.source_metadata)
+            route_metadata = create_route_metadata(page)
+            self._route = page.app.getRoute(page.source.name, route_metadata)
+            self._route_metadata = route_metadata
             if self._route is None:
                 raise Exception("Can't get route for page: %s" % page.path)
-        return self._route.getUri(self._route_metadata, provider=page)
+        return self._route.getUri(self._route_metadata)
 
     def _loadCustom(self):
         page_url = self._get_uri()
--- a/piecrust/processing/sitemap.py	Sat Jun 27 00:03:56 2015 -0700
+++ b/piecrust/processing/sitemap.py	Sat Jun 27 08:27:35 2015 -0700
@@ -2,6 +2,7 @@
 import logging
 import yaml
 from piecrust.processing.base import SimpleFileProcessor
+from piecrust.routing import create_route_metadata
 
 
 logger = logging.getLogger(__name__)
@@ -60,14 +61,15 @@
 
         for name in source_names:
             logger.debug("Generating automatic sitemap entries for '%s'." %
-                    name)
+                         name)
             source = self.app.getSource(name)
             if source is None:
                 raise Exception("No such source: %s" % name)
 
             for page in source.getPages():
-                route = self.app.getRoute(source.name, page.source_metadata)
-                uri = route.getUri(page.source_metadata, provider=page)
+                route_metadata = create_route_metadata(page)
+                route = self.app.getRoute(source.name, route_metadata)
+                uri = route.getUri(route_metadata)
 
                 t = page.datetime.timestamp()
                 sm_cfg = page.config.get('sitemap')
--- a/piecrust/rendering.py	Sat Jun 27 00:03:56 2015 -0700
+++ b/piecrust/rendering.py	Sat Jun 27 08:27:35 2015 -0700
@@ -34,8 +34,7 @@
         self.route_metadata = route_metadata
 
     def getUri(self, sub_num=1):
-        return self.route.getUri(self.route_metadata, provider=self.page,
-                                 sub_num=sub_num)
+        return self.route.getUri(self.route_metadata, sub_num=sub_num)
 
     def __getattr__(self, name):
         return getattr(self.page, name)
--- a/piecrust/routing.py	Sat Jun 27 00:03:56 2015 -0700
+++ b/piecrust/routing.py	Sat Jun 27 08:27:35 2015 -0700
@@ -15,6 +15,18 @@
 ugly_url_cleaner = re.compile(r'\.html$')
 
 
+def create_route_metadata(page):
+    route_metadata = copy.deepcopy(page.source_metadata)
+    route_metadata.update(page.getRouteMetadata())
+
+    # TODO: fix this hard-coded shit
+    for key in ['year', 'month', 'day']:
+        if key in route_metadata and isinstance(route_metadata[key], str):
+            route_metadata[key] = int(route_metadata[key])
+
+    return route_metadata
+
+
 class IRouteMetadataProvider(object):
     def getRouteMetadata(self):
         raise NotImplementedError()
@@ -122,16 +134,7 @@
 
         return route_metadata
 
-    def getUri(self, route_metadata, *, sub_num=1, provider=None):
-        route_metadata = copy.deepcopy(route_metadata)
-        if provider:
-            route_metadata.update(provider.getRouteMetadata())
-
-        #TODO: fix this hard-coded shit
-        for key in ['year', 'month', 'day']:
-            if key in route_metadata and isinstance(route_metadata[key], str):
-                route_metadata[key] = int(route_metadata[key])
-
+    def getUri(self, route_metadata, *, sub_num=1):
         uri = self.uri_format % route_metadata
         suffix = None
         if sub_num > 1: