Mercurial > piecrust2
view piecrust/sources/mixins.py @ 711:ab5c6a8ae90a
bake: Replace hard-coded taxonomy support with "generator" system.
* Taxonomies are now implemented one or more `TaxonomyGenerator`s.
* A `BlogArchivesGenerator` stub is there but non-functional.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Thu, 26 May 2016 19:52:47 -0700 |
parents | 32c7c2d219d2 |
children | 4850f8c21b6e |
line wrap: on
line source
import os import os.path import logging from piecrust.data.filters import PaginationFilter, page_value_accessor from piecrust.data.paginationdata import PaginationData from piecrust.sources.base import PageFactory from piecrust.sources.interfaces import IPaginationSource, IListableSource from piecrust.sources.pageref import PageRef logger = logging.getLogger(__name__) class SourceFactoryIterator(object): def __init__(self, source): self.source = source # This is to permit recursive traversal of the # iterator chain. It acts as the end. self.it = None def __iter__(self): return self.source.getPages() class SourceFactoryWithoutGeneratorsIterator(object): def __init__(self, source): self.source = source self._generator_pages = None # See comment above. self.it = None def __iter__(self): self._cacheGeneratorPages() for p in self.source.getPages(): if p.rel_path in self._generator_pages: continue yield p def _cacheGeneratorPages(self): if self._generator_pages is not None: return app = self.source.app self._generator_pages = set() for src in app.sources: for gen in app.generators: for sn, rp in gen.page_ref.possible_split_ref_specs: if sn == self.source.name: self._generator_pages.add(rp) class DateSortIterator(object): def __init__(self, it, reverse=True): self.it = it self.reverse = reverse def __iter__(self): return iter(sorted(self.it, key=lambda x: x.datetime, reverse=self.reverse)) class PaginationDataBuilderIterator(object): def __init__(self, it): self.it = it def __iter__(self): for page in self.it: if page is None: yield None else: yield PaginationData(page) class SimplePaginationSourceMixin(IPaginationSource): """ Implements the `IPaginationSource` interface in a standard way that should fit most page sources. """ def getItemsPerPage(self): return self.config['items_per_page'] def getSourceIterator(self): if self.config.get('iteration_includes_generator_pages', False): return SourceFactoryIterator(self) return SourceFactoryWithoutGeneratorsIterator(self) def getSorterIterator(self, it): return DateSortIterator(it) def getTailIterator(self, it): return PaginationDataBuilderIterator(it) def getPaginationFilter(self, page): conf = (page.config.get('items_filters') or self.config.get('items_filters')) if conf == 'none' or conf == 'nil' or conf == '': conf = None if conf is not None: f = PaginationFilter(value_accessor=page_value_accessor) f.addClausesFromConfig(conf) return f return None def getSettingAccessor(self): return page_value_accessor class SimpleListableSourceMixin(IListableSource): """ Implements the `IListableSource` interface for sources that map to simple file-system structures. """ def listPath(self, rel_path): rel_path = rel_path.lstrip('\\/') path = self._getFullPath(rel_path) names = self._sortFilenames(os.listdir(path)) items = [] for name in names: if os.path.isdir(os.path.join(path, name)): if self._filterPageDirname(name): rel_subdir = os.path.join(rel_path, name) items.append((True, name, rel_subdir)) else: if self._filterPageFilename(name): slug = self._makeSlug(os.path.join(rel_path, name)) metadata = {'slug': slug} fac_path = name if rel_path != '.': fac_path = os.path.join(rel_path, name) fac_path = fac_path.replace('\\', '/') self._populateMetadata(fac_path, metadata) fac = PageFactory(self, fac_path, metadata) name, _ = os.path.splitext(name) items.append((False, name, fac)) return items def getDirpath(self, rel_path): return os.path.dirname(rel_path) def getBasename(self, rel_path): filename = os.path.basename(rel_path) name, _ = os.path.splitext(filename) return name def _getFullPath(self, rel_path): return os.path.join(self.fs_endpoint_path, rel_path) def _sortFilenames(self, names): return sorted(names) def _filterPageDirname(self, name): return True def _filterPageFilename(self, name): return True def _makeSlug(self, rel_path): return rel_path.replace('\\', '/') def _populateMetadata(self, rel_path, metadata, mode=None): pass