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

« back to all changes in this revision

Viewing changes to www/dispatch/__init__.py

  • Committer: mattgiuca
  • Date: 2008-02-05 01:41:15 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:409
Moved www/conf and www/common to a new directory lib. This separates the "web"
part of IVLE from what is becoming less web oriented (at least from Apache's
standpoint).
Modified setup.py to install this lib directory correctly and write conf in
the right place. Also adds the lib directory to ivle.pth.

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
import mod_python
30
30
from mod_python import apache
31
31
 
32
 
import sys
33
32
import os
34
33
import os.path
35
 
import urllib
36
 
 
37
34
import conf
38
35
import conf.apps
39
 
import conf.conf
40
36
import apps
41
37
 
42
38
from request import Request
43
39
import html
44
 
import cgi
45
40
import login
46
 
from common import (util, forumutil)
47
 
import traceback
48
 
import plugins.console
49
 
import logging
50
 
import socket
 
41
from common import util
51
42
 
52
43
def handler(req):
53
44
    """Handles a request which may be to anywhere in the site except media.
57
48
    """
58
49
    # Make the request object into an IVLE request which can be passed to apps
59
50
    apachereq = req
60
 
    try:
61
 
        req = Request(req, html.write_html_head)
62
 
    except Exception:
63
 
        # Pass the apachereq to error reporter, since ivle req isn't created
64
 
        # yet.
65
 
        handle_unknown_exception(apachereq, *sys.exc_info())
66
 
        # Tell Apache not to generate its own errors as well
67
 
        return apache.OK
68
 
 
69
 
    # Run the main handler, and catch all exceptions
70
 
    try:
71
 
        return handler_(req, apachereq)
72
 
    except mod_python.apache.SERVER_RETURN:
73
 
        # An apache error. We discourage these, but they might still happen.
74
 
        # Just raise up.
75
 
        raise
76
 
    except Exception:
77
 
        handle_unknown_exception(req, *sys.exc_info())
78
 
        # Tell Apache not to generate its own errors as well
79
 
        return apache.OK
80
 
 
81
 
def handler_(req, apachereq):
82
 
    """
83
 
    Nested handler function. May raise exceptions. The top-level handler is
84
 
    just used to catch exceptions.
85
 
    Takes both an IVLE request and an Apache req.
86
 
    """
87
 
    # Hack? Try and get the user login early just in case we throw an error
88
 
    # (most likely 404) to stop us seeing not logged in even when we are.
89
 
    if not req.publicmode:
90
 
        req.user = login.get_user_details(req)
 
51
    req = Request(req, html.write_html_head)
91
52
 
92
53
    # Check req.app to see if it is valid. 404 if not.
93
54
    if req.app is not None and req.app not in conf.apps.app_url:
95
56
        if req.app == 'logout':
96
57
            logout(req)
97
58
        else:
98
 
            req.throw_error(Request.HTTP_NOT_FOUND,
99
 
                "There is no application called %s." % repr(req.app))
 
59
            # TODO: Nicer 404 message?
 
60
            req.throw_error(Request.HTTP_NOT_FOUND)
100
61
 
101
 
    # Special handling for public mode - only allow the public app, call it
102
 
    # and get out.
 
62
    # Special handling for public mode - just call public app and get out
103
63
    # NOTE: This will not behave correctly if the public app uses
104
64
    # write_html_head_foot, but "serve" does not.
105
65
    if req.publicmode:
106
 
        if req.app != conf.apps.public_app:
107
 
            req.throw_error(Request.HTTP_FORBIDDEN,
108
 
                "This application is not available on the public site.")
109
66
        app = conf.apps.app_url[conf.apps.public_app]
110
67
        apps.call_app(app.dir, req)
111
68
        return req.OK
117
74
        app = conf.apps.app_url[req.app]
118
75
 
119
76
    # Check if app requires auth. If so, perform authentication and login.
120
 
    # This will either return a User object, None, or perform a redirect
121
 
    # which we will not catch here.
122
77
    if app.requireauth:
123
 
        req.user = login.login(req)
124
 
        logged_in = req.user is not None
 
78
        req.username = login.login(req)
 
79
        logged_in = req.username is not None
125
80
    else:
