~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."""
243 by mattgiuca
Added common/zip.py. Creates a zip file from paths in the student directory.
43
    zipmode = False
44
    zipbasepath = None
45
    zipfilename = None
46
    path = None
93 by mattgiuca
New directory hierarchy.
47
48
    req.write_html_head_foot = False
49
243 by mattgiuca
Added common/zip.py. Creates a zip file from paths in the student directory.
50
    # If any "path=" variables have been supplied, bring these into a list and
51
    # make a zip file instead.
52
    fields = req.get_fieldstorage()
53
    paths = fields.getlist("path")
54
    if len(paths) > 0:
55
        zipmode = True
56
        zipbasepath = req.path
57
        zipfilename = os.path.basename(zipbasepath)
58
        for i in range(0, len(paths)):
59
            paths[i] = paths[i].value
60
    else:
61
        # Otherwise, just serve directly (unless it's a directory)
62
        (_, path) = studpath.url_to_local(req.path)
63
        if path is None:
64
            # TODO: Nicer 404 message?
65
            req.throw_error(req.HTTP_NOT_FOUND)
66
        elif not os.access(path, os.R_OK):
67
            req.throw_error(req.HTTP_NOT_FOUND)
68
        # If it's a directory, serve as a zip file
69
        if os.path.isdir(path):
70
            zipmode = True
71
            # Zip it from the perspective of its own parent.
72
            # That way it will be a directory in the top level of the zip
73
            # file.
74
            path = req.path
75
            if path[-1] == os.sep: path = path[:-1]
76
            splitpath = path.rsplit(os.sep, 1)
77
            if len(splitpath) == 1:
78
                zipbasepath = ''
79
                paths = [path]
80
            else:
81
                zipbasepath = splitpath[0]
82
                paths = [splitpath[1]]
83
            zipfilename = paths[0]
84
85
    if zipmode:
86
        req.content_type = zip_mimetype
87
        # zipfilename is some filename. Strip trailing slash or extension,
88
        # and add ".zip".
89
        if zipfilename == '':
90
            zipfilename = "files"
91
        elif zipfilename[-1] == '/':
92
            zipfilename = zipfilename[:-1]
93
        elif '.' in zipfilename:
94
            zipfilename = zipfilename[:zipfilename.rindex('.')]
95
        zipfilename += ".zip"
96
        req.headers_out["Content-Disposition"] = ("attachment; filename=" +
97
            zipfilename)
98
        zipfile = StringIO.StringIO()
99
        zip.make_zip(zipbasepath, paths, zipfile,req)
100
        req.write(zipfile.getvalue())
101
    else:
102
        req.content_type = default_mimetype
103
        req.sendfile(path)