Mercurial > piecrust2
view piecrust/pipelines/page.py @ 881:b4e10471e970
bake: Don't create bake jobs for overriden pages.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Sat, 17 Jun 2017 09:02:15 -0700 |
parents | d6d35b2efd04 |
children | 812ca80863d4 |
line wrap: on
line source
import logging from piecrust.pipelines.base import ContentPipeline from piecrust.pipelines._pagebaker import PageBaker from piecrust.pipelines._pagerecords import PagePipelineRecordEntry from piecrust.sources.base import AbortedSourceUseError logger = logging.getLogger(__name__) class PagePipeline(ContentPipeline): PIPELINE_NAME = 'page' RECORD_ENTRY_CLASS = PagePipelineRecordEntry def __init__(self, source, ppctx): super().__init__(source, ppctx) self._pagebaker = None self._stats = source.app.env.stats def initialize(self): stats = self.app.env.stats stats.registerCounter('SourceUseAbortions', raise_if_registered=False) self._pagebaker = PageBaker(self.app, self.ctx.out_dir, force=self.ctx.force) self._pagebaker.startWriterQueue() def createJobs(self, ctx): used_paths = {} for rec in ctx.record_histories.current.records: src_name = rec.name.split('@')[0] for e in rec.getEntries(): paths = e.getAllOutputPaths() if paths is not None: for p in paths: used_paths[p] = (src_name, e) jobs = [] route = self.source.route pretty_urls = self.app.config.get('site/pretty_urls') record = ctx.record_histories.current.getRecord(self.record_name) for item in self.source.getAllContents(): route_params = item.metadata['route_params'] uri = route.getUri(route_params) path = self._pagebaker.getOutputPath(uri, pretty_urls) override = used_paths.get(path) if override is not None: override_source_name, override_entry = override override_source = self.app.getSource(override_source_name) if override_source.config['realm'] == \ self.source.config['realm']: logger.error( "Page '%s' would get baked to '%s' " "but is overriden by '%s'." % (item.spec, path, override_entry.item_spec)) else: logger.debug( "Page '%s' would get baked to '%s' " "but is overriden by '%s'." % (item.spec, path, override_entry.item_spec)) entry = PagePipelineRecordEntry() entry.item_spec = item.spec entry.flags |= PagePipelineRecordEntry.FLAG_OVERRIDEN record.addEntry(entry) continue jobs.append(self.createJob(item)) if len(jobs) > 0: return jobs return None def mergeRecordEntry(self, record_entry, ctx): existing = ctx.record.getEntry(record_entry.item_spec) existing.errors += record_entry.errors existing.flags |= record_entry.flags existing.subs = record_entry.subs def run(self, job, ctx, result): step_num = job.step_num if step_num == 0: self._loadPage(job.content_item, ctx, result) elif step_num == 1: self._renderOrPostpone(job.content_item, ctx, result) elif step_num == 2: self._renderAlways(job.content_item, ctx, result) def getDeletions(self, ctx): for prev, cur in ctx.record_history.diffs: if prev and not cur: for sub in prev.subs: yield (sub.out_path, 'previous source file was removed') elif prev and cur: prev_out_paths = [o.out_path for o in prev.subs] cur_out_paths = [o.out_path for o in cur.subs] diff = set(prev_out_paths) - set(cur_out_paths) for p in diff: yield (p, 'source file changed outputs') def collapseRecords(self, ctx): pass def shutdown(self): self._pagebaker.stopWriterQueue() def _loadPage(self, content_item, ctx, result): logger.debug("Loading page: %s" % content_item.spec) page = self.app.getPage(self.source, content_item) record_entry = result.record_entry record_entry.config = page.config.getAll() record_entry.timestamp = page.datetime.timestamp() result.next_step_job = self.createJob(content_item) def _renderOrPostpone(self, content_item, ctx, result): # Here our job is to render the page's segments so that they're # cached in memory and on disk... unless we detect that the page # is using some other sources, in which case we abort and we'll try # again on the second pass. logger.debug("Conditional render for: %s" % content_item.spec) page = self.app.getPage(self.source, content_item) prev_entry = ctx.previous_entry cur_entry = result.record_entry self.app.env.abort_source_use = True try: self._pagebaker.bake(page, prev_entry, cur_entry) except AbortedSourceUseError: logger.debug("Page was aborted for using source: %s" % content_item.spec) self.app.env.stats.stepCounter("SourceUseAbortions") result.next_step_job = self.createJob(content_item) finally: self.app.env.abort_source_use = False def _renderAlways(self, content_item, ctx, result): logger.debug("Full render for: %s" % content_item.spec) page = self.app.getPage(self.source, content_item) prev_entry = ctx.previous_entry cur_entry = result.record_entry self._pagebaker.bake(page, prev_entry, cur_entry)