126
 
        req.user = login.get_user_details(req)
 
81
        req.username = login.get_username(req)
127
82
        logged_in = True
128
83
 
129
84
    if logged_in:
130
85
        # Keep the user's session alive by writing to the session object.
131
 
        # req.get_session().save()
132
 
        # Well, it's a fine idea, but it creates considerable grief in the
133
 
        # concurrent update department, so instead, we'll just make the
134
 
        # sessions not time out.
135
 
        
 
86
        req.get_session().save()
136
87
        # If user did not specify an app, HTTP redirect to default app and
137
88
        # exit.
138
89
        if req.app is None:
147
98
 
148
99
        # Call the specified app with the request object
149
100
        apps.call_app(app.dir, req)
150
 
 
151
101
    # if not logged in, login.login will have written the login box.
152
102
    # Just clean up and exit.
153
103
 
158
108
 
159
109
    # When done, write out the HTML footer if the app has requested it
160
110
    if req.write_html_head_foot:
161
 
        # Show the console if required
162
 
        if logged_in and app.useconsole:
163
 
            plugins.console.present(req, windowpane=True)
164
111
        html.write_html_foot(req)
165
112
 
166
113
    # Note: Apache will not write custom HTML error messages here.
173
120
    session = req.get_session()
174
121
    session.invalidate()
175
122
    session.delete()
176
 
    req.add_cookie(forumutil.invalidated_forum_cookie())
177
123
    req.throw_redirect(util.make_path(''))
178
 
 
179
 
def handle_unknown_exception(req, exc_type, exc_value, exc_traceback):
180
 
    """
181
 
    Given an exception that has just been thrown from IVLE, print its details
182
 
    to the request.
183
 
    This is a full handler. It assumes nothing has been written, and writes a
184
 
    complete HTML page.
185
 
    req: May be EITHER an IVLE req or an Apache req.
186
 
    IVLE reqs may have the HTML head/foot written (on a 400 error), but
187
 
    the handler code may pass an apache req if an exception occurs before
188
 
    the IVLE request is created.
189
 
    """
190
 
    req.content_type = "text/html"
191
 
    logfile = os.path.join(conf.conf.log_path, 'ivle_error.log')
192
 
    logfail = False
193
 
    # For some reason, some versions of mod_python have "_server" instead of
194
 
    # "main_server". So we check for both.
195
 
    try:
196
 
        admin_email = apache.main_server.server_admin
197
 
    except AttributeError:
198
 
        try:
199
 
            admin_email = apache._server.server_admin
200
 
        except AttributeError:
201
 
            admin_email = ""
202
 
    try:
203
 
        httpcode = exc_value.httpcode
204
 
        req.status = httpcode
205
 
    except AttributeError:
206
 
        httpcode = None
207
 
        req.status = apache.HTTP_INTERNAL_SERVER_ERROR
208
 
    try:
209
 
        login = req.user.login
210
 
    except AttributeError:
211
 
        login = None
212
 
 
213
 
    # Log File
214
 
    try:
215
 
        logging.basicConfig(level=logging.INFO,
216
 
            format='%(asctime)s %(levelname)s: ' +
217
 
                '(HTTP: ' + str(req.status) +
218
 
                ', Ref: ' + str(login) + '@' +
219
 
                str(socket.gethostname()) + str(req.uri) +
220
 
                ') %(message)s',
221
 
            filename=logfile,
222
 
            filemode='a')
223
 
    except IOError:
224
 
        logfail = True
225
 
    logging.debug('Logging Unhandled Exception')
226
 
 
227
 
    # We handle 3 types of error.
228
 
    # IVLEErrors with 4xx response codes (client error).
229
 
    # IVLEErrors with 5xx response codes (handled server error).
230
 
    # Other exceptions (unhandled server error).
231
 
    # IVLEErrors should not have other response codes than 4xx or 5xx
232
 
    # (eg. throw_redirect should have been used for 3xx codes).
233
 
    # Therefore, that is treated as an unhandled error.
234
 
 
235
 
    if (exc_type == util.IVLEError and httpcode >= 400
236
 
        and httpcode <= 499):
237
 
        # IVLEErrors with 4xx response codes are client errors.
