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

« back to all changes in this revision

Viewing changes to www/dispatch/request.py

  • Committer: mattgiuca
  • Date: 2008-08-18 12:15:25 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:1027
Tutorial: Added new feature - previous attempt viewing. Allows users to see
    code they have previously submitted to tutorials.
    A new button ("View previous attempts") appears on each exercise box.
    This uses the getattempts and getattempt Ajax services checked in
    previously.
Note once again: Students are not (for the moment) able to see deactivated
attempts (this is a conservative approach - the ability to see deactivated
attempts can be turned on by setting HISTORY_ALLOW_INACTIVE = True in
tutorialservice).

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
 
26
26
import common.util
27
27
import mod_python
28
 
from mod_python import (util, Session)
 
28
from mod_python import (util, Session, Cookie)
 
29
import conf
 
30
import plugins.console
29
31
 
30
32
class Request:
31
33
    """An IVLE request object. This is presented to the IVLE apps as a way of
42
44
            String. The path specified in the URL *not including* the
43
45
            application or the IVLE location prefix. eg. a URL of
44
46
            "/ivle/files/joe/myfiles" has a path of "joe/myfiles".
45
 
        username (read)
46
 
            String. Login name of the user who is currently logged in, or
 
47
        user (read)
 
48
            User object. Details of the user who is currently logged in, or
47
49
            None.
 
50
        hostname (read)
 
51
            String. Hostname the server is running on.
48
52
        headers_in (read)
49
53
            Table object representing headers sent by the client.
50
54
        headers_out (read, can be written to)
51
55
            Table object representing headers to be sent to the client.
 
56
        publicmode (read)
 
57
            Bool. True if the request came for the "public host" as
 
58
            configured in conf.py. Note that public mode requests do not
 
59
            have an app (app is set to None).
52
60
 
53
61
        status (write)
54
62
            Int. Response status number. Use one of the status codes defined
73
81
            in the head, if write_html_head_foot is True.
74
82
            URLs should be relative to the IVLE root; they will be fixed up
75
83
            to be site-relative.
 
84
        scripts_init (write)
 
85
            List of strings. Write a list of JS function names, and they
 
86
            will be added as window.addListener('load', ..., false); calls
 
87
            in the head, if write_html_head_foot is True.
 
88
            This is the propper way to specify functions that need to run at 
 
89
            page load time.
76
90
        write_html_head_foot (write)
77
91
            Boolean. If True, dispatch assumes that this is an XHTML page, and
78
92
            will immediately write a full HTML head, open the body element,
158
172
        self.func_write_html_head = write_html_head
159
173
        self.headers_written = False
160
174
 
 
175
        # Determine if the browser used the public host name to make the
 
176
        # request (in which case we are in "public mode")
 
177
        if req.hostname == conf.public_host:
 
178
            self.publicmode = True
 
179
        else:
 
180
            self.publicmode = False
 
181
 
161
182
        # Inherit values for the input members
162
183
        self.method = req.method
163
184
        self.uri = req.uri
164
185
        # Split the given path into the app (top-level dir) and sub-path
165
186
        # (after first stripping away the root directory)
166
 
        (self.app, self.path) = (
167
 
            common.util.split_path(common.util.unmake_path(req.uri)))
168
 
        self.username = None
 
187
        path = common.util.unmake_path(req.uri)
 
188
        (self.app, self.path) = (common.util.split_path(path))
 
189
        self.user = None
 
190
        self.hostname = req.hostname
169
191
        self.headers_in = req.headers_in
170
192
        self.headers_out = req.headers_out
171
193
 
176
198
        self.title = None     # Will be set by dispatch before passing to app
177
199
        self.styles = []
178
200
        self.scripts = []
 
201
        self.scripts_init = []
179
202
        self.write_html_head_foot = False
 
203
        self.got_common_vars = False
180
204
 
181
205
    def __writeheaders(self):
182
206
        """Writes out the HTTP and HTML headers before any real data is
183
207
        written."""
184
208
        self.headers_written = True
 
209
        
 
210
        # app is the App object for the chosen app
 
211
        try:
 
212
            app = conf.apps.app_url[self.app]
 
213
        except KeyError:
 
214
            app = None
 
215
 
 
216
        # Write any final modifications to header content
 
217
        if app and app.useconsole and self.user:
 
218
            plugins.console.insert_scripts_styles(self.scripts, self.styles, \
 
219
                self.scripts_init)
 
220
 
185
221
        # Prepare the HTTP and HTML headers before the first write is made
186
222
        if self.content_type != None:
187
223
            self.apache_req.content_type = self.content_type
204
240
 
205
241
        if not self.headers_written:
206
242
            self.__writeheaders()
207
 
        self.apache_req.write(string, flush)
 
243
        if isinstance(string, unicode):
 
244
            # Encode unicode strings as UTF-8
 
245
            # (Otherwise cannot handle being written to a bytestream)
 
246
            self.apache_req.write(string.encode('utf8'), flush)
 
247
        else:
 
248
            # 8-bit clean strings just get written directly.
 
249
            # This includes binary strings.
 
250
            self.apache_req.write(string, flush)
208
251
 
209
252
    def flush(self):
210
253
        """Flushes the output buffer."""
220
263
        """Reads at most len bytes directly from the client. (See mod_python
221
264
        Request.read)."""
222
265
        if len is None:
223
 
            self.apache_req.read()
 
266
            return self.apache_req.read()
224
267
        else:
225
 
            self.apache_req.read(len)
 
268
            return self.apache_req.read(len)
226
269
 
227
 
    def throw_error(self, httpcode):
 
270
    def throw_error(self, httpcode, message=None):
228
271
        """Writes out an HTTP error of the specified code. Raises an exception
