comparison 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
comparison
equal deleted inserted replaced
2:40fa08b261b9 3:f485ba500df3
1 import sys
2 import time
3 import os.path
4 import logging
5 import argparse
6 import colorama
7 from piecrust.app import PieCrust, PieCrustConfiguration, APP_VERSION
8 from piecrust.chefutil import format_timed
9 from piecrust.environment import StandardEnvironment
10 from piecrust.pathutil import SiteNotFoundError, find_app_root
11 from piecrust.plugins.base import PluginLoader
12
13
14 logger = logging.getLogger(__name__)
15
16
17 class ColoredFormatter(logging.Formatter):
18 COLORS = {
19 'DEBUG': colorama.Fore.BLACK + colorama.Style.BRIGHT,
20 'INFO': '',
21 'WARNING': colorama.Fore.YELLOW,
22 'ERROR': colorama.Fore.RED,
23 'CRITICAL': colorama.Back.RED + colorama.Fore.WHITE
24 }
25
26 def __init__(self, fmt=None, datefmt=None):
27 super(ColoredFormatter, self).__init__(fmt, datefmt)
28
29 def format(self, record):
30 color = self.COLORS.get(record.levelname)
31 res = super(ColoredFormatter, self).format(record)
32 if color:
33 res = color + res + colorama.Style.RESET_ALL
34 return res
35
36
37 class NullPieCrust:
38 def __init__(self):
39 self.root_dir = None
40 self.debug = False
41 self.templates_dirs = []
42 self.plugins_dirs = []
43 self.theme_dir = None
44 self.cache_dir = None
45 self.config = PieCrustConfiguration()
46 self.plugin_loader = PluginLoader(self)
47 self.env = StandardEnvironment()
48 self.env.initialize(self)
49
50
51 def main():
52 start_time = time.clock()
53
54 # We need to parse some arguments before we can build the actual argument
55 # parser, because it can affect which plugins will be loaded. Also, log-
56 # related arguments must be parsed first because we want to log everything
57 # from the beginning.
58 root = None
59 cache = True
60 debug = False
61 quiet = False
62 log_file = None
63 config_variant = None
64 i = 1
65 while i < len(sys.argv):
66 arg = sys.argv[i]
67 if arg.startswith('--root='):
68 root = os.path.expanduser(arg[len('--root='):])
69 elif arg == '--root':
70 root = sys.argv[i + 1]
71 ++i
72 elif arg.startswith('--config='):
73 config_variant = arg[len('--config='):]
74 elif arg == '--config':
75 config_variant = sys.argv[i + 1]
76 ++i
77 elif arg == '--log':
78 log_file = sys.argv[i + 1]
79 ++i
80 elif arg == '--no-cache':
81 cache = False
82 elif arg == '--debug':
83 debug = True
84 elif arg == '--quiet':
85 quiet = True
86
87 if arg[0] != '-':
88 break
89
90 i = i + 1
91
92 # Setup the logger.
93 if debug and quiet:
94 raise Exception("You can't specify both --debug and --quiet.")
95
96 colorama.init()
97 root_logger = logging.getLogger()
98 root_logger.setLevel(logging.INFO)
99 log_handler = logging.StreamHandler(sys.stdout)
100 if debug:
101 root_logger.setLevel(logging.DEBUG)
102 log_handler.setFormatter(ColoredFormatter("[%(name)s] %(message)s"))
103 else:
104 if quiet:
105 root_logger.setLevel(logging.WARNING)
106 log_handler.setFormatter(ColoredFormatter("%(message)s"))
107 root_logger.addHandler(log_handler)
108 if log_file:
109 root_logger.addHandler(logging.FileHandler(log_file))
110
111 # Setup the app.
112 if root is None:
113 root = find_app_root()
114
115 if not root:
116 app = NullPieCrust()
117 else:
118 app = PieCrust(root, cache=cache)
119
120 # Handle a configuration variant.
121 if config_variant is not None:
122 if not root:
123 raise SiteNotFoundError()
124 app.config.applyVariant('variants/' + config_variant)
125
126 # Setup the arg parser.
127 parser = argparse.ArgumentParser(
128 description="The PieCrust chef manages your website.")
129 parser.add_argument('--version', action='version', version=('%(prog)s ' + APP_VERSION))
130 parser.add_argument('--root', help="The root directory of the website.")
131 parser.add_argument('--config', help="The configuration variant to use for this command.")
132 parser.add_argument('--debug', help="Show debug information.", action='store_true')
133 parser.add_argument('--no-cache', help="When applicable, disable caching.", action='store_true')
134 parser.add_argument('--quiet', help="Print only important information.", action='store_true')
135 parser.add_argument('--log', help="Send log messages to the specified file.")
136
137 commands = sorted(app.plugin_loader.getCommands(),
138 lambda a, b: cmp(a.name, b.name))
139 subparsers = parser.add_subparsers()
140 for c in commands:
141 p = subparsers.add_parser(c.name, help=c.description)
142 c.setupParser(p, app)
143 p.set_defaults(func=c._runFromChef)
144
145 # Parse the command line.
146 result = parser.parse_args()
147 logger.debug(format_timed(start_time, 'initialized PieCrust'))
148
149 # Run the command!
150 exit_code = result.func(app, result)
151 return exit_code
152