238
 
        # Therefore, these have a "nice" response (we even coat it in the IVLE
239
 
        # HTML wrappers).
240
 
        
241
 
        req.write_html_head_foot = True
242
 
        req.write('<div id="ivle_padding">\n')
243
 
        try:
244
 
            codename, msg = req.get_http_codename(httpcode)
245
 
        except AttributeError:
246
 
            codename, msg = None, None
247
 
        # Override the default message with the supplied one,
248
 
        # if available.
249
 
        if exc_value.message is not None:
250
 
            msg = exc_value.message
251
 
        if codename is not None:
252
 
            req.write("<h1>Error: %s</h1>\n" % cgi.escape(codename))
253
 
        else:
254
 
            req.write("<h1>Error</h1>\n")
255
 
        if msg is not None:
256
 
            req.write("<p>%s</p>\n" % cgi.escape(msg))
257
 
        else:
258
 
            req.write("<p>An unknown error occured.</p>\n")
259
 
        
260
 
        # Logging
261
 
        logging.info(str(msg))
262
 
        
263
 
        req.write("<p>(HTTP error code %d)</p>\n" % httpcode)
264
 
        if logfail:
265
 
            req.write("<p>Warning: Could not open Error Log: '%s'</p>\n"
266
 
                %cgi.escape(logfile))
267
 
        req.write('</div>\n')
268
 
    else:
269
 
        # A "bad" error message. We shouldn't get here unless IVLE
270
 
        # misbehaves (which is currently very easy, if things aren't set up
271
 
        # correctly).
272
 
        # Write the traceback.
273
 
        # If this is a non-4xx IVLEError, get the message and httpcode and
274
 
        # make the error message a bit nicer (but still include the
275
 
        # traceback).
276
 
        # We also need to special-case IVLEJailError, as we can get another
277
 
        # almost-exception out of it.
278
 
 
279
 
        codename, msg = None, None
280
 
 
281
 
        if exc_type is util.IVLEJailError:
282
 
            msg = exc_value.type_str + ": " + exc_value.message
283
 
            tb = 'Exception information extracted from IVLEJailError:\n'
284
 
            tb += urllib.unquote(exc_value.info)
285
 
        else:
286
 
            try:
287
 
                codename, msg = req.get_http_codename(httpcode)
288
 
            except AttributeError:
289
 
                pass
290
 
            # Override the default message with the supplied one,
291
 
            # if available.
292
 
            if hasattr(exc_value, 'message') and exc_value.message is not None:
293
 
                msg = exc_value.message
294
 
                # Prepend the exception type
295
 
                if exc_type != util.IVLEError:
296
 
                    msg = exc_type.__name__ + ": " + msg
297
 
 
298
 
            tb = ''.join(traceback.format_exception(exc_type, exc_value,
299
 
                                                    exc_traceback))
300
 
 
301
 
        # Logging
302
 
        logging.error('%s\n%s'%(str(msg), tb))
303
 
 
304
 
        req.write("""<html>
305
 
<head><title>IVLE Internal Server Error</title></head>
306
 
<body>
307
 
<h1>IVLE Internal Server Error""")
308
 
        if (codename is not None
309
 
            and httpcode != apache.HTTP_INTERNAL_SERVER_ERROR):
310
 
            req.write(": %s" % cgi.escape(codename))
311
 
        req.write("""</h1>
312
 
<p>An error has occured which is the fault of the IVLE developers or
313
 
administration.</p>
314
 
""")
315
 
        if msg is not None:
316
 
            req.write("<p>%s</p>\n" % cgi.escape(msg))
317
 
        if httpcode is not None:
318
 
            req.write("<p>(HTTP error code %d)</p>\n" % httpcode)
319
 
        req.write("""
320
 
<p>Please report this to <a href="mailto:%s">%s</a> (the system
321
 
administrator). Include the following information:</p>
322
 
""" % (cgi.escape(admin_email), cgi.escape(admin_email)))
323
 
 
324
 
        req.write("<pre>\n%s\n</pre>\n"%cgi.escape(tb))
325
 
        if logfail:
326
 
            req.write("<p>Warning: Could not open Error Log: '%s'</p>\n"
327
 
                %cgi.escape(logfile))
328
 
        req.write("</body>")