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

1072 by matt.giuca
Renamed scripts to services.
1
#!/usr/bin/python
2
3
# IVLE - Informatics Virtual Learning Environment
4
# Copyright (C) 2007-2008 The University of Melbourne
5
#
6
# This program is free software; you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; either version 2 of the License, or
9
# (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
# GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
1099.3.1 by William Grant
Change serveservice's interface - it now uses a JSON-based non-CGI one.
20
# Author: Thomas Conway, Will Grant
1072 by matt.giuca
Renamed scripts to services.
21
22
import mimetypes
23
import os
1099.3.1 by William Grant
Change serveservice's interface - it now uses a JSON-based non-CGI one.
24
import sys
1072 by matt.giuca
Renamed scripts to services.
25
import StringIO
1099.3.1 by William Grant
Change serveservice's interface - it now uses a JSON-based non-CGI one.
26
from optparse import OptionParser
27
28
import cjson
1072 by matt.giuca
Renamed scripts to services.
29
1079 by William Grant
Merge setup-refactor branch. This completely breaks existing installations;
30
from ivle import zip as zipmod
1099.3.2 by William Grant
Move more stuff from interpretservice to serveservice.
31
import ivle.conf.app.server
32
33
def determine_file_type(filename):
34
    filetype = mimetypes.guess_type(filename)[0]
35
    if filetype is None:
36
         filetype = ivle.conf.mimetypes.default_mimetype
37
    return filetype
1072 by matt.giuca
Renamed scripts to services.
38
1099.3.5 by William Grant
Enable CGI path backtracking in serveservice.
39
def throw_error(message, extra={}):
40
    error = {'error': message}
41
    error.update(extra)
42
    print cjson.encode(error)
1099.3.1 by William Grant
Change serveservice's interface - it now uses a JSON-based non-CGI one.
43
    sys.exit(0)
44
45
parser = OptionParser()
46
parser.add_option('-d', '--download', dest='download', action='store_true',
47
                  help='force download, not execution, of the paths')
48
(options, args) = parser.parse_args()
49
50
# Detect download mode. Download mode zips any multiple selection,
51
# and does not execute CGI scripts.
52
if options.download:
53
    download = True
1099.3.10 by William Grant
Convince serveservice not to mangle single paths when downloading.
54
    # paths is filled later.
55
else:
56
    download = False
57
    assert len(args) == 1
58
59
default_mimetype = "application/octet-stream"
60
zip_mimetype = "application/zip"
61
62
zipmode = False
63
zipbasepath = None
64
zipfilename = None
65
66
# If multiple paths have been specified, zip them up.
67
if len(args) > 1:
1099.3.1 by William Grant
Change serveservice's interface - it now uses a JSON-based non-CGI one.
68
    # Mangle the paths - we want the basename of their dirname in front.
69
    paths = []
1099.3.12 by William Grant
Support downloading of a selection of files as a zip.
70
    dir = os.path.dirname(args[0])
1099.3.1 by William Grant
Change serveservice's interface - it now uses a JSON-based non-CGI one.
71
    for path in args:
72
        assert os.path.dirname(path) == dir
73
        paths.append(os.path.join(os.path.basename(dir),
74
                                  os.path.basename(path)))
75
    dir = os.path.dirname(dir)
1072 by matt.giuca
Renamed scripts to services.
76
    zipmode = True
1099.3.1 by William Grant
Change serveservice's interface - it now uses a JSON-based non-CGI one.
77
    zipbasepath = dir
1072 by matt.giuca
Renamed scripts to services.
78
    zipfilename = os.path.basename(zipbasepath)
79
else:
1099.3.10 by William Grant
Convince serveservice not to mangle single paths when downloading.
80
    paths = args
1099.3.1 by William Grant
Change serveservice's interface - it now uses a JSON-based non-CGI one.
81
    filename = paths[0]
1099.3.5 by William Grant
Enable CGI path backtracking in serveservice.
82
    if not os.access(filename, os.F_OK):
83
        # The given path doesn't exist. CGI lets us backtrack and put the path
84
        # elements through which we pass into PATH_INFO, so we try that.
