~azzar1/unity/add-show-desktop-key

« back to all changes in this revision

Viewing changes to ivle/dispatch/__init__.py

  • Committer: me at id
  • Date: 2009-01-15 05:53:45 UTC
  • mto: This revision was merged to the branch mainline in revision 1090.
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:branches%2Fstorm:1161
bin/ivle-showenrolment: Switch to ivle.database.User.enrolments from
    ivle.db.get_enrolment, removing the dependency on ivle.db.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# IVLE - Informatics Virtual Learning Environment
2
 
# Copyright (C) 2007-2009 The University of Melbourne
 
1
# IVLE
 
2
# Copyright (C) 2007-2008 The University of Melbourne
3
3
#
4
4
# This program is free software; you can redistribute it and/or modify
5
5
# it under the terms of the GNU General Public License as published by
15
15
# along with this program; if not, write to the Free Software
16
16
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
17
 
18
 
# Author: Matt Giuca, Will Grant
19
 
 
20
 
"""
21
 
This is a mod_python handler program. The correct way to call it is to have
22
 
Apache send all requests to be handled by the module 'dispatch'.
23
 
 
24
 
Top-level handler. Handles all requests to all pages in IVLE.
25
 
Handles authentication (not authorization).
26
 
Then passes the request along to the appropriate ivle app.
27
 
"""
 
18
# Module: dispatch
 
19
# Author: Matt Giuca
 
20
# Date: 11/12/2007
 
21
 
 
22
# This is a mod_python handler program. The correct way to call it is to have
 
23
# Apache send all requests to be handled by the module 'dispatch'.
 
24
 
 
25
# Top-level handler. Handles all requests to all pages in IVLE.
 
26
# Handles authentication (not authorization).
 
27
# Then passes the request along to the appropriate ivle app.
28
28
 
29
29
import sys
30
30
import os
35
35
import logging
36
36
import socket
37
37
import time
38
 
import inspect
39
38
 
40
39
import mod_python
41
 
import routes
 
40
from mod_python import apache, Cookie
42
41
 
43
42
from ivle import util
44
43
import ivle.conf
45
44
import ivle.conf.apps
46
 
from ivle.dispatch.request import Request
47
 
from ivle.dispatch import login
48
 
from ivle.webapp.base.plugins import ViewPlugin
49
45
import apps
 
46
import login
50
47
import html
 
48
from request import Request
51
49
import plugins.console # XXX: Relies on www/ being in the Python path.
52
50
 
53
 
# XXX List of plugins, which will eventually be read in from conf
54
 
