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

« back to all changes in this revision

Viewing changes to ivle/fileservice_lib/listing.py

  • Committer: Matt Giuca
  • Date: 2009-05-19 02:54:08 UTC
  • mfrom: (1258 trunk)
  • mto: This revision was merged to the branch mainline in revision 1322.
  • Revision ID: matt.giuca@gmail.com-20090519025408-19c7cjl7w6ot6frm
MergedĀ fromĀ trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
110
110
 
111
111
import ivle.svn
112
112
import ivle.date
113
 
from ivle import (util, studpath)
114
 
import ivle.conf.mimetypes
 
113
import ivle.mimetypes
 
114
from ivle import studpath
115
115
 
116
116
# Make a Subversion client object
117
117
svnclient = pysvn.Client()
151
151
        req.status = req.HTTP_FORBIDDEN
152
152
        req.headers_out['X-IVLE-Return-Error'] = 'Forbidden'
153
153
        req.write("Forbidden")
154
 
    elif not os.access(path, os.R_OK):
155
 
        req.status = req.HTTP_NOT_FOUND
156
 
        req.headers_out['X-IVLE-Return-Error'] = 'File not found'
157
 
        req.write("File not found")
158
 
    elif os.path.isdir(path):
 
154
        return
 
155
 
 
156
    # If this is a repository-revision request, it needs to be treated
 
157
    # differently than if it were a regular file request.
 
158
    # Note: If there IS a revision requested but the file doesn't exist in
 
159
    # that revision, this will terminate.
 
160
    revision = _get_revision_or_die(req, svnclient, path)
 
161
 
 
162
    if revision is None:
 
163
        if not os.access(path, os.R_OK):
 
164
            req.status = req.HTTP_NOT_FOUND
 
165
            req.headers_out['X-IVLE-Return-Error'] = 'File not found'
 
166
            req.write("File not found")
 
167
            return
 
168
        is_dir = os.path.isdir(path)
 
169
    else:
 
170
        is_dir = ivle.svn.revision_is_dir(svnclient, path, revision)
 
171
 
 
172
    if is_dir:
159
173
        # It's a directory. Return the directory listing.
160
174
        req.content_type = mime_dirlisting
161
175
        req.headers_out['X-IVLE-Return'] = 'Dir'
162
176
        # TODO: Fix this dirty, dirty hack
163
 
        newjson = get_dirlisting(req, svnclient, path)
 
177
        newjson = get_dirlisting(req, svnclient, path, revision)
164
178
        if ("X-IVLE-Action-Error" in req.headers_out):
165
179
            newjson["Error"] = req.headers_out["X-IVLE-Action-Error"]
166
180
        req.write(cjson.encode(newjson))
167
181
    elif return_contents:
168
182
        # It's a file. Return the file contents.
169
183
        # First get the mime type of this file
170
 
        # (Note that importing ivle.util has already initialised mime types)
171
184
        (type, _) = mimetypes.guess_type(path)
172
185
        if type is None:
173
 
            type = ivle.conf.mimetypes.default_mimetype
 
186
            type = ivle.mimetypes.DEFAULT_MIMETYPE
174
187
        req.content_type = type
175
188
        req.headers_out['X-IVLE-Return'] = 'File'
176
189
 
177
 
        send_file(req, svnclient, path)
 
190
        send_file(req, svnclient, path, revision)
178
191
    else:
179
192
        # It's a file. Return a "fake directory listing" with just this file.
180
193
        req.content_type = mime_dirlisting
181
194
        req.headers_out['X-IVLE-Return'] = 'File'
182
 
        req.write(cjson.encode(get_dirlisting(req, svnclient, path)))
 
195
        req.write(cjson.encode(get_dirlisting(req, svnclient, path,
 
196
                                              revision)))
183
197
 
184
198
def _get_revision_or_die(req, svnclient, path):
185
 
    '''Looks for a revision specification in req's URL, returning the revision
186
 
       specified. Returns None if there was no revision specified. Errors and
187
 
       terminates the request if the specification was bad, or it doesn't exist
188
 
       for the given path.
189
 
    '''
 
199
    """Looks for a revision specification in req's URL.
 
200
    Errors and terminates the request if the specification was bad, or it
 
201
    doesn't exist for the given path.
 
202
    @param req: Request object.
 
203
    @param svnclient: pysvn Client object.
 
204
    @param path: Path to the file whose revision is to be retrieved.
 
205
    @returns: pysvn Revision object, for the file+revision specified, or None
 
206
        if there was no revision specified.
 
207
    """
