Mercurial > piecrust2
diff piecrust/main.py @ 3:f485ba500df3
Gigantic change to basically make PieCrust 2 vaguely functional.
- Serving works, with debug window.
- Baking works, multi-threading, with dependency handling.
- Various things not implemented yet.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Sun, 10 Aug 2014 23:43:16 -0700 |
parents | |
children | 343d08ef5668 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/piecrust/main.py Sun Aug 10 23:43:16 2014 -0700 @@ -0,0 +1,152 @@ +import sys +import time +import os.path +import logging +import argparse +import colorama +from piecrust.app import PieCrust, PieCrustConfiguration, APP_VERSION +from piecrust.chefutil import format_timed +from piecrust.environment import StandardEnvironment +from piecrust.pathutil import SiteNotFoundError, find_app_root +from piecrust.plugins.base import PluginLoader + + +logger = logging.getLogger(__name__) + + +class ColoredFormatter(logging.Formatter): + COLORS = { + 'DEBUG': colorama.Fore.BLACK + colorama.Style.BRIGHT, + 'INFO': '', + 'WARNING': colorama.Fore.YELLOW, + 'ERROR': colorama.Fore.RED, + 'CRITICAL': colorama.Back.RED + colorama.Fore.WHITE + } + + def __init__(self, fmt=None, datefmt=None): + super(ColoredFormatter, self).__init__(fmt, datefmt) + + def format(self, record): + color = self.COLORS.get(record.levelname) + res = super(ColoredFormatter, self).format(record) + if color: + res = color + res + colorama.Style.RESET_ALL + return res + + +class NullPieCrust: + def __init__(self): + self.root_dir = None + self.debug = False + self.templates_dirs = [] + self.plugins_dirs = [] + self.theme_dir = None + self.cache_dir = None + self.config = PieCrustConfiguration() + self.plugin_loader = PluginLoader(self) + self.env = StandardEnvironment() + self.env.initialize(self) + + +def main(): + start_time = time.clock() + + # We need to parse some arguments before we can build the actual argument + # parser, because it can affect which plugins will be loaded. Also, log- + # related arguments must be parsed first because we want to log everything + # from the beginning. + root = None + cache = True + debug = False + quiet = False + log_file = None + config_variant = None + i = 1 + while i < len(sys.argv): + arg = sys.argv[i] + if arg.startswith('--root='): + root = os.path.expanduser(arg[len('--root='):]) + elif arg == '--root': + root = sys.argv[i + 1] + ++i + elif arg.startswith('--config='): + config_variant = arg[len('--config='):] + elif arg == '--config': + config_variant = sys.argv[i + 1] + ++i + elif arg == '--log': + log_file = sys.argv[i + 1] + ++i + elif arg == '--no-cache': + cache = False + elif arg == '--debug': + debug = True + elif arg == '--quiet': + quiet = True + + if arg[0] != '-': + break + + i = i + 1 + + # Setup the logger. + if debug and quiet: + raise Exception("You can't specify both --debug and --quiet.") + + colorama.init() + root_logger = logging.getLogger() + root_logger.setLevel(logging.INFO) + log_handler = logging.StreamHandler(sys.stdout) + if debug: + root_logger.setLevel(logging.DEBUG) + log_handler.setFormatter(ColoredFormatter("[%(name)s] %(message)s")) + else: + if quiet: + root_logger.setLevel(logging.WARNING) + log_handler.setFormatter(ColoredFormatter("%(message)s")) + root_logger.addHandler(log_handler) + if log_file: + root_logger.addHandler(logging.FileHandler(log_file)) + + # Setup the app. + if root is None: + root = find_app_root() + + if not root: + app = NullPieCrust() + else: + app = PieCrust(root, cache=cache) + + # Handle a configuration variant. + if config_variant is not None: + if not root: + raise SiteNotFoundError() + app.config.applyVariant('variants/' + config_variant) + + # Setup the arg parser. + parser = argparse.ArgumentParser( + description="The PieCrust chef manages your website.") + parser.add_argument('--version', action='version', version=('%(prog)s ' + APP_VERSION)) + parser.add_argument('--root', help="The root directory of the website.") + parser.add_argument('--config', help="The configuration variant to use for this command.") + parser.add_argument('--debug', help="Show debug information.", action='store_true') + parser.add_argument('--no-cache', help="When applicable, disable caching.", action='store_true') + parser.add_argument('--quiet', help="Print only important information.", action='store_true') + parser.add_argument('--log', help="Send log messages to the specified file.") + + commands = sorted(app.plugin_loader.getCommands(), + lambda a, b: cmp(a.name, b.name)) + subparsers = parser.add_subparsers() + for c in commands: + p = subparsers.add_parser(c.name, help=c.description) + c.setupParser(p, app) + p.set_defaults(func=c._runFromChef) + + # Parse the command line. + result = parser.parse_args() + logger.debug(format_timed(start_time, 'initialized PieCrust')) + + # Run the command! + exit_code = result.func(app, result) + return exit_code +