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

« back to all changes in this revision

Viewing changes to ivle/fileservice_lib/action.py

  • Committer: William Grant
  • Date: 2009-04-28 04:50:39 UTC
  • Revision ID: grantw@unimelb.edu.au-20090428045039-ibb7gwtjrhe9osq3
Populate req.config in a cleaner manner.

Show diffs side-by-side

added added

removed removed

Lines of Context:
135
135
import pysvn
136
136
 
137
137
from ivle import (util, studpath, zip)
 
138
from ivle.fileservice_lib.exceptions import WillNotOverwrite
138
139
import ivle.conf
139
140
 
 
141
 
140
142
def get_login(_realm, existing_login, _may_save):
141
143
    """Callback function used by pysvn for authentication.
142
144
    realm, existing_login, _may_save: The 3 arguments passed by pysvn to
149
151
    # If we're being asked again, then it means the credentials failed for
150
152
    # some reason and we should just fail. (This is not desirable, but it's
151
153
    # better than being asked an infinite number of times).
152
 
    return (existing_login != "", ivle.conf.login, ivle.conf.svn_pass, True)
 
154
    return (existing_login != "", str(ivle.conf.login),
 
155
                                  str(ivle.conf.svn_pass), True)
153
156
 
154
157
# Make a Subversion client object
155
158
svnclient = pysvn.Client()
194
197
    except KeyError:
195
198
        # Default, just send an error but then continue
196
199
        raise ActionError("Unknown action")
197
 
    action(req, fields)
 
200
    return action(req, fields)
198
201
 
199
202
def actionpath_to_urlpath(req, path):
200
203
    """Determines the URL path (relative to the student home) upon which the
263
266
    except shutil.Error:
264
267
        raise ActionError("Could not move the file specified")
265
268
 
 
269
def svn_movefile(req, frompath, topath, copy=False):
 
270
    """Performs an svn move, resolving filenames, checking for any errors,
 
271
    and throwing ActionErrors if necessary. Can also be used to do a copy
 
272
    operation instead.
 
273
 
 
274
    frompath and topath are straight paths from the client. Will be checked.
 
275
    """
 
276
    if frompath is None or topath is None:
 
277
        raise ActionError("Required field missing")
 
278
    frompath = actionpath_to_local(req, frompath)
 
279
    topath = actionpath_to_local(req, topath)
 
280
    if not os.path.exists(frompath):
 
281
        raise ActionError("The source file does not exist")
 
282
    if os.path.exists(topath):
 
283
        if frompath == topath:
 
284
            raise ActionError("Source and destination are the same")
 
285
        raise ActionError("A file already exists with that name")
 
286
 
 
287
    try:
 
288
        if copy:
 
289
            svnclient.copy(frompath, topath)
 
290
        else:
 
291
            svnclient.move(frompath, topath)
 
292
    except OSError:
 
293
        raise ActionError("Could not move the file specified")
 
294
    except pysvn.ClientError:
 
295
        raise ActionError("Could not move the file specified")  
 
296
 
 
297
 
266
298
### ACTIONS ###
267
299
 
268
300
def action_delete(req, fields):
370
402
 
371
403
    Reads fields: 'path', 'data' (file upload, multiple), 'unpack'
372
404
    """
373
 
 
374
405
    # Important: Data is "None" if the file submitted is empty.
375
406
    path = fields.getfirst('path')
376
407
    data = fields['data']
389
420
    for datum in data:
390
421
        # Each of the uploaded files
391
422
        filepath = os.path.join(path, datum.filename)
 
423
        (_, _, filepath_local) = studpath.url_to_jailpaths(filepath)
 
424
        if os.path.isdir(filepath_local):
 
425
            raise ActionError("A directory already exists "
 
426
                    + "with that name")
 
427
        else:
 
428
            if os.path.exists(filepath_local):
 
429
                raise ActionError("A file already exists with that name")
392
430
        filedata = datum.file
393
431
 
394
432
        if unpack and datum.filename.lower().endswith(".zip"):
403
441
                zip.unzip(abspath, filedata)
404
442
            except (OSError, IOError):
405
443
                goterror = True
 
444
            except WillNotOverwrite, e:
 
445
                raise ActionError("File '" + e.filename + "' already exists.")
406
446
        else:
407
447
            # Not a zip file
408
448
            (_, _, filepath_local) = studpath.url_to_jailpaths(filepath)
444
484
    files = fields.getlist('file')
445
485
    if dst is None or src is None or mode is None:
446
486
        raise ActionError("Required field missing")
447
 
    if mode == "copy":
448
 
        copy = True
449
 
    elif mode == "move":
450
 
        copy = False
451
 
    else:
452
 
        raise ActionError("Invalid mode (must be 'copy' or 'move')")
 
487
 
453
488
    dst_local = actionpath_to_local(req, dst)
454
489
    if not os.path.isdir(dst_local):
455
490
        raise ActionError("dst is not a directory")
464
499
        # The destination is found by taking just the basename of the file
465
500
        topath = os.path.join(dst, os.path.basename(file))
466
501
        try:
467
 
            movefile(req, frompath, topath, copy)
 
502
            if mode == "copy":
 
503
                movefile(req, frompath, topath, True)
 
504
            elif mode == "move":
 
505
                movefile(req, frompath, topath, False)
 
506
            elif mode == "svncopy":
 
507
                svn_movefile(req, frompath, topath, True)
 
508
            elif mode == "svnmove":
 
509
                svn_movefile(req, frompath, topath, False)
 
510
            else:
 
511
                raise ActionError("Invalid mode (must be '(svn)copy' or '(svn)move')")
468
512
        except ActionError, message:
469
513
            # Store the error for later; we want to copy as many as possible
470
514
            if errormsg is None:
694
738
def action_svnrepostat(req, fields):
695
739
    """Discovers whether a path exists in a repo under the IVLE SVN root.
696
740
 
 
741
    If it does exist, returns a dict containing its metadata.
 
742
 
697
743
    Reads fields: 'path'
698
744
    """
699
745
    path = fields.getfirst('path')
700
746
    url = ivle.conf.svn_addr + "/" + path
701
 
    svnclient.exception_style = 1 
 
747
    svnclient.exception_style = 1
702
748
 
703
749
    try:
704
750
        svnclient.callback_get_login = get_login
705
 
        svnclient.info2(url)
 
751
        info = svnclient.info2(url,
 
752
            revision=pysvn.Revision(pysvn.opt_revision_kind.head))[0][1]
 
753
        return {'svnrevision': info['rev'].number
 
754
                  if info['rev'] and
 
755
                     info['rev'].kind == pysvn.opt_revision_kind.number
 
756
                  else None}
706
757
    except pysvn.ClientError, e:
707
758
        # Error code 170000 means ENOENT in this revision.
708
759
        if e[1][0][1] == 170000:
709
760
            raise util.IVLEError(404, 'The specified repository path does not exist')
710
761
        else:
711
762
            raise ActionError(str(e[0]))
 
763
            
712
764
 
713
765
# Table of all action functions #
714
766
# Each function has the interface f(req, fields).