190
208
    # Work out the revisions from query
191
209
    r_str = req.get_fieldstorage().getfirst("r")
192
210
    revision = ivle.svn.revision_from_string(r_str)
195
213
    if r_str and not (revision and
196
214
                      ivle.svn.revision_exists(svnclient, path, revision)):
197
215
        req.status = req.HTTP_NOT_FOUND
198
 
        req.headers_out['X-IVLE-Return-Error'] = 'Revision not found'
 
216
        message = ('Revision not found or file not found in revision %d' %
 
217
                   revision.number)
 
218
        req.headers_out['X-IVLE-Return-Error'] = message
199
219
        req.ensure_headers_written()
200
 
        req.write('Revision not found')
 
220
        req.write(message)
201
221
        req.flush()
202
222
        sys.exit()
203
223
    return revision
204
224
 
205
 
def send_file(req, svnclient, path):
206
 
    revision = _get_revision_or_die(req, svnclient, path)
 
225
def send_file(req, svnclient, path, revision):
 
226
    """Given a local absolute path to a file, sends the contents of the file
 
227
    to the client.
 
228
 
 
229
    @param req: Request object. Will not be mutated; just reads the session.
 
230
    @param svnclient: Svn client object.
 
231
    @param path: String. Absolute path on the local file system. Not checked,
 
232
        must already be guaranteed safe. May be a file or a directory.
 
233
    @param revision: pysvn Revision object for the given path, or None.
 
234
    """
207
235
    if revision:
208
236
        req.write(svnclient.cat(path, revision=revision))
209
237
    else:
210
238
        req.sendfile(path)
211
239
 
212
 
def get_dirlisting(req, svnclient, path):
 
240
def get_dirlisting(req, svnclient, path, revision):
213
241
    """Given a local absolute path, creates a directory listing object
214
242
    ready to be JSONized and sent to the client.
215
243
 
216
 
    req: Request object. Will not be mutated; just reads the session.
217
 
    svnclient: Svn client object.
218
 
    path: String. Absolute path on the local file system. Not checked,
 
244
    @param req: Request object. Will not be mutated; just reads the session.
 
245
    @param svnclient: Svn client object.
 
246
    @param path: String. Absolute path on the local file system. Not checked,
219
247
        must already be guaranteed safe. May be a file or a directory.
 
248
    @param revision: pysvn Revision object for the given path, or None.
220
249
    """
221
250
 
222
 
    revision = _get_revision_or_die(req, svnclient, path)
223
 
 
224
251
    # Start by trying to do an SVN status, so we can report file version
225
252
    # status
226
253
    listing = {}
284
311
    d = {}
285
312
    if stat.S_ISDIR(file_stat.st_mode):
286
313
        d["isdir"] = True
287
 
        d["type_nice"] = util.nice_filetype("/")
 
314
        d["type_nice"] = ivle.mimetypes.nice_filetype("/")
288
315
        # Only directories can be published
289
316
        d["published"] = studpath.published(fullpath)
290
317
    else:
292
319
        d["size"] = file_stat.st_size
293
320
        (type, _) = mimetypes.guess_type(fullpath)
294
321
        if type is None:
295
 
            type = ivle.conf.mimetypes.default_mimetype
 
322
            type = ivle.mimetypes.DEFAULT_MIMETYPE
296
323
        d["type"] = type
297
 
        d["type_nice"] = util.nice_filetype(fullpath)
 
324
        d["type_nice"] = ivle.mimetypes.nice_filetype(fullpath)
298
325
    d["mtime"] = file_stat.st_mtime
299
326
    d["mtime_nice"] = ivle.date.make_date_nice(file_stat.st_mtime)
300
327
    d["mtime_short"] = ivle.date.make_date_nice_short(file_stat.st_mtime)
327
354
        filename = os.path.basename(fullpath)
328
355
    text_status = status.text_status
329
356
    d = {'svnstatus': str(text_status)}
 
357
 
 
358
    if status.entry is not None:
 
359
        d.update({
 
360
           'svnurl': status.entry.url,
 
361
           'svnrevision': status.entry.revision.number
 
362
             if status.entry.revision.kind == pysvn.opt_revision_kind.number
 
363
             else None,
 
364
        })
 
365
 
330
366
    try:
331
367
        d.update(_fullpath_stat_fileinfo(fullpath))
332
368
    except OSError: