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

« back to all changes in this revision

Viewing changes to www/apps/download/__init__.py

  • Committer: dcoles
  • Date: 2008-03-31 01:10:43 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:720
download: Fixing the download button.
    We now run download in the jail so that we don't encounter permission 
    problems.  Since this is very similar to "serve" we now extend serveservice 
    to do the work of download and use the serve code to do download.

    w/a/s/__init__.py: Overloaded servefile to support downloads
    w/a/d/__init__.py: Use servefile from server rather than old implementaion
    s/serveservice: Added support for download of directories (as zip files)
    l/c/zip.py: Now uses paths not ivle_urls

Show diffs side-by-side

added added

removed removed

Lines of Context:
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.
26
 
 
27
 
from common import (util, studpath, zip)
28
 
import conf
29
 
 
30
 
import functools
31
 
import os
32
 
import mimetypes
 
26
# Uses a large chunk of code from "serve"
 
27
 
 
28
from common import studpath
 
29
from apps import server
33
30
import StringIO
34
31
 
35
32
# Serve all files as application/octet-stream so the browser presents them as
40
37
def handle(req):
41
38
    """Handler for the Download application which serves files for
42
39
    download."""
43
 
    # Make sure the logged in user has permission to see this file
44
 
    studpath.authorize(req)
45
 
 
46
 
    zipmode = False
47
 
    zipbasepath = None
48
 
    zipfilename = None
49
 
    path = None
50
40
 
51
41
    req.write_html_head_foot = False
52
42
 
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
 
            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):
74
 
            zipmode = True
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
77
 
            # file.
78
 
            path = req.path
79
 
            if path[-1] == os.sep: path = path[:-1]
80
 
            splitpath = path.rsplit(os.sep, 1)
81
 
            if len(splitpath) == 1:
82
 
                zipbasepath = ''
83
 
                paths = [path]
84
 
            else:
85
 
                zipbasepath = splitpath[0]
86
 
                paths = [splitpath[1]]
87
 
            zipfilename = paths[0]
88
 
 
89
 
    if zipmode:
90
 
        req.content_type = zip_mimetype
91
 
        # zipfilename is some filename. Strip trailing slash or extension,
92
 
        # and add ".zip".
93
 
        if zipfilename == '':
94
 
            zipfilename = "files"
95
 
        elif zipfilename[-1] == '/':
96
 
            zipfilename = zipfilename[:-1]
97
 
        elif '.' in zipfilename:
98
 
            zipfilename = zipfilename[:zipfilename.rindex('.')]
99
 
        zipfilename += ".zip"
100
 
        req.headers_out["Content-Disposition"] = ("attachment; filename=" +
101
 
            zipfilename)
102
 
        zipfile = StringIO.StringIO()
103
 
        zip.make_zip(zipbasepath, paths, zipfile)
104
 
        req.write(zipfile.getvalue())
105
 
    else:
106
 
        req.content_type = default_mimetype
107
 
        req.sendfile(path)
 
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)
 
46
 
 
47
    if user is None:
 
48
        req.throw_error(req.HTTP_NOT_FOUND,
 
49
            "The path specified is invalid.")
 
50
 
 
51
    # Use the code from server to avoid duplication
 
52
    server.serve_file(req, user, path, download=True)