23
23
# Unlike "serve", all content is served as a static file, and with the
24
24
# application/octet-stream mime type.
25
25
# Also can serve directories or multiple files, automatically zipping them up.
27
from common import (util, studpath, zip)
26
# Uses a large chunk of code from "serve"
28
from common import studpath
29
from apps import server
35
32
# Serve all files as application/octet-stream so the browser presents them as
41
38
"""Handler for the Download application which serves files for
43
# Make sure the logged in user has permission to see this file
44
studpath.authorize(req)
51
41
req.write_html_head_foot = False
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")
59
zipbasepath = req.path
60
zipfilename = os.path.basename(zipbasepath)
61
for i in range(0, len(paths)):
62
paths[i] = paths[i].value
64
# Otherwise, just serve directly (unless it's a directory)
65
(_, path) = studpath.url_to_local(req.path)
67
req.throw_error(req.HTTP_NOT_FOUND,
68
"The path specified is invalid.")
69
elif not os.access(path, os.R_OK):
70
req.throw_error(req.HTTP_NOT_FOUND,
71
"The specified file does not exist.")
72
# If it's a directory, serve as a zip file
73
if os.path.isdir(path):
75
# Zip it from the perspective of its own parent.
76
# That way it will be a directory in the top level of the zip
79
if path[-1] == os.sep: path = path[:-1]
80
splitpath = path.rsplit(os.sep, 1)
81
if len(splitpath) == 1:
85
zipbasepath = splitpath[0]
86
paths = [splitpath[1]]
87
zipfilename = paths[0]
90
req.content_type = zip_mimetype
91
# zipfilename is some filename. Strip trailing slash or extension,
95
elif zipfilename[-1] == '/':
96
zipfilename = zipfilename[:-1]
97
elif '.' in zipfilename:
98
zipfilename = zipfilename[:zipfilename.rindex('.')]
100
req.headers_out["Content-Disposition"] = ("attachment; filename=" +
102
zipfile = StringIO.StringIO()
103
zip.make_zip(zipbasepath, paths, zipfile)
104
req.write(zipfile.getvalue())
106
req.content_type = default_mimetype
43
# Get the username of the student whose work we are browsing, and the path
44
# on the local machine where the file is stored.
45
(user, path) = studpath.url_to_local(req.path)
48
req.throw_error(req.HTTP_NOT_FOUND,
49
"The path specified is invalid.")
51
# Use the code from server to avoid duplication
52
server.serve_file(req, user, path, download=True)