17
17
# along with this program; if not, write to the Free Software
18
18
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
# Script: serveservice
21
# Author: Thomas Conway
24
# A CGI script for serving files.
20
# Author: Thomas Conway, Will Grant
27
from optparse import OptionParser
31
31
from ivle import (cgirequest, studpath)
32
32
from ivle import zip as zipmod
34
req = cgirequest.CGIRequest()
35
req.install_error_handler()
37
# Work out the parts of the URL
38
url = urlparse.urlparse(req.path)
41
filename = studpath.url_to_jailpaths(urlpath)[2]
34
def throw_error(message):
35
print cjson.encode({'error': message})
38
parser = OptionParser()
39
parser.add_option('-d', '--download', dest='download', action='store_true',
40
help='force download, not execution, of the paths')
41
(options, args) = parser.parse_args()
43
# Detect download mode. Download mode zips any multiple selection,
44
# and does not execute CGI scripts.
48
dir = os.path.dirname(args[0])
50
# Mangle the paths - we want the basename of their dirname in front.
53
assert os.path.dirname(path) == dir
54
paths.append(os.path.join(os.path.basename(dir),
55
os.path.basename(path)))
56
dir = os.path.dirname(dir)
43
61
default_mimetype = "application/octet-stream"
44
62
zip_mimetype = "application/zip"
51
# If any "path=" variables have been supplied, bring these into a list and
52
# make a zip file instead.
53
fields = req.get_fieldstorage()
54
paths = fields.getlist("path")
68
# If multiple paths have been specified, zip them up.
57
zipbasepath = filename
58
72
zipfilename = os.path.basename(zipbasepath)
59
#for i in range(0, len(paths)):
60
#paths[i] = paths[i].value
63
req.throw_error(req.HTTP_NOT_FOUND,
64
"The path specified is invalid.")
65
elif not os.access(filename, os.R_OK):
66
req.throw_error(req.HTTP_NOT_FOUND,
67
"The specified file (%s) does not exist." % urlpath)
68
# If it's a directory, serve as a zip file
75
if not os.access(filename, os.R_OK):
76
throw_error('not-found')
78
# If it's a directory, serve as a zip file
69
79
if os.path.isdir(filename):
71
81
# Zip it from the perspective of its own parent.
92
101
elif '.' in zipfilename:
93
102
zipfilename = zipfilename[:zipfilename.rindex('.')]
94
103
zipfilename += ".zip"
95
req.headers_out["Content-Disposition"] = ("attachment; filename=" +
104
#req.headers_out["Content-Disposition"] = ("attachment; filename=" +
105
# zipfilename) # TODO
97
106
zipfile = StringIO.StringIO()
98
107
zipmod.make_zip(zipbasepath, paths, zipfile)
100
req.write(zipfile.getvalue())
109
print cjson.encode({'content': zipfile.getvalue(), 'type': zip_mimetype})
102
#req.content_type = default_mimetype
103
req.sendfile(filename)
111
print cjson.encode({'content': open(filename).read()})