plugins_HACK = [
55
 
    'ivle.webapp.core#Plugin',
56
 
    'ivle.webapp.admin.user#Plugin',
57
 
    'ivle.webapp.tutorial#Plugin',
58
 
    'ivle.webapp.admin.subject#Plugin',
59
 
    'ivle.webapp.filesystem.browser#Plugin',
60
 
    'ivle.webapp.filesystem.diff#Plugin',
61
 
    'ivle.webapp.filesystem.svnlog#Plugin',
62
 
    'ivle.webapp.groups#Plugin',
63
 
    'ivle.webapp.console#Plugin',
64
 
    'ivle.webapp.security#Plugin',
65
 
    'ivle.webapp.media#Plugin',
66
 
67
 
 
68
 
def generate_route_mapper(view_plugins):
69
 
    """
70
 
    Build a Mapper object for doing URL matching using 'routes', based on the
71
 
    given plugin registry.
72
 
    """
73
 
    m = routes.Mapper(explicit=True)
74
 
    for plugin in view_plugins:
75
 
        # Establish a URL pattern for each element of plugin.urls
76
 
        assert hasattr(plugin, 'urls'), "%r does not have any urls" % plugin 
77
 
        for url in plugin.urls:
78
 
            routex = url[0]
79
 
            view_class = url[1]
80
 
            kwargs_dict = url[2] if len(url) >= 3 else {}
81
 
            m.connect(routex, view=view_class, **kwargs_dict)
82
 
    return m
83
 
 
84
 
def get_plugin(pluginstr):
85
 
    plugin_path, classname = pluginstr.split('#')
86
 
    # Load the plugin module from somewhere in the Python path
87
 
    # (Note that plugin_path is a fully-qualified Python module name).
88
 
    return (plugin_path,
89
 
            getattr(__import__(plugin_path, fromlist=[classname]), classname))
 
51
# List of cookies that IVLE uses (to be removed at logout)
 
52
ivle_cookies = ["ivleforumcookie", "clipboard"]
90
53
 
91
54
def handler(req):
92
55
    """Handles a request which may be to anywhere in the site except media.
103
66
        # yet.
104
67
        handle_unknown_exception(apachereq, *sys.exc_info())
105
68
        # Tell Apache not to generate its own errors as well
106
 
        return mod_python.apache.OK
 
69
        return apache.OK
107
70
 
108
71
    # Run the main handler, and catch all exceptions
109
72
    try:
115
78
    except Exception:
116
79
        handle_unknown_exception(req, *sys.exc_info())
117
80
        # Tell Apache not to generate its own errors as well
118
 
        return mod_python.apache.OK
 
81
        return apache.OK
119
82
 
120
83
def handler_(req, apachereq):
121
84
    """
128
91
    if not req.publicmode:
129
92
        req.user = login.get_user_details(req)
130
93
 
131
 
    ### BEGIN New plugins framework ###
132
 
    # XXX This should be done ONCE per Python process, not per request.
133
 
    # (Wait till WSGI)
134
 
    # XXX No authentication is done here
135
 
    req.plugins = dict([get_plugin(pluginstr) for pluginstr in plugins_HACK])
136
 
    # Index the plugins by base class
137
 
    req.plugin_index = {}
138
 
    for plugin in req.plugins.values():
139
 
        # Getmro returns a tuple of all the super-classes of the plugin
140
 
        for base in inspect.getmro(plugin):
141
 
            if base not in req.plugin_index:
142
 
                req.plugin_index[base] = []
143
 
            req.plugin_index[base].append(plugin)
144
 
    req.reverse_plugins = dict([(v, k) for (k, v) in req.plugins.items()])
145
 
    req.mapper = generate_route_mapper(req.plugin_index[ViewPlugin])
146
 
 
147
 
    matchdict = req.mapper.match(req.uri)
148
 
    if matchdict is not None:
149
 
        viewcls = matchdict['view']
150
 
        # Get the remaining arguments, less 'view', 'action' and 'controller'
151
 
        # (The latter two seem to be built-in, and we don't want them).
152
 
        kwargs = matchdict.copy()
153
 
        del kwargs['view']
154
 
        # Instantiate the view, which should be a BaseView class
155
 
        view = viewcls(req, **kwargs)
156
 
        # Render the output
157
 
        view.render(req)
158
 
        req.store.commit()
159
 
        return req.OK
160
 
    ### END New plugins framework ###
161
 
 
162
94
    # Check req.app to see if it is valid. 404 if not.
163
95
    if req.app is not None and req.app not in ivle.conf.apps.app_url:
164
 
        req.throw_error(Request.HTTP_NOT_FOUND,
165
 
            "There is no application called %s." % repr(req.app))
 
96
        # Maybe it is a special app!
 
97
        if req.app == 'logout':
 
98
            logout(req)
 
99
        else:
 
100
            req.throw_error(Request.HTTP_NOT_FOUND,
 
101
                "There is no application called %s." % repr(req.app))
166
102
 
167
103
    # Special handling for public mode - only allow the public app, call it
168
104
    # and get out.
234
170
    # Use req.throw_error to do that.
235
171
    return req.OK
236
172
 
 
173
def logout(req):
 
174
    """Log out the current user (if any) by destroying the session state.
 
175
    Then redirect to the top-level IVLE page."""
 
176
    session = req.get_session()
 
177
    session.invalidate()
 
178
    session.delete()
 
179
    # Invalidates all IVLE cookies
 
180
    all_cookies = Cookie.get_cookies(req)
 
181
    for cookie in all_cookies:
 
182
        if cookie in ivle_cookies:
 
183
            req.add_cookie(Cookie.Cookie(cookie,'',expires=1,path='/'))
 
184
    req.throw_redirect(util.make_path('')) 
 
185
 
237
186
def handle_unknown_exception(req, exc_type, exc_value, exc_traceback):
238
187
    """
239
188
    Given an exception that has just been thrown from IVLE, print its details
251
200
    # For some reason, some versions of mod_python have "_server" instead of
252
201
    # "main_server". So we check for both.
253
202
    try:
254
 
        admin_email = mod_python.apache.main_server.server_admin
 
203
        admin_email = apache.main_server.server_admin
255
204
    except AttributeError:
256
205
        try:
257
 
            admin_email = mod_python.apache._server.server_admin
 
206
            admin_email = apache._server.server_admin
258
207
        except AttributeError:
259
208
            admin_email = ""
260
209
    try:
262
211
        req.status = httpcode
263
212
    except AttributeError:
264
213
        httpcode = None
265
 
        req.status = mod_python.apache.HTTP_INTERNAL_SERVER_ERROR
266
 
    try:
267
 
        publicmode = req.publicmode
268
 
    except AttributeError:
269
 
        publicmode = True
 
214
        req.status = apache.HTTP_INTERNAL_SERVER_ERROR
270
215
    try:
271
216
        login = req.user.login
272
217
    except AttributeError:
273
218
        login = None
274
 
    try:
275
 
        role = req.user.role
276
 
    except AttributeError:
277
 
        role = None
278
219
 
279
220
    # Log File
280
221
    try:
370
311
 
371
312
        # Logging
372
313
        logging.error('%s\n%s'%(str(msg), tb))
373
 
        # Error messages are only displayed is the user is NOT a student,
374
 
        # or if there has been a problem logging the error message
375
 
        show_errors = (not publicmode) and ((login and \
376
 
                            str(role) != "student") or logfail)
 
314
 
377
315
        req.write("""<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"                 
378
316
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">                                      
379
317
<html xmlns="http://www.w3.org/1999/xhtml">
380
318
<head><title>IVLE Internal Server Error</title></head>
381
319
<body>
382
320
<h1>IVLE Internal Server Error""")
383
 
        if (show_errors):
384
 
            if (codename is not None
385
 
                        and httpcode != mod_python.apache.HTTP_INTERNAL_SERVER_ERROR):
386
 
                req.write(": %s" % cgi.escape(codename))
387
 
        
 
321
        if (codename is not None
 
322
            and httpcode != apache.HTTP_INTERNAL_SERVER_ERROR):
 
323
            req.write(": %s" % cgi.escape(codename))
388
324
        req.write("""</h1>
389
325
<p>An error has occured which is the fault of the IVLE developers or
390
 
administration. The developers have been notified.</p>
 
326
administration.</p>
391
327
""")
392
 
        if (show_errors):
393
 
            if msg is not None:
394
 
                req.write("<p>%s</p>\n" % cgi.escape(msg))
395
 
            if httpcode is not None:
396
 
                req.write("<p>(HTTP error code %d)</p>\n" % httpcode)
397
 
            req.write("""
398
 
    <p>Please report this to <a href="mailto:%s">%s</a> (the system
399
 
    administrator). Include the following information:</p>
400
 
    """ % (cgi.escape(admin_email), cgi.escape(admin_email)))
 
328
        if msg is not None:
 
329
            req.write("<p>%s</p>\n" % cgi.escape(msg))
 
330
        if httpcode is not None:
 
331
            req.write("<p>(HTTP error code %d)</p>\n" % httpcode)
 
332
        req.write("""
 
333
<p>Please report this to <a href="mailto:%s">%s</a> (the system
 
334
administrator). Include the following information:</p>
 
335
""" % (cgi.escape(admin_email), cgi.escape(admin_email)))
401
336
 
402
 
            req.write("<pre>\n%s\n</pre>\n"%cgi.escape(tb))
403
 
            if logfail:
404
 
                req.write("<p>Warning: Could not open Error Log: '%s'</p>\n"
405
 
                    %cgi.escape(logfile))
 
337
        req.write("<pre>\n%s\n</pre>\n"%cgi.escape(tb))
 
338
        if logfail:
 
339
            req.write("<p>Warning: Could not open Error Log: '%s'</p>\n"
 
340
                %cgi.escape(logfile))
406
341
        req.write("</body></html>")