view piecrust/commands/builtin/info.py @ 975:a0a62d0da723

internal: Check that the `Assetor` has an asset URL format to work with.
author Ludovic Chabant <ludovic@chabant.com>
date Tue, 17 Oct 2017 01:08:56 -0700
parents 58ae026b4c31
children 07c23be08029
line wrap: on
line source

import os.path
import logging
from piecrust.commands.base import ChefCommand


logger = logging.getLogger(__name__)


class RootCommand(ChefCommand):
    def __init__(self):
        super(RootCommand, self).__init__()
        self.name = 'root'
        self.description = "Gets the root directory of the current website."

    def setupParser(self, parser, app):
        pass

    def run(self, ctx):
        logger.info(ctx.app.root_dir)


class ShowConfigCommand(ChefCommand):
    def __init__(self):
        super(ShowConfigCommand, self).__init__()
        self.name = 'showconfig'
        self.description = ("Shows the website's configuration.")

    def setupParser(self, parser, app):
        parser.add_argument(
            'path',
            help="The path to a config section or value",
            nargs='?')

    def run(self, ctx):
        import yaml
        from piecrust.configuration import ConfigurationDumper

        if ctx.args.path:
            show = ctx.app.config.get(ctx.args.path)
        else:
            show = ctx.app.config.getAll()

        if show is not None:
            if isinstance(show, (dict, list)):
                out = yaml.dump(show, default_flow_style=False,
                                Dumper=ConfigurationDumper)
                logger.info(out)
            else:
                logger.info(show)
        elif ctx.args.path:
            logger.error("No such configuration path: %s" % ctx.args.path)
            ctx.result = 1


class ShowSourcesCommand(ChefCommand):
    def __init__(self):
        super(ShowSourcesCommand, self).__init__()
        self.name = 'sources'
        self.description = "Shows the sources defined for this website."

    def setupParser(self, parser, app):
        pass

    def run(self, ctx):
        for src in ctx.app.sources:
            logger.info("%s:" % src.name)
            logger.info("    type: %s" % src.config.get('type'))
            logger.debug("    class: %s" % type(src))
            desc = src.describe()
            if isinstance(desc, dict):
                for k, v in desc.items():
                    logger.info("    %s: %s" % (k, v))


class ShowRoutesCommand(ChefCommand):
    def __init__(self):
        super(ShowRoutesCommand, self).__init__()
        self.name = 'routes'
        self.description = "Shows the routes defined for this website."

    def setupParser(self, parser, app):
        pass

    def run(self, ctx):
        for route in ctx.app.routes:
            logger.info("%s:" % route.uri_pattern)
            logger.info("    source: %s" % (route.source_name or ''))
            logger.info("    regex: %s" % route.uri_re.pattern)
            logger.info("    function: %s(%s)" % (
                route.func_name,
                ', '.join(route.uri_params)))


class ShowPathsCommand(ChefCommand):
    def __init__(self):
        super(ShowPathsCommand, self).__init__()
        self.name = 'paths'
        self.description = "Shows the paths that this website is using."

    def setupParser(self, parser, app):
        pass

    def run(self, ctx):
        app = ctx.app
        paths = ['theme_dir', 'templates_dirs', 'cache_dir']
        for p in paths:
            value = getattr(app, p)
            if isinstance(value, list):
                logging.info("%s:" % p)
                for v in value:
                    logging.info("  - %s" % v)
            else:
                logging.info("%s: %s" % (p, value))


class FindCommand(ChefCommand):
    def __init__(self):
        super(FindCommand, self).__init__()
        self.name = 'find'
        self.description = "Find pages in the website."

    def setupParser(self, parser, app):
        parser.add_argument(
            'pattern',
            help="The pattern to match with page filenames",
            nargs='?')
        parser.add_argument(
            '-n', '--name',
            help="Limit the search to sources matching this name")
        parser.add_argument(
            '--full-path',
            help="Return full paths instead of root-relative paths",
            action='store_true')
        parser.add_argument(
            '--metadata',
            help="Return metadata about the page instead of just the path",
            action='store_true')
        parser.add_argument(
            '--include-theme',
            help="Include theme pages to the search",
            action='store_true')
        parser.add_argument(
            '--exact',
            help=("Match the exact given pattern, instead of any page "
                  "containing the pattern"),
            action='store_true')

    def run(self, ctx):
        import fnmatch
        from piecrust.sources.fs import FSContentSourceBase

        pattern = ctx.args.pattern
        sources = list(ctx.app.sources)
        if not ctx.args.exact and pattern is not None:
            pattern = '*%s*' % pattern

        for src in sources:
            if not ctx.args.include_theme and src.is_theme_source:
                continue
            if ctx.args.name and not fnmatch.fnmatch(src.name, ctx.args.name):
                continue

            is_fs_src = isinstance(src, FSContentSourceBase)
            items = src.getAllContents()
            for item in items:
                if ctx.args.metadata:
                    logger.info("spec:%s" % item.spec)
                    for key, val in item.metadata.items():
                        logger.info("%s:%s" % (key, val))
                    logger.info("---")
                else:
                    if is_fs_src:
                        name = os.path.relpath(item.spec, ctx.app.root_dir)
                        if pattern is None or fnmatch.fnmatch(name, pattern):
                            if ctx.args.metadata:
                                logger.info("path:%s" % item.spec)
                                for key, val in item.metadata.items():
                                    logger.info("%s:%s" % (key, val))
                                logger.info("---")
                            else:
                                if ctx.args.full_path:
                                    name = item.spec
                                logger.info(name)
                    else:
                        if pattern is None or fnmatch.fnmatch(name, pattern):
                            logger.info(item.spec)