~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
1157 by William Grant
serveservice now only respects the download (black|white)lists when serving,
116
        if not download and (
117
            (ivle.conf.app.server.blacklist_served_filetypes and \
1099.3.2 by William Grant
Move more stuff from interpretservice to serveservice.
118
                determine_file_type(filename) in \
119
                ivle.conf.app.server.served_filetypes_blacklist) or \
120
            (ivle.conf.app.server.served_filetypes_whitelist and \
121
                determine_file_type(filename) not in \
1157 by William Grant
serveservice now only respects the download (black|white)lists when serving,
122
                ivle.conf.app.server.served_filetypes_whitelist)):
1099.3.2 by William Grant
Move more stuff from interpretservice to serveservice.
123
            throw_error('forbidden')
1072 by matt.giuca
Renamed scripts to services.
124
125
if zipmode:
126
    # zipfilename is some filename. Strip trailing slash or extension,
127
    # and add ".zip".
128
    if zipfilename == '':
129
        zipfilename = "files"
130
    elif zipfilename[-1] == '/':
131
        zipfilename = zipfilename[:-1]
132
    elif '.' in zipfilename:
133
        zipfilename = zipfilename[:zipfilename.rindex('.')]
134
    zipfilename += ".zip"
1099.3.1 by William Grant
Change serveservice's interface - it now uses a JSON-based non-CGI one.
135
    #req.headers_out["Content-Disposition"] = ("attachment; filename=" +   
136
    #    zipfilename) # TODO
1072 by matt.giuca
Renamed scripts to services.
137
    zipfile = StringIO.StringIO()
138
    zipmod.make_zip(zipbasepath, paths, zipfile)
1099.3.10 by William Grant
Convince serveservice not to mangle single paths when downloading.
139
1099.3.8 by William Grant
Change the serveservice interface to return the data outside JSON, immediately
140
    print cjson.encode({'type': zip_mimetype,
1099.3.3 by William Grant
Make serveservice return types and possibly filenames as well.
141
                        'name': zipfilename})
1163 by William Grant
Stream files from serveservice, rather than reading the whole file in at once.
142
143
    stream = zipfile
144
    stream.seek(0)
1072 by matt.giuca
Renamed scripts to services.
145
else:
1163 by William Grant
Stream files from serveservice, rather than reading the whole file in at once.
146
1099.3.8 by William Grant
Change the serveservice interface to return the data outside JSON, immediately
147
    print cjson.encode({'type': determine_file_type(filename),
1099.3.4 by William Grant
... and names for normal files too.
148
                        'name': os.path.basename(filename)})
1163 by William Grant
Stream files from serveservice, rather than reading the whole file in at once.
149
    stream = open(filename)
150
    
151
next = stream.read(1024)
152
while next:
153
    sys.stdout.write(next)
154
    next = stream.read(1024)