1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
import os
import sys
from code import interact
from paste.deploy import loadapp
from paste.script.command import Command
from paste.script.templates import Template
from paste.util.template import paste_script_template_renderer
from repoze.bfg.scripting import get_root
class StarterProjectTemplate(Template):
_template_dir = 'paster_templates/starter'
summary = 'repoze.bfg starter project'
template_renderer = staticmethod(paste_script_template_renderer)
class ZODBProjectTemplate(Template):
_template_dir = 'paster_templates/zodb'
summary = 'repoze.bfg ZODB starter project'
template_renderer = staticmethod(paste_script_template_renderer)
class RoutesAlchemyProjectTemplate(Template):
_template_dir = 'paster_templates/routesalchemy'
summary = 'repoze.bfg SQLAlchemy project using Routes (no traversal)'
template_renderer = staticmethod(paste_script_template_renderer)
class AlchemyProjectTemplate(Template):
_template_dir = 'paster_templates/alchemy'
summary = 'repoze.bfg SQLAlchemy project using traversal'
template_renderer = staticmethod(paste_script_template_renderer)
def get_app(config_file, name, loadapp=loadapp):
""" Return the WSGI application named ``name`` in the PasteDeploy
config file ``config_file``"""
config_name = 'config:%s' % config_file
here_dir = os.getcwd()
app = loadapp(config_name, name=name, relative_to=here_dir)
return app
_marker = object()
class BFGShellCommand(Command):
"""Open an interactive shell with a :mod:`repoze.bfg` app loaded.
This command accepts two positional arguments:
``config_file`` -- specifies the PasteDeploy config file to use
for the interactive shell.
``section_name`` -- specifies the section name in the PasteDeploy
config file that represents the application.
Example::
$ paster bfgshell myapp.ini main
.. note:: You should use a ``section_name`` that refers to the
actual ``app`` section in the config file that points at
your BFG app without any middleware wrapping, or this
command will almost certainly fail.
"""
summary = "Open an interactive shell with a repoze.bfg app loaded"
min_args = 2
max_args = 2
group_name = 'bfg'
parser = Command.standard_parser(simulate=True)
parser.add_option('-d', '--disable-ipython',
action='store_true',
dest='disable_ipython',
help="Don't use IPython even if it is available")
interact = (interact,) # for testing
loadapp = (loadapp,) # for testing
get_app = staticmethod(get_app) # hook point
get_root = staticmethod(get_root) # hook point
verbose = 3
def __init__(self, *arg, **kw):
# needs to be in constructor to support Jython (used to be at class
# scope as ``usage = '\n' + __doc__``.
self.usage = '\n' + self.__doc__
Command.__init__(self, *arg, **kw)
def command(self, IPShell=_marker):
if IPShell is _marker:
try: #pragma no cover
from IPython.Shell import IPShell
except ImportError: #pragma no cover
IPShell = None
cprt =('Type "help" for more information. "root" is the BFG app '
'root object.')
banner = "Python %s on %s\n%s" % (sys.version, sys.platform, cprt)
config_file, section_name = self.args
self.logging_file_config(config_file)
app = self.get_app(config_file, section_name, loadapp=self.loadapp[0])
root, closer = self.get_root(app)
if IPShell is not None and not self.options.disable_ipython:
try:
shell = IPShell(argv=[], user_ns={'root':root})
shell.IP.BANNER = shell.IP.BANNER + '\n\n' + banner
shell.mainloop()
finally:
closer()
else:
try:
self.interact[0](banner, local={'root':root})
finally:
closer()
|