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

93 by mattgiuca
New directory hierarchy.
1
# IVLE
2
# Copyright (C) 2007-2008 The University of Melbourne
3
#
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
18
# App: download
19
# Author: Matt Giuca
243 by mattgiuca
Added common/zip.py. Creates a zip file from paths in the student directory.
20
# Date: 17/1/2008
93 by mattgiuca
New directory hierarchy.
21
22
# Serves content to the user (acting as a web server for students files).
23
# Unlike "serve", all content is served as a static file, and with the
24
# application/octet-stream mime type.
25
# Also can serve directories or multiple files, automatically zipping them up.
26
243 by mattgiuca
Added common/zip.py. Creates a zip file from paths in the student directory.
27
from common import (util, studpath, zip)
93 by mattgiuca
New directory hierarchy.
28
import conf
29
30
import functools
31
import os
32
import mimetypes
243 by mattgiuca
Added common/zip.py. Creates a zip file from paths in the student directory.
33
import StringIO
93 by mattgiuca
New directory hierarchy.
34
35
# Serve all files as application/octet-stream so the browser presents them as
36
# a download.
37
default_mimetype = "application/octet-stream"
243 by mattgiuca
Added common/zip.py. Creates a zip file from paths in the student directory.
38
zip_mimetype = "application/zip"
93 by mattgiuca
New directory hierarchy.
39
40
def handle(req):
41
    """Handler for the Download application which serves files for
42
    download."""
262 by mattgiuca
studpath: Added "authorize" function which checks the logged in user against
43
    # Make sure the logged in user has permission to see this file
44
    studpath.authorize(req)
45
243 by mattgiuca
Added common/zip.py. Creates a zip file from paths in the student directory.
46
    zipmode = False
47
    zipbasepath = None
48
    zipfilename = None
49
    path = None
93 by mattgiuca
New directory hierarchy.
50
51
    req.write_html_head_foot = False
52
243 by mattgiuca
Added common/zip.py. Creates a zip file from paths in the student directory.
53
    # If any "path=" variables have been supplied, bring these into a list and
54
    # make a zip file instead.
55
    fields = req.get_fieldstorage()
56
    paths = fields.getlist("path")
57
    if len(paths) > 0:
58
        zipmode = True
59
        zipbasepath = req.path
60
        zipfilename = os.path.basename(zipbasepath)
61
        for i in range(0, len(paths)):
62
            paths[i] = paths[i].value
63
    else:
64
        # Otherwise, just serve directly (unless it's a directory)
65
        (_, path) = studpath.url_to_local(req.path)
66
        if path is None:
67
            # TODO: Nicer 404 message?
68
            req.throw_error(req.HTTP_NOT_FOUND)
69
        elif not os.access(path, os.R_OK):
70
            req.throw_error(req.HTTP_NOT_FOUND)
71
        # If it's a directory, serve as a zip file
72
        if os.path.isdir(path):
73
            zipmode = True
74
            # Zip it from the perspective of its own parent.
75
            # That way it will be a directory in the top level of the zip
76
            # file.
77
            path = req.path
78
            if path[-1] == os.sep: path = path[:-1]
79
            splitpath = path.rsplit(os.sep, 1)
80
            if len(splitpath) == 1:
81
                zipbasepath = ''
82
                paths = [path]
83
            else:
84
                zipbasepath = splitpath[0]
85
                paths = [splitpath[1]]
86
            zipfilename = paths[0]
87
88
    if zipmode:
89
        req.content_type = zip_mimetype
90
        # zipfilename is some filename. Strip trailing slash or extension,
91
        # and add ".zip".
92
        if zipfilename == '':
93
            zipfilename = "files"
94
        elif zipfilename[-1] == '/':
95
            zipfilename = zipfilename[:-1]
96
        elif '.' in zipfilename:
97
            zipfilename = zipfilename[:zipfilename.rindex('.')]
98
        zipfilename += ".zip"
99
        req.headers_out["Content-Disposition"] = ("attachment; filename=" +
100
            zipfilename)
101
        zipfile = StringIO.StringIO()
102
        zip.make_zip(zipbasepath, paths, zipfile,req)
103
        req.write(zipfile.getvalue())
104
    else:
105
        req.content_type = default_mimetype
106
        req.sendfile(path)