85
        while not os.access(filename, os.F_OK):
86
            filename, path_info_frag = os.path.split(filename)
87
88
        # We now have a file that exists, but is it something that we're allowed
89
        # to execute? If not, we should 404 anyway.
90
        if determine_file_type(filename) not in ivle.conf.app.server.interpreters:
91
            throw_error('not-found')
1099.3.1 by William Grant
Change serveservice's interface - it now uses a JSON-based non-CGI one.
92
93
    # If it's a directory, serve as a zip file
1072 by matt.giuca
Renamed scripts to services.
94
    if os.path.isdir(filename):
1099.3.2 by William Grant
Move more stuff from interpretservice to serveservice.
95
        if not download:
96
            # Not giving a directory listing - this is visible to everyone.
97
            throw_error('is-directory')
1072 by matt.giuca
Renamed scripts to services.
98
        zipmode = True
99
        # Zip it from the perspective of its own parent.
100
        # That way it will be a directory in the top level of the zip
101
        # file.
102
        if filename[-1] == os.sep: filename = filename[:-1]
103
        splitpath = filename.rsplit(os.sep, 1)
104
        if len(splitpath) == 1:
105
            zipbasepath = ''
106
            paths = [filename]
107
        else:
108
            zipbasepath = splitpath[0]
109
            paths = [splitpath[1]]
1099.3.1 by William Grant
Change serveservice's interface - it now uses a JSON-based non-CGI one.
110
        zipfilename = filename
1099.3.2 by William Grant
Move more stuff from interpretservice to serveservice.
111
    else:
112
        if not download and \
113
           determine_file_type(filename) in ivle.conf.app.server.interpreters:
1099.3.5 by William Grant
Enable CGI path backtracking in serveservice.
114
            throw_error('is-executable', {'path': filename})
1099.3.2 by William Grant
Move more stuff from interpretservice to serveservice.
115
116
        if (ivle.conf.app.server.blacklist_served_filetypes and \
117
                determine_file_type(filename) in \
118
                ivle.conf.app.server.served_filetypes_blacklist) or \
119
            (ivle.conf.app.server.served_filetypes_whitelist and \
120
                determine_file_type(filename) not in \
121
                ivle.conf.app.server.served_filetypes_whitelist):
122
            throw_error('forbidden')
1072 by matt.giuca
Renamed scripts to services.
123
124
if zipmode:
125
    # zipfilename is some filename. Strip trailing slash or extension,
126
    # and add ".zip".
127
    if zipfilename == '':
128
        zipfilename = "files"
129
    elif zipfilename[-1] == '/':
130
        zipfilename = zipfilename[:-1]
131
    elif '.' in zipfilename:
132
        zipfilename = zipfilename[:zipfilename.rindex('.')]
133
    zipfilename += ".zip"
1099.3.1 by William Grant
Change serveservice's interface - it now uses a JSON-based non-CGI one.
134
    #req.headers_out["Content-Disposition"] = ("attachment; filename=" +   
135
    #    zipfilename) # TODO
1072 by matt.giuca
Renamed scripts to services.
136
    zipfile = StringIO.StringIO()
137
    zipmod.make_zip(zipbasepath, paths, zipfile)
1099.3.10 by William Grant
Convince serveservice not to mangle single paths when downloading.
138
1099.3.8 by William Grant
Change the serveservice interface to return the data outside JSON, immediately
139
    print cjson.encode({'type': zip_mimetype,
1099.3.3 by William Grant
Make serveservice return types and possibly filenames as well.
140
                        'name': zipfilename})
1099.3.8 by William Grant
Change the serveservice interface to return the data outside JSON, immediately
141
    print zipfile.getvalue()
1072 by matt.giuca
Renamed scripts to services.
142
else:
1099.3.8 by William Grant
Change the serveservice interface to return the data outside JSON, immediately
143
    print cjson.encode({'type': determine_file_type(filename),
1099.3.4 by William Grant
... and names for normal files too.
144
                        'name': os.path.basename(filename)})
1099.3.8 by William Grant
Change the serveservice interface to return the data outside JSON, immediately
145
    print open(filename).read()