Mercurial > piecrust2
diff piecrust/commands/builtin/scaffolding.py @ 852:4850f8c21b6e
core: Start of the big refactor for PieCrust 3.0.
* Everything is a `ContentSource`, including assets directories.
* Most content sources are subclasses of the base file-system source.
* A source is processed by a "pipeline", and there are 2 built-in pipelines,
one for assets and one for pages. The asset pipeline is vaguely functional,
but the page pipeline is completely broken right now.
* Rewrite the baking process as just running appropriate pipelines on each
content item. This should allow for better parallelization.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Wed, 17 May 2017 00:11:48 -0700 |
parents | 2bb3c1a04e98 |
children | 58ae026b4c31 |
line wrap: on
line diff
--- a/piecrust/commands/builtin/scaffolding.py Sat Apr 29 21:42:22 2017 -0700 +++ b/piecrust/commands/builtin/scaffolding.py Wed May 17 00:11:48 2017 -0700 @@ -1,6 +1,5 @@ import os import os.path -import re import io import time import glob @@ -9,19 +8,13 @@ from piecrust import RESOURCES_DIR from piecrust.chefutil import print_help_item from piecrust.commands.base import ExtendableChefCommand, ChefCommandExtension -from piecrust.sources.base import MODE_CREATING -from piecrust.sources.interfaces import IPreparingSource -from piecrust.uriutil import multi_replace +from piecrust.pathutil import SiteNotFoundError +from piecrust.sources.fs import FSContentSourceBase logger = logging.getLogger(__name__) -def make_title(slug): - slug = re.sub(r'[\-_]', ' ', slug) - return slug.title() - - class PrepareCommand(ExtendableChefCommand): """ Chef command for creating pages with some default content. """ @@ -36,6 +29,8 @@ if app.root_dir is None: return + from piecrust.sources.interfaces import IPreparingSource + subparsers = parser.add_subparsers() for src in app.sources: if not isinstance(src, IPreparingSource): @@ -47,14 +42,16 @@ "source." % src.name) continue p = subparsers.add_parser( - src.item_name, - help=("Creates an empty page in the '%s' source." % - src.name)) + src.config['item_name'], + help=("Creates an empty page in the '%s' source." % + src.name)) src.setupPrepareParser(p, app) p.add_argument('-t', '--template', default='default', help="The template to use, which will change the " - "generated text and header. Run `chef help " - "scaffolding` for more information.") + "generated text and header. Run `chef help " + "scaffolding` for more information.") + p.add_argument('-f', '--force', action='store_true', + help="Overwrite any existing content.") p.set_defaults(source=src) p.set_defaults(sub_func=self._doRun) @@ -68,60 +65,55 @@ ctx.args.sub_func(ctx) def _doRun(self, ctx): + from piecrust.uriutil import multi_replace + if not hasattr(ctx.args, 'source'): raise Exception("No source specified. " "Please run `chef prepare -h` for usage.") app = ctx.app - source = ctx.args.source - metadata = source.buildMetadata(ctx.args) - factory = source.findPageFactory(metadata, MODE_CREATING) - path = factory.path - name, ext = os.path.splitext(path) - if ext == '.*': - path = '%s.%s' % ( - name, - app.config.get('site/default_auto_format')) - if os.path.exists(path): - raise Exception("'%s' already exists." % path) - tpl_name = ctx.args.template extensions = self.getExtensions(app) ext = next( - filter( - lambda e: tpl_name in e.getTemplateNames(ctx.app), - extensions), - None) + filter( + lambda e: tpl_name in e.getTemplateNames(app), + extensions), + None) if ext is None: raise Exception("No such page template: %s" % tpl_name) - - tpl_text = ext.getTemplate(ctx.app, tpl_name) + tpl_text = ext.getTemplate(app, tpl_name) if tpl_text is None: raise Exception("Error loading template: %s" % tpl_name) - title = (metadata.get('slug') or metadata.get('path') or - 'Untitled page') - title = make_title(title) - tokens = { - '%title%': title, - '%time.today%': time.strftime('%Y/%m/%d'), - '%time.now%': time.strftime('%H:%M:%S')} - tpl_text = multi_replace(tpl_text, tokens) + + source = ctx.args.source + content_item = source.createContent(ctx.args) - 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) + config_tokens = { + '%title%': "Untitled Content", + '%time.today%': time.strftime('%Y/%m/%d'), + '%time.now%': time.strftime('%H:%M:%S') + } + config = content_item.metadata.get('config') + if config: + for k, v in config.items(): + config_tokens['%%%s%%' % k] = v + tpl_text = multi_replace(tpl_text, config_tokens) - with open(path, 'w') as f: + logger.info("Creating content: %s" % content_item.spec) + mode = 'w' if ctx.args.force else 'x' + with content_item.open(mode) as f: f.write(tpl_text) + # If this was a file-system content item, see if we need to auto-open + # an editor on it. editor = ctx.app.config.get('prepare/editor') editor_type = ctx.app.config.get('prepare/editor_type', 'exe') - if editor: + if editor and isinstance(source, FSContentSourceBase): import shlex shell = False - args = '%s "%s"' % (editor, path) + args = '%s "%s"' % (editor, content_item.spec) if '%path%' in editor: - args = editor.replace('%path%', path) + args = editor.replace('%path%', content_item.spec) if editor_type.lower() == 'shell': shell = True @@ -146,9 +138,9 @@ def getTemplateDescription(self, app, name): descs = { - 'default': "The default template, for a simple page.", - 'rss': "A fully functional RSS feed.", - 'atom': "A fully functional Atom feed."} + 'default': "The default template, for a simple page.", + 'rss': "A fully functional RSS feed.", + 'atom': "A fully functional Atom feed."} return descs[name] def getTemplate(self, app, name): @@ -189,7 +181,7 @@ raise Exception("No such page scaffolding template: %s" % name) if len(matches) > 1: raise Exception( - "More than one scaffolding template has name: %s" % name) + "More than one scaffolding template has name: %s" % name) with open(matches[0], 'r', encoding='utf8') as fp: return fp.read() @@ -214,16 +206,16 @@ help_list = tplh.getvalue() help_txt = ( - textwrap.fill( - "Running the 'prepare' command will let " - "PieCrust setup a page for you in the correct place, with " - "some hopefully useful default text.") + - "\n\n" + - textwrap.fill("The following templates are available:") + - "\n\n" + - help_list + - "\n" + - "You can add user-defined templates by creating pages in a " - "`scaffold/pages` sub-directory in your website.") + textwrap.fill( + "Running the 'prepare' command will let " + "PieCrust setup a page for you in the correct place, with " + "some hopefully useful default text.") + + "\n\n" + + textwrap.fill("The following templates are available:") + + "\n\n" + + help_list + + "\n" + + "You can add user-defined templates by creating pages in a " + "`scaffold/pages` sub-directory in your website.") return help_txt