Mercurial > piecrust2
changeset 11:617191dec18e
Fixes for Windows, make `findPagePath` return a ref path.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Mon, 18 Aug 2014 16:47:44 -0700 |
parents | cd35d356ccce |
children | 30a42341cfa8 |
files | piecrust/baking/baker.py piecrust/commands/builtin/util.py piecrust/processing/base.py piecrust/serving.py piecrust/sources/base.py piecrust/sources/posts.py tests/mockutil.py tests/test_baking_baker.py |
diffstat | 8 files changed, 81 insertions(+), 43 deletions(-) [+] |
line wrap: on
line diff
--- a/piecrust/baking/baker.py Sun Aug 17 21:18:48 2014 -0700 +++ b/piecrust/baking/baker.py Mon Aug 18 16:47:44 2014 -0700 @@ -74,7 +74,7 @@ else: bake_path.append(decoded_uri + '.html') - return os.path.join(*bake_path) + return os.path.normpath(os.path.join(*bake_path)) def bake(self, factory, route, taxonomy_name=None, taxonomy_term=None): page = factory.buildPage() @@ -155,9 +155,8 @@ ctx, rp = self._bakeSingle(page, sub_uri, cur_sub, out_path, pagination_filter, custom_data) except Exception as ex: - logger.exception("Error baking page '%s' for URI '%s': %s" % - (page.ref_spec, uri, ex)) - raise + raise Exception("Error baking page '%s' for URI '%s'." % + (page.ref_spec, uri)) from ex cur_record_entry.out_uris.append(sub_uri) cur_record_entry.out_paths.append(out_path)
--- a/piecrust/commands/builtin/util.py Sun Aug 17 21:18:48 2014 -0700 +++ b/piecrust/commands/builtin/util.py Mon Aug 18 16:47:44 2014 -0700 @@ -86,18 +86,19 @@ app = ctx.app source = ctx.args.source metadata = source.buildMetadata(ctx.args) - page_path = source.findPagePath(metadata, MODE_CREATING) - name, ext = os.path.splitext(page_path) + rel_path, metadata = source.findPagePath(metadata, MODE_CREATING) + path = source.resolveRef(rel_path) + name, ext = os.path.splitext(path) if ext == '.*': - page_path = '%s.%s' % (name, + path = '%s.%s' % (name, app.config.get('site/default_auto_format')) - if os.path.exists(page_path): - raise Exception("'%s' already exists." % page_path) + if os.path.exists(path): + raise Exception("'%s' already exists." % path) - logger.info("Creating page: %s" % os.path.relpath(page_path, app.root_dir)) - if not os.path.exists(os.path.dirname(page_path)): - os.makedirs(os.path.dirname(page_path), 0o755) - with open(page_path, 'w') as f: + logger.info("Creating page: %s" % os.path.relpath(path, app.root_dir)) + if not os.path.exists(os.path.dirname(path)): + os.makedirs(os.path.dirname(path), 0o755) + with open(path, 'w') as f: f.write('---\n') f.write('title: %s\n' % 'Unknown title') f.write('---\n')
--- a/piecrust/processing/base.py Sun Aug 17 21:18:48 2014 -0700 +++ b/piecrust/processing/base.py Mon Aug 18 16:47:44 2014 -0700 @@ -329,6 +329,8 @@ def re_matchany(filename, patterns): + # skip patterns use a forward slash regardless of the platform. + filename = filename.replace('\\', '/') for pattern in patterns: if pattern.match(filename): return True
--- a/piecrust/serving.py Sun Aug 17 21:18:48 2014 -0700 +++ b/piecrust/serving.py Mon Aug 18 16:47:44 2014 -0700 @@ -1,6 +1,7 @@ import re import gzip import time +import os import os.path import hashlib import logging @@ -17,7 +18,7 @@ from piecrust.page import Page from piecrust.processing.base import ProcessorPipeline from piecrust.rendering import PageRenderingContext, render_page -from piecrust.sources.base import MODE_PARSING +from piecrust.sources.base import PageFactory, MODE_PARSING logger = logging.getLogger(__name__) @@ -103,7 +104,7 @@ def _try_serve_asset(self, app, environ, request): logger.debug("Searching for asset with path: %s" % request.path) - rel_req_path = request.path.lstrip('/') + rel_req_path = request.path.lstrip('/').replace('/', os.sep) entry = self._record.findEntry(rel_req_path) if entry is None: return None @@ -161,16 +162,16 @@ for route, route_metadata in routes: source = app.getSource(route.source_name) if route.taxonomy is None: - path, fac_metadata = source.findPagePath( + rel_path, fac_metadata = source.findPagePath( route_metadata, MODE_PARSING) - if path is not None: + if rel_path is not None: break else: taxonomy = app.getTaxonomy(route.taxonomy) term_value = route_metadata.get(taxonomy.term_name) if term_value is not None: tax_page_ref = taxonomy.getPageRef(source.name) - path = tax_page_ref.path + rel_path = tax_page_ref.rel_path source = tax_page_ref.source fac_metadata = {taxonomy.term_name: term_value} break @@ -180,7 +181,8 @@ (req_path, [r.source_name for r, _ in routes])) # Build the page and render it. - page = Page(source, fac_metadata, path) + fac = PageFactory(source, rel_path, fac_metadata) + page = fac.buildPage() render_ctx = PageRenderingContext(page, req_path, page_num) if taxonomy is not None: flt = PaginationFilter()
--- a/piecrust/sources/base.py Sun Aug 17 21:18:48 2014 -0700 +++ b/piecrust/sources/base.py Mon Aug 18 16:47:44 2014 -0700 @@ -294,6 +294,7 @@ self.fs_endpoint = config.get('fs_endpoint', name) self.fs_endpoint_path = os.path.join(self.root_dir, CONTENT_DIR, self.fs_endpoint) self.supported_extensions = list(app.config.get('site/auto_formats').keys()) + self.default_auto_format = app.config.get('site/default_auto_format') def buildPageFactories(self): logger.debug("Scanning for pages in: %s" % self.fs_endpoint_path) @@ -313,22 +314,26 @@ fac_path = f if rel_dirpath != '.': fac_path = os.path.join(rel_dirpath, f) + fac_path = fac_path.replace('\\', '/') yield PageFactory(self, fac_path, metadata) def resolveRef(self, ref_path): - return os.path.join(self.fs_endpoint_path, ref_path) + return os.path.normpath( + os.path.join(self.fs_endpoint_path, ref_path)) def findPagePath(self, metadata, mode): uri_path = metadata['path'] if uri_path == '': uri_path = '_index' - path = os.path.join(self.fs_endpoint_path, uri_path) + path = os.path.normpath(os.path.join(self.fs_endpoint_path, uri_path)) _, ext = os.path.splitext(path) if mode == MODE_CREATING: if ext == '': - return '%s.*' % path - return path, metadata + path = '%s.%s' % (path, self.default_auto_format) + rel_path = os.path.relpath(path, self.fs_endpoint_path) + rel_path = rel_path.replace('\\', '/') + return rel_path, metadata if ext == '': paths_to_check = ['%s.%s' % (path, e) @@ -337,7 +342,9 @@ paths_to_check = [path] for path in paths_to_check: if os.path.isfile(path): - return path, metadata + rel_path = os.path.relpath(path, self.fs_endpoint_path) + rel_path = rel_path.replace('\\', '/') + return rel_path, metadata return None, None @@ -393,5 +400,8 @@ def __iter__(self): for page in self.it: - yield PaginationData(page) + if page is None: + yield None + else: + yield PaginationData(page)
--- a/piecrust/sources/posts.py Sun Aug 17 21:18:48 2014 -0700 +++ b/piecrust/sources/posts.py Mon Aug 18 16:47:44 2014 -0700 @@ -8,7 +8,7 @@ from piecrust.sources.base import (PageSource, IPreparingSource, SimplePaginationSourceMixin, PageNotFoundError, InvalidFileSystemEndpointError, - PageFactory, MODE_CREATING) + PageFactory, MODE_CREATING, MODE_PARSING) logger = logging.getLogger(__name__) @@ -22,13 +22,14 @@ self.fs_endpoint = config.get('fs_endpoint', name) self.fs_endpoint_path = os.path.join(self.root_dir, CONTENT_DIR, self.fs_endpoint) self.supported_extensions = list(app.config.get('site/auto_formats').keys()) + self.default_auto_format = app.config.get('site/default_auto_format') @property def path_format(self): return self.__class__.PATH_FORMAT def resolveRef(self, ref_path): - return os.path.join(self.fs_endpoint_path, ref_path) + return os.path.normpath(os.path.join(self.fs_endpoint_path, ref_path)) def findPagePath(self, metadata, mode): year = metadata.get('year') @@ -40,6 +41,8 @@ if ext is None: if len(self.supported_extensions) == 1: ext = self.supported_extensions[0] + elif mode == MODE_CREATING and self.default_auto_format: + ext = self.default_auto_format replacements = { 'year': year, @@ -64,7 +67,8 @@ if ext is None: needs_recapture = True replacements['ext'] = '*' - path = os.path.join(self.fs_endpoint_path, self.path_format % replacements) + path = os.path.normpath(os.path.join( + self.fs_endpoint_path, self.path_format % replacements)) if needs_recapture: if mode == MODE_CREATING: @@ -73,8 +77,8 @@ if len(possible_paths) != 1: raise PageNotFoundError() path = possible_paths[0] - elif not os.path.isfile(path): - raise PageNotFoundError() + elif mode == MODE_PARSING and not os.path.isfile(path): + raise PageNotFoundError(path) regex_repl = { 'year': '(?P<year>\d{4})', @@ -83,8 +87,12 @@ 'slug': '(?P<slug>.*)', 'ext': '(?P<ext>.*)' } - pattern = os.path.join(self.fs_endpoint_path, self.path_format) % regex_repl - m = re.match(pattern, path) + #sanitized_fs_endpoint_path = (self.fs_endpoint_path. + # replace('\\', '/').rstrip('/')) + #pattern = (re.escape(sanitized_fs_endpoint_path) + '/' + + # self.path_format % regex_repl) + pattern = self.path_format % regex_repl + '$' + m = re.search(pattern, path.replace('\\', '/')) if not m: raise Exception("Expected to be able to match path with path " "format: %s" % path) @@ -94,8 +102,9 @@ 'day': m.group('day'), 'slug': m.group('slug') } - - return path, fac_metadata + rel_path = os.path.relpath(path, self.fs_endpoint_path) + rel_path = rel_path.replace('\\', '/') + return rel_path, fac_metadata def setupPrepareParser(self, parser, app): parser.add_argument('-d', '--date', help="The date of the post, " @@ -114,6 +123,7 @@ raise InvalidFileSystemEndpointError(self.name, self.fs_endpoint_path) def _makeFactory(self, path, slug, year, month, day): + path = path.replace('\\', '/') timestamp = datetime.date(year, month, day) metadata = { 'slug': slug,
--- a/tests/mockutil.py Sun Aug 17 21:18:48 2014 -0700 +++ b/tests/mockutil.py Mon Aug 18 16:47:44 2014 -0700 @@ -40,6 +40,7 @@ "site:\n title: Mock Website\n") def path(self, p): + p = p.replace('\\', '/') if p in ['/', '', None]: return '/%s' % self._root return '/%s/%s' % (self._root, p.lstrip('/')) @@ -49,6 +50,7 @@ return PieCrust(root_dir, cache=False) def withDir(self, path): + path = path.replace('\\', '/') cur = self._fs[self._root] for b in path.split('/'): if b not in cur: @@ -57,6 +59,7 @@ return self def withFile(self, path, contents): + path = path.replace('\\', '/') cur = self._fs[self._root] bits = path.split('/') for b in bits[:-1]: @@ -73,11 +76,13 @@ return self.withDir('kitchen/' + path) def withConfig(self, config): - return self.withFile('kitchen/_content/config.yml', + return self.withFile( + 'kitchen/_content/config.yml', yaml.dump(config)) def withThemeConfig(self, config): - return self.withFile('kitchen/_content/theme/_content/theme_config.yml', + return self.withFile( + 'kitchen/_content/theme/_content/theme_config.yml', yaml.dump(config)) def withPage(self, url, config=None, contents=None): @@ -92,7 +97,7 @@ if not ext: url += '.md' url = url.lstrip('/') - return self.withAsset('_content/pages/' + url, text) + return self.withAsset('_content/' + url, text) def withPageAsset(self, page_url, name, contents=None): contents = contents or "A test asset." @@ -138,25 +143,31 @@ self._patchers.append(mock.patch(name, func, **kwargs)) def _open(self, path, *args, **kwargs): - path = os.path.abspath(path) + path = os.path.normpath(path) if path.startswith(resources_path): return self._originals['__main__.open'](path, **kwargs) e = self._getFsEntry(path) + if e is None: + raise OSError("No such file: %s" % path) return io.StringIO(e[0]) def _codecsOpen(self, path, *args, **kwargs): - path = os.path.abspath(path) + path = os.path.normpath(path) if path.startswith(resources_path): return self._originals['codecs.open'](path, *args, **kwargs) e = self._getFsEntry(path) + if e is None: + raise OSError("No such file: %s" % path) return io.StringIO(e[0]) def _listdir(self, path): if not path.startswith('/' + self._root): return self._originals['os.listdir'](path) e = self._getFsEntry(path) + if e is None: + raise OSError("No such directory: %s" % path) if not isinstance(e, dict): - raise Exception("'%s' is not a directory." % path) + raise OSError("'%s' is not a directory." % path) return list(e.keys()) def _isdir(self, path): @@ -175,12 +186,13 @@ return self._originals['os.path.getmtime'](path) e = self._getFsEntry(path) if e is None: - raise OSError() + raise OSError("No such file: %s" % path) return e[1]['mtime'] def _getFsEntry(self, path): cur = self._fs - bits = path.lstrip('/').split('/') + path = path.replace('\\', '/').lstrip('/') + bits = path.split('/') for p in bits: try: cur = cur[p]
--- a/tests/test_baking_baker.py Sun Aug 17 21:18:48 2014 -0700 +++ b/tests/test_baking_baker.py Mon Aug 18 16:47:44 2014 -0700 @@ -1,3 +1,4 @@ +import os.path import pytest from piecrust.baking.baker import PageBaker from .mockutil import get_mock_app @@ -36,6 +37,7 @@ baker = PageBaker(app, '/destination') sub_uri = baker.getOutputUri(uri, page_num) path = baker.getOutputPath(sub_uri) - expected = '/destination/' + expected + expected = os.path.normpath( + os.path.join('/destination', expected)) assert expected == path