diff options
| -rw-r--r-- | pyramid/paster.py | 93 |
1 files changed, 89 insertions, 4 deletions
diff --git a/pyramid/paster.py b/pyramid/paster.py index f670ae618..9683da043 100644 --- a/pyramid/paster.py +++ b/pyramid/paster.py @@ -1,13 +1,16 @@ import os +import re import sys from code import interact import zope.deprecation from paste.deploy import loadapp +from paste.script.command import BadCommand from paste.script.command import Command from pyramid.scripting import get_root +from pyramid.util import DottedNameResolver from pyramid.scaffolds import PyramidTemplate # bw compat zope.deprecation.deprecated( @@ -79,6 +82,45 @@ class PShellCommand(PCommand): dest='disable_ipython', help="Don't use IPython even if it is available") + _pshell_section_re = re.compile(r'^\s*\[\s*pshell\s*\]\s*$') + _section_re = re.compile(r'^\s*\[') + + def pshell_file_config(self, filename): + vars = { + 'here': os.path.dirname(filename), + '__file__': filename, + } + f = open(filename) + lines = f.readlines() + f.close() + lineno = 1 + # find the pshell section + while lines: + if self._pshell_section_re.search(lines[0]): + lines.pop(0) + break + lines.pop(0) + lineno += 1 + # parse pshell section for key/value pairs + resolver = DottedNameResolver(None) + self.loaded_objects = {} + self.object_help = {} + for line in lines: + lineno += 1 + line = line.strip() + if not line or line.startswith('#'): + continue + if self._section_re.search(line): + break + if '=' not in line: + raise BadCommand('Missing = in %s at %s: %r' + % (filename, lineno, line)) + name, value = line.split('=', 1) + name = name.strip() + value = value.strip() % vars + self.loaded_objects[name] = resolver.maybe_resolve(value) + self.object_help[name] = value + def command(self, IPShell=_marker): # IPShell passed to command method is for testing purposes if IPShell is _marker: # pragma: no cover @@ -86,15 +128,58 @@ class PShellCommand(PCommand): from IPython.Shell import IPShell except ImportError: IPShell = None - cprt =('Type "help" for more information. "root" is the Pyramid app ' - 'root object, "registry" is the Pyramid registry object.') + cprt =('Type "help" for more information.') banner = "Python %s on %s\n%s" % (sys.version, sys.platform, cprt) app_spec = self.args[0] config_file = app_spec.split('#', 1)[0] self.logging_file_config(config_file) app = self.get_app(app_spec, loadapp=self.loadapp[0]) - root, closer = self.get_root(app) - shell_globals = {'root':root, 'registry':app.registry} + + # load default globals + shell_globals = { + 'app': app, + } + default_variables = {'app': 'The WSGI Application'} + if hasattr(app, 'registry'): + root, closer = self.get_root(app) + shell_globals.update({'root':root, 'registry':app.registry}) + default_variables.update({ + 'root': 'The root of the default resource tree.', + 'registry': 'The Pyramid registry object.', + 'settings': 'The Pyramid settings object.', + }) + warning = '' + else: + # warn the user that this isn't actually the Pyramid app + warning = """\n +WARNING: You have loaded a generic WSGI application, therefore the +"root" and "registry" are not available. To correct this, run "pshell" +again and specify the INI section containing your Pyramid application.""" + closer = lambda: None + + # load the pshell section of the ini file + self.pshell_file_config(config_file) + shell_globals.update(self.loaded_objects) + + # eliminate duplicates from default_variables + for k in self.loaded_objects: + if k in default_variables: + del default_variables[k] + + # append the loaded variables + if default_variables: + banner += '\n\nDefault Variables:' + for var, txt in default_variables.iteritems(): + banner += '\n %-12s %s' % (var, txt) + + if self.object_help: + banner += '\n\nCustom Variables:' + for var in sorted(self.object_help.keys()): + banner += '\n %-12s %s' % (var, self.object_help[var]) + + # append the warning + banner += warning + banner += '\n' if (IPShell is None) or self.options.disable_ipython: try: |
