Mercurial > piecrust2
comparison piecrust/pipelines/_pagebaker.py @ 854:08e02c2a2a1a
core: Keep refactoring, this time to prepare for generator sources.
- Make a few APIs simpler.
- Content pipelines create their own jobs, so that generator sources can
keep aborting in `getContents`, but rely on their pipeline to generate
pages for baking.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Sun, 04 Jun 2017 23:34:28 -0700 |
parents | 4850f8c21b6e |
children | 504ddb370df8 |
comparison
equal
deleted
inserted
replaced
853:f070a4fc033c | 854:08e02c2a2a1a |
---|---|
23 self.copy_assets = copy_assets | 23 self.copy_assets = copy_assets |
24 self.site_root = app.config.get('site/root') | 24 self.site_root = app.config.get('site/root') |
25 self.pretty_urls = app.config.get('site/pretty_urls') | 25 self.pretty_urls = app.config.get('site/pretty_urls') |
26 self._writer_queue = None | 26 self._writer_queue = None |
27 self._writer = None | 27 self._writer = None |
28 self._stats = app.env.stats | |
28 | 29 |
29 def startWriterQueue(self): | 30 def startWriterQueue(self): |
30 self._writer_queue = queue.Queue() | 31 self._writer_queue = queue.Queue() |
31 self._writer = threading.Thread( | 32 self._writer = threading.Thread( |
32 name='PageSerializer', | 33 name='PageSerializer', |
51 else: | 52 else: |
52 bake_path.append(decoded_uri) | 53 bake_path.append(decoded_uri) |
53 | 54 |
54 return os.path.normpath(os.path.join(*bake_path)) | 55 return os.path.normpath(os.path.join(*bake_path)) |
55 | 56 |
56 def bake(self, qualified_page, prev_entry, dirty_source_names): | 57 def bake(self, page, prev_entry, cur_entry, dirty_source_names): |
57 # Start baking the sub-pages. | 58 # Start baking the sub-pages. |
58 cur_sub = 1 | 59 cur_sub = 1 |
59 has_more_subs = True | 60 has_more_subs = True |
60 sub_entries = [] | 61 pretty_urls = page.config.get('pretty_urls', self.pretty_urls) |
61 pretty_urls = qualified_page.config.get( | |
62 'pretty_urls', self.pretty_urls) | |
63 | 62 |
64 while has_more_subs: | 63 while has_more_subs: |
65 sub_page = qualified_page.getSubPage(cur_sub) | 64 sub_uri = page.getUri(sub_num=cur_sub) |
66 sub_uri = sub_page.uri | |
67 logger.debug("Baking '%s' [%d]..." % (sub_uri, cur_sub)) | 65 logger.debug("Baking '%s' [%d]..." % (sub_uri, cur_sub)) |
68 | 66 |
69 out_path = self.getOutputPath(sub_uri, pretty_urls) | 67 out_path = self.getOutputPath(sub_uri, pretty_urls) |
70 | 68 |
71 # Create the sub-entry for the bake record. | 69 # Create the sub-entry for the bake record. |
72 sub_entry = SubPagePipelineRecordEntry(sub_uri, out_path) | 70 sub_entry = SubPagePipelineRecordEntry(sub_uri, out_path) |
73 sub_entries.append(sub_entry) | 71 cur_entry.subs.append(sub_entry) |
74 | 72 |
75 # Find a corresponding sub-entry in the previous bake record. | 73 # Find a corresponding sub-entry in the previous bake record. |
76 prev_sub_entry = None | 74 prev_sub_entry = None |
77 if prev_entry is not None: | 75 if prev_entry is not None: |
78 try: | 76 try: |
87 | 85 |
88 # Check for up-to-date outputs. | 86 # Check for up-to-date outputs. |
89 do_bake = True | 87 do_bake = True |
90 if not force_this_sub: | 88 if not force_this_sub: |
91 try: | 89 try: |
92 in_path_time = qualified_page.path_mtime | 90 in_path_time = page.content_mtime |
93 out_path_time = os.path.getmtime(out_path) | 91 out_path_time = os.path.getmtime(out_path) |
94 if out_path_time >= in_path_time: | 92 if out_path_time >= in_path_time: |
95 do_bake = False | 93 do_bake = False |
96 except OSError: | 94 except OSError: |
97 # File doesn't exist, we'll need to bake. | 95 # File doesn't exist, we'll need to bake. |
121 cache_key) | 119 cache_key) |
122 sub_entry.flags |= \ | 120 sub_entry.flags |= \ |
123 SubPagePipelineRecordEntry.FLAG_FORMATTING_INVALIDATED | 121 SubPagePipelineRecordEntry.FLAG_FORMATTING_INVALIDATED |
124 | 122 |
125 logger.debug(" p%d -> %s" % (cur_sub, out_path)) | 123 logger.debug(" p%d -> %s" % (cur_sub, out_path)) |
126 rp = self._bakeSingle(qualified_page, cur_sub, out_path) | 124 rp = self._bakeSingle(page, cur_sub, out_path) |
127 except Exception as ex: | 125 except Exception as ex: |
128 logger.exception(ex) | 126 logger.exception(ex) |
129 page_rel_path = os.path.relpath(qualified_page.path, | |
130 self.app.root_dir) | |
131 raise BakingError("%s: error baking '%s'." % | 127 raise BakingError("%s: error baking '%s'." % |
132 (page_rel_path, sub_uri)) from ex | 128 (page.content_spec, sub_uri)) from ex |
133 | 129 |
134 # Record what we did. | 130 # Record what we did. |
135 sub_entry.flags |= SubPagePipelineRecordEntry.FLAG_BAKED | 131 sub_entry.flags |= SubPagePipelineRecordEntry.FLAG_BAKED |
136 sub_entry.render_info = rp.copyRenderInfo() | 132 sub_entry.render_info = rp.copyRenderInfo() |
137 | 133 |
147 out_assets_dir = os.path.join(out_assets_dir, | 143 out_assets_dir = os.path.join(out_assets_dir, |
148 out_name_noext) | 144 out_name_noext) |
149 | 145 |
150 logger.debug("Copying page assets to: %s" % out_assets_dir) | 146 logger.debug("Copying page assets to: %s" % out_assets_dir) |
151 _ensure_dir_exists(out_assets_dir) | 147 _ensure_dir_exists(out_assets_dir) |
152 | 148 # TODO: copy assets to out dir |
153 qualified_page.source.buildAssetor(qualified_page, sub_uri).copyAssets(out_assets_dir) | |
154 | 149 |
155 # Figure out if we have more work. | 150 # Figure out if we have more work. |
156 has_more_subs = False | 151 has_more_subs = False |
157 if sub_entry.anyPass(lambda p: p.pagination_has_more): | 152 if sub_entry.anyPass(lambda p: p.pagination_has_more): |
158 cur_sub += 1 | 153 cur_sub += 1 |
159 has_more_subs = True | 154 has_more_subs = True |
160 | 155 |
161 return sub_entries | 156 def _bakeSingle(self, page, sub_num, out_path): |
162 | 157 ctx = RenderingContext(page, sub_num=sub_num) |
163 def _bakeSingle(self, qp, out_path): | 158 page.source.prepareRenderContext(ctx) |
164 ctx = RenderingContext(qp) | 159 |
165 qp.source.prepareRenderContext(ctx) | 160 with self._stats.timerScope("PageRender"): |
166 | |
167 with self.app.env.timerScope("PageRender"): | |
168 rp = render_page(ctx) | 161 rp = render_page(ctx) |
169 | 162 |
170 with self.app.env.timerScope("PageSerialize"): | 163 with self._stats.timerScope("PageSerialize"): |
171 if self._writer_queue is not None: | 164 if self._writer_queue is not None: |
172 self._writer_queue.put_nowait((out_path, rp.content)) | 165 self._writer_queue.put_nowait((out_path, rp.content)) |
173 else: | 166 else: |
174 with open(out_path, 'w', encoding='utf8') as fp: | 167 with open(out_path, 'w', encoding='utf8') as fp: |
175 fp.write(rp.content) | 168 fp.write(rp.content) |