229
272
        which is caught by the dispatch or web server, so any code following
230
273
        this call will not be executed.
232
275
        httpcode: An HTTP response status code. Pass a constant from the
233
276
        Request class.
234
277
        """
235
 
        raise mod_python.apache.SERVER_RETURN, httpcode
 
278
        raise common.util.IVLEError(httpcode, message)
236
279
 
237
280
    def throw_redirect(self, location):
238
281
        """Writes out an HTTP redirect to the specified URL. Raises an
244
287
        """
245
288
        mod_python.util.redirect(self.apache_req, location)
246
289
 
 
290
    def add_cookie(self, cookie, value=None, **attributes):
 
291
        """Inserts a cookie into this request object's headers."""
 
292
        if value is None:
 
293
            Cookie.add_cookie(self.apache_req, cookie)
 
294
        else:
 
295
            Cookie.add_cookie(self.apache_req, cookie, value, **attributes)
 
296
 
247
297
    def get_session(self):
248
298
        """Returns a mod_python Session object for this request.
249
299
        Note that this is dependent on mod_python and may need to change
250
300
        interface if porting away from mod_python."""
251
 
        # Cache the session object
 
301
        # Cache the session object and set the timeout to 24 hours.
252
302
        if not hasattr(self, 'session'):
253
 
            self.session = Session.Session(self.apache_req)
 
303
            self.session = Session.FileSession(self.apache_req,
 
304
                                               timeout = 60 * 60 * 24)
254
305
        return self.session
255
306
 
256
307
    def get_fieldstorage(self):
261
312
        if not hasattr(self, 'fields'):
262
313
            self.fields = util.FieldStorage(self.apache_req)
263
314
        return self.fields
 
315
 
 
316
    def get_cgi_environ(self):
 
317
        """Returns the CGI environment emulation for this request. (Calls
 
318
        add_common_vars). The environment is returned as a mapping
 
319
        compatible with os.environ."""
 
320
        if not self.got_common_vars:
 
321
            self.apache_req.add_common_vars()
 
322
            self.got_common_vars = True
 
323
        return self.apache_req.subprocess_env
 
324
 
 
325
    @staticmethod
 
326
    def get_http_codename(code):
 
327
        """Given a HTTP error code int, returns a (name, description)
 
328
        pair, suitable for displaying to the user.
 
329
        May return (None,None) if code is unknown.
 
330
        Only lists common 4xx and 5xx codes (since this is just used
 
331
        to display throw_error error messages).
 
332
        """
 
333
        try:
 
334
            return http_codenames[code]
 
335
        except KeyError:
 
336
            return None, None
 
337
 
 
338
# Human strings for HTTP response codes
 
339
http_codenames = {
 
340
    Request.HTTP_BAD_REQUEST:
 
341
        ("Bad Request",
 
342
        "Your browser sent a request IVLE did not understand."),
 
343
    Request.HTTP_UNAUTHORIZED:
 
344
        ("Unauthorized",
 
345
        "You are not allowed to view this part of IVLE."),
 
346
    Request.HTTP_FORBIDDEN:
 
347
        ("Forbidden",
 
348
        "You are not allowed to view this part of IVLE."),
 
349
    Request.HTTP_NOT_FOUND:
 
350
        ("Not Found",
 
351
        "The application or file you requested does not exist."),
 
352
    Request.HTTP_METHOD_NOT_ALLOWED:
 
353
        ("Method Not Allowed",
 
354
        "Your browser is interacting with IVLE in the wrong way."
 
355
        "This is probably a bug in IVLE. "
 
356
        "Please report it to the administrators."),
 
357
    Request.HTTP_INTERNAL_SERVER_ERROR:
 
358
        ("Internal Server Error",
 
359
        "An unknown error occured in IVLE."),
 
360
    Request.HTTP_NOT_IMPLEMENTED:
 
361
        ("Not Implemented",
 
362
        "The application or file you requested has not been implemented "
 
363
        "in IVLE."),
 
364
    Request.HTTP_SERVICE_UNAVAILABLE:
 
365
        ("Service Unavailable",
 
366
        "IVLE is currently experiencing technical difficulties. "
 
367
        "Please try again later."),
 
368
}