Mercurial > piecrust2
view piecrust/sources/pageref.py @ 550:6f216c1ab6b1
bake: Add a flag to know which record entries got collapsed from last run.
This makes it possible to find entries for things that were actually baked
during the current run, as opposed to skipped because they were "clean".
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Tue, 04 Aug 2015 21:22:30 -0700 |
parents | e7b865f8f335 |
children | ab5c6a8ae90a |
line wrap: on
line source
import re import os.path import copy from piecrust.sources.base import PageFactory page_ref_pattern = re.compile(r'(?P<src>[\w]+)\:(?P<path>.*?)(;|$)') class PageNotFoundError(Exception): pass class PageRef(object): """ A reference to a page, with support for looking a page in different realms. """ _INDEX_NEEDS_LOADING = -2 _INDEX_NOT_FOUND = -1 class _HitInfo(object): def __init__(self, source_name, rel_path, path, metadata): self.source_name = source_name self.rel_path = rel_path self.path = path self.metadata = metadata def __init__(self, app, page_ref): self.app = app self._page_ref = page_ref self._hits = None self._first_valid_hit_index = self._INDEX_NEEDS_LOADING self._exts = list(app.config.get('site/auto_formats').keys()) @property def exists(self): try: self._checkHits() return True except PageNotFoundError: return False @property def source_name(self): return self._first_valid_hit.source_name @property def source(self): return self.app.getSource(self.source_name) @property def rel_path(self): return self._first_valid_hit.rel_path @property def path(self): return self._first_valid_hit.path @property def metadata(self): return self._first_valid_hit.metadata @property def possible_ref_specs(self): self._load() return ['%s:%s' % (h.source_name, h.rel_path) for h in self._hits] @property def possible_split_ref_specs(self): self._load() return [(h.source_name, h.rel_path) for h in self._hits] @property def possible_paths(self): self._load() return [h.path for h in self._hits] def getFactory(self): return PageFactory(self.source, self.rel_path, copy.deepcopy(self.metadata)) @property def _first_valid_hit(self): self._checkHits() return self._hits[self._first_valid_hit_index] def _load(self): if self._hits is not None: return self._hits = [] if self._page_ref is None: self._first_valid_hit_index = self._INDEX_NOT_FOUND return it = list(page_ref_pattern.finditer(self._page_ref)) if len(it) == 0: raise Exception("Invalid page ref: %s" % self._page_ref) for m in it: source_name = m.group('src') source = self.app.getSource(source_name) if source is None: raise Exception("No such source: %s" % source_name) rel_path = m.group('path') if '%ext%' in rel_path: for e in self._exts: cur_rel_path = rel_path.replace('%ext%', e) path, metadata = source.resolveRef(cur_rel_path) self._hits.append(self._HitInfo( source_name, cur_rel_path, path, metadata)) else: path, metadata = source.resolveRef(rel_path) self._hits.append( self._HitInfo(source_name, rel_path, path, metadata)) def _checkHits(self): if self._first_valid_hit_index >= 0: return if self._first_valid_hit_index == self._INDEX_NEEDS_LOADING: self._load() self._first_valid_hit_index = self._INDEX_NOT_FOUND for i, hit in enumerate(self._hits): if os.path.isfile(hit.path): self._first_valid_hit_index = i break if self._first_valid_hit_index == self._INDEX_NOT_FOUND: raise PageNotFoundError( "No valid paths were found for page reference: %s" % self._page_ref)