Mercurial > piecrust2
annotate piecrust/baking/single.py @ 182:a54d3c0b5f4a
tests: Patch `os.path.exists` and improve patching for `open`.
You can specify additional modules for which to patch `open`.
Also, it was incorrectly updating the opened file, even when it was opened
for read only. Now it only updates the contents if the file was opened for
write, and supports appending to the end.
Last, it supports opening text files in binary mode.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Sun, 04 Jan 2015 14:55:41 -0800 |
parents | 91dcbb5fe1e8 |
children | 55087da9a72e |
rev | line source |
---|---|
150
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
1 import os.path |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
2 import shutil |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
3 import codecs |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
4 import logging |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
5 import urllib.error |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
6 import urllib.parse |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
7 import urllib.request |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
8 from piecrust.baking.records import FLAG_OVERRIDEN, FLAG_SOURCE_MODIFIED |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
9 from piecrust.data.filters import (PaginationFilter, HasFilterClause, |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
10 IsFilterClause, AndBooleanClause) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
11 from piecrust.rendering import (PageRenderingContext, render_page, |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
12 PASS_FORMATTING, PASS_RENDERING) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
13 from piecrust.sources.base import (PageFactory, |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
14 REALM_NAMES, REALM_USER, REALM_THEME) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
15 |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
16 |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
17 logger = logging.getLogger(__name__) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
18 |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
19 |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
20 class BakingError(Exception): |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
21 pass |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
22 |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
23 |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
24 class PageBaker(object): |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
25 def __init__(self, app, out_dir, force=False, record=None, |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
26 copy_assets=True): |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
27 self.app = app |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
28 self.out_dir = out_dir |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
29 self.force = force |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
30 self.record = record |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
31 self.copy_assets = copy_assets |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
32 self.site_root = app.config.get('site/root') |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
33 self.pretty_urls = app.config.get('site/pretty_urls') |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
34 self.pagination_suffix = app.config.get('site/pagination_suffix') |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
35 |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
36 def getOutputUri(self, uri, num): |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
37 suffix = self.pagination_suffix.replace('%num%', str(num)) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
38 if self.pretty_urls: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
39 # Output will be: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
40 # - `uri/name` |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
41 # - `uri/name/2` |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
42 # - `uri/name.ext` |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
43 # - `uri/name.ext/2` |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
44 if num <= 1: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
45 return uri |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
46 return uri + suffix |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
47 else: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
48 # Output will be: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
49 # - `uri/name.html` |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
50 # - `uri/name/2.html` |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
51 # - `uri/name.ext` |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
52 # - `uri/name/2.ext` |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
53 if uri == '/': |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
54 if num <= 1: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
55 return '/' |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
56 return '/' + suffix.lstrip('/') |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
57 else: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
58 if num <= 1: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
59 return uri |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
60 #TODO: watch out for tags with dots in them. |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
61 base_uri, ext = os.path.splitext(uri) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
62 return base_uri + suffix + ext |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
63 |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
64 def getOutputPath(self, uri): |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
65 bake_path = [self.out_dir] |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
66 decoded_uri = urllib.parse.unquote(uri.lstrip('/')) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
67 if self.pretty_urls: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
68 bake_path.append(decoded_uri) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
69 bake_path.append('index.html') |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
70 else: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
71 name, ext = os.path.splitext(decoded_uri) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
72 if decoded_uri == '': |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
73 bake_path.append('index.html') |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
74 elif ext: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
75 bake_path.append(decoded_uri) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
76 else: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
77 bake_path.append(decoded_uri + '.html') |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
78 |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
79 return os.path.normpath(os.path.join(*bake_path)) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
80 |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
81 def bake(self, factory, route, record_entry, |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
82 taxonomy_name=None, taxonomy_term=None): |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
83 custom_data = None |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
84 pagination_filter = None |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
85 route_metadata = dict(factory.metadata) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
86 if taxonomy_name and taxonomy_term: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
87 # Must bake a taxonomy listing page... we'll have to add a |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
88 # pagination filter for only get matching posts, and the output |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
89 # URL will be a bit different. |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
90 tax = self.app.getTaxonomy(taxonomy_name) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
91 pagination_filter = PaginationFilter() |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
92 if tax.is_multiple: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
93 if isinstance(taxonomy_term, tuple): |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
94 abc = AndBooleanClause() |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
95 for t in taxonomy_term: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
96 abc.addClause(HasFilterClause(taxonomy_name, t)) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
97 pagination_filter.addClause(abc) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
98 slugified_term = '/'.join(taxonomy_term) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
99 else: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
100 pagination_filter.addClause( |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
101 HasFilterClause(taxonomy_name, taxonomy_term)) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
102 slugified_term = taxonomy_term |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
103 else: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
104 pagination_filter.addClause( |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
105 IsFilterClause(taxonomy_name, taxonomy_term)) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
106 slugified_term = taxonomy_term |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
107 custom_data = {tax.term_name: taxonomy_term} |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
108 route_metadata.update({tax.term_name: slugified_term}) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
109 |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
110 # Generate the URL using the route. |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
111 page = factory.buildPage() |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
112 uri = route.getUri(route_metadata, page) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
113 |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
114 override = self.record.getOverrideEntry(factory, uri) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
115 if override is not None: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
116 override_source = self.app.getSource(override.source_name) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
117 if override_source.realm == factory.source.realm: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
118 raise BakingError( |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
119 "Page '%s' maps to URL '%s' but is overriden by page" |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
120 "'%s:%s'." % (factory.ref_spec, uri, |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
121 override.source_name, override.rel_path)) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
122 logger.debug("'%s' [%s] is overriden by '%s:%s'. Skipping" % |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
123 (factory.ref_spec, uri, override.source_name, |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
124 override.rel_path)) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
125 record_entry.flags |= FLAG_OVERRIDEN |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
126 return |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
127 |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
128 cur_sub = 1 |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
129 has_more_subs = True |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
130 force_this = self.force |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
131 invalidate_formatting = False |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
132 record_entry.config = page.config.get().copy() |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
133 prev_record_entry = self.record.getPreviousEntry( |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
134 factory.source.name, factory.rel_path, |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
135 taxonomy_name, taxonomy_term) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
136 |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
137 logger.debug("Baking '%s'..." % uri) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
138 |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
139 # If the current page is known to use pages from other sources, |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
140 # see if any of those got baked, or are going to be baked for some |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
141 # reason. If so, we need to bake this one too. |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
142 # (this happens for instance with the main page of a blog). |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
143 if prev_record_entry and prev_record_entry.was_baked_successfully: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
144 invalidated_render_passes = set() |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
145 used_src_names = list(prev_record_entry.used_source_names) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
146 for src_name, rdr_pass in used_src_names: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
147 entries = self.record.getCurrentEntries(src_name) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
148 for e in entries: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
149 if e.was_baked or e.flags & FLAG_SOURCE_MODIFIED: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
150 invalidated_render_passes.add(rdr_pass) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
151 break |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
152 if len(invalidated_render_passes) > 0: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
153 logger.debug("'%s' is known to use sources %s, at least one " |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
154 "of which got baked. Will force bake this page. " |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
155 % (uri, used_src_names)) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
156 force_this = True |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
157 if PASS_FORMATTING in invalidated_render_passes: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
158 logger.debug("Will invalidate cached formatting for '%s' " |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
159 "since sources were using during that pass." |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
160 % uri) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
161 invalidate_formatting = True |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
162 |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
163 while has_more_subs: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
164 sub_uri = self.getOutputUri(uri, cur_sub) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
165 out_path = self.getOutputPath(sub_uri) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
166 |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
167 # Check for up-to-date outputs. |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
168 do_bake = True |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
169 if not force_this: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
170 try: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
171 in_path_time = record_entry.path_mtime |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
172 out_path_time = os.path.getmtime(out_path) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
173 if out_path_time > in_path_time: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
174 do_bake = False |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
175 except OSError: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
176 # File doesn't exist, we'll need to bake. |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
177 pass |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
178 |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
179 # If this page didn't bake because it's already up-to-date. |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
180 # Keep trying for as many subs as we know this page has. |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
181 if not do_bake: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
182 if (prev_record_entry is not None and |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
183 prev_record_entry.num_subs < cur_sub): |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
184 logger.debug("") |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
185 cur_sub += 1 |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
186 has_more_subs = True |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
187 logger.debug(" %s is up to date, skipping to next " |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
188 "sub-page." % out_path) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
189 continue |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
190 |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
191 # We don't know how many subs to expect... just skip. |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
192 logger.debug(" %s is up to date, skipping bake." % out_path) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
193 break |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
194 |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
195 # All good, proceed. |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
196 try: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
197 if invalidate_formatting: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
198 cache_key = '%s:%s' % (uri, cur_sub) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
199 self.app.env.rendered_segments_repository.invalidate( |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
200 cache_key) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
201 |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
202 logger.debug(" p%d -> %s" % (cur_sub, out_path)) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
203 ctx, rp = self._bakeSingle(page, sub_uri, cur_sub, out_path, |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
204 pagination_filter, custom_data) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
205 except Exception as ex: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
206 if self.app.debug: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
207 logger.exception(ex) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
208 page_rel_path = os.path.relpath(page.path, self.app.root_dir) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
209 raise BakingError("%s: error baking '%s'." % |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
210 (page_rel_path, uri)) from ex |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
211 |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
212 # Copy page assets. |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
213 if (cur_sub == 1 and self.copy_assets and |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
214 ctx.used_assets is not None): |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
215 if self.pretty_urls: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
216 out_assets_dir = os.path.dirname(out_path) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
217 else: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
218 out_assets_dir, out_name = os.path.split(out_path) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
219 if sub_uri != self.site_root: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
220 out_name_noext, _ = os.path.splitext(out_name) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
221 out_assets_dir += out_name_noext |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
222 |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
223 logger.debug("Copying page assets to: %s" % out_assets_dir) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
224 if not os.path.isdir(out_assets_dir): |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
225 os.makedirs(out_assets_dir, 0o755) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
226 for ap in ctx.used_assets: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
227 dest_ap = os.path.join(out_assets_dir, os.path.basename(ap)) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
228 logger.debug(" %s -> %s" % (ap, dest_ap)) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
229 shutil.copy(ap, dest_ap) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
230 |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
231 # Record what we did and figure out if we have more work. |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
232 record_entry.out_uris.append(sub_uri) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
233 record_entry.out_paths.append(out_path) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
234 record_entry.used_source_names |= ctx.used_source_names |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
235 record_entry.used_taxonomy_terms |= ctx.used_taxonomy_terms |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
236 |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
237 has_more_subs = False |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
238 if (ctx.used_pagination is not None and |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
239 ctx.used_pagination.has_more): |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
240 cur_sub += 1 |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
241 has_more_subs = True |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
242 |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
243 def _bakeSingle(self, page, sub_uri, num, out_path, |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
244 pagination_filter=None, custom_data=None): |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
245 ctx = PageRenderingContext(page, sub_uri) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
246 ctx.page_num = num |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
247 if pagination_filter: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
248 ctx.pagination_filter = pagination_filter |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
249 if custom_data: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
250 ctx.custom_data = custom_data |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
251 |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
252 rp = render_page(ctx) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
253 |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
254 out_dir = os.path.dirname(out_path) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
255 if not os.path.isdir(out_dir): |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
256 os.makedirs(out_dir, 0o755) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
257 |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
258 with codecs.open(out_path, 'w', 'utf8') as fp: |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
259 fp.write(rp.content) |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
260 |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
261 return ctx, rp |
91dcbb5fe1e8
Split baking code in smaller files.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
262 |