45
44
import ivle.conf.apps
46
45
from ivle.dispatch.request import Request
47
46
from ivle.dispatch import login
48
from ivle.webapp.base.plugins import ViewPlugin
49
from ivle.webapp.errors import HTTPError
49
import plugins.console # XXX: Relies on www/ being in the Python path.
53
51
# XXX List of plugins, which will eventually be read in from conf
55
'ivle.webapp.core#Plugin',
56
53
'ivle.webapp.admin.user#Plugin',
57
54
'ivle.webapp.tutorial#Plugin',
58
55
'ivle.webapp.admin.subject#Plugin',
59
'ivle.webapp.filesystem.browser#Plugin',
60
'ivle.webapp.filesystem.diff#Plugin',
61
'ivle.webapp.filesystem.svnlog#Plugin',
56
'ivle.webapp.browser#Plugin',
62
57
'ivle.webapp.groups#Plugin',
63
'ivle.webapp.console#Plugin',
64
'ivle.webapp.security#Plugin',
65
'ivle.webapp.media#Plugin',
66
'ivle.webapp.forum#Plugin',
69
def generate_route_mapper(view_plugins):
60
def get_routes_mapper():
71
62
Build a Mapper object for doing URL matching using 'routes', based on the
72
given plugin registry.
74
65
m = routes.Mapper(explicit=True)
75
for plugin in view_plugins:
66
for pluginstr in plugins_HACK:
67
plugin_path, classname = pluginstr.split('#')
68
# Load the plugin module from somewhere in the Python path
69
# (Note that plugin_path is a fully-qualified Python module name).
70
plugin = getattr(__import__(plugin_path, fromlist=[classname]),
76
72
# Establish a URL pattern for each element of plugin.urls
77
assert hasattr(plugin, 'urls'), "%r does not have any urls" % plugin
78
73
for url in plugin.urls:
80
75
view_class = url[1]
82
77
m.connect(routex, view=view_class, **kwargs_dict)
85
def get_plugin(pluginstr):
86
plugin_path, classname = pluginstr.split('#')
87
# Load the plugin module from somewhere in the Python path
88
# (Note that plugin_path is a fully-qualified Python module name).
90
getattr(__import__(plugin_path, fromlist=[classname]), classname))
93
81
"""Handles a request which may be to anywhere in the site except media.
94
82
Intended to be called by mod_python, as a handler.
133
121
# XXX This should be done ONCE per Python process, not per request.
134
122
# (Wait till WSGI)
135
123
# XXX No authentication is done here
136
req.plugins = dict([get_plugin(pluginstr) for pluginstr in plugins_HACK])
137
# Index the plugins by base class
138
req.plugin_index = {}
139
for plugin in req.plugins.values():
140
# Getmro returns a tuple of all the super-classes of the plugin
141
for base in inspect.getmro(plugin):
142
if base not in req.plugin_index:
143
req.plugin_index[base] = []
144
req.plugin_index[base].append(plugin)
145
req.reverse_plugins = dict([(v, k) for (k, v) in req.plugins.items()])
146
req.mapper = generate_route_mapper(req.plugin_index[ViewPlugin])
124
req.mapper = get_routes_mapper()
148
125
matchdict = req.mapper.match(req.uri)
149
126
if matchdict is not None:
150
127
viewcls = matchdict['view']
152
129
# (The latter two seem to be built-in, and we don't want them).
153
130
kwargs = matchdict.copy()
154
131
del kwargs['view']
156
# Instantiate the view, which should be a BaseView class
157
view = viewcls(req, **kwargs)
161
# A view explicitly raised an HTTP error. Respect it.
164
# Try to find a custom error view.
165
if hasattr(viewcls, 'get_error_view'):
166
errviewcls = viewcls.get_error_view(e)
171
errview = errviewcls(req, e)
178
# A non-HTTPError appeared. We have an unknown exception. Panic.
179
handle_unknown_exception(req, *sys.exc_info())
132
# Instantiate the view, which should be a BaseView class
133
view = viewcls(req, **kwargs)
184
138
### END New plugins framework ###
186
140
# Check req.app to see if it is valid. 404 if not.
250
204
# When done, write out the HTML footer if the app has requested it
251
205
if req.write_html_head_foot:
206
# Show the console if required
207
if logged_in and app.useconsole:
208
plugins.console.present(req, windowpane=True)
252
209
html.write_html_foot(req)
254
211
# Note: Apache will not write custom HTML error messages here.