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

« back to all changes in this revision

Viewing changes to ivle/fileservice_lib/action.py

  • Committer: me at id
  • Date: 2009-01-15 06:11:02 UTC
  • mto: This revision was merged to the branch mainline in revision 1090.
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:branches%2Fstorm:1163
www/app/{subjects,tutorial}: Use the new Storm API to get enrolled subjects.

Show diffs side-by-side

added added

removed removed

Lines of Context:
131
131
import os
132
132
import cStringIO
133
133
import shutil
134
 
import urllib
135
134
 
136
135
import pysvn
137
136
 
138
137
from ivle import (util, studpath, zip)
139
 
from ivle.fileservice_lib.exceptions import WillNotOverwrite
140
138
import ivle.conf
141
139
 
142
 
 
143
140
def get_login(_realm, existing_login, _may_save):
144
141
    """Callback function used by pysvn for authentication.
145
142
    realm, existing_login, _may_save: The 3 arguments passed by pysvn to
198
195
    except KeyError:
199
196
        # Default, just send an error but then continue
200
197
        raise ActionError("Unknown action")
201
 
    return action(req, fields)
 
198
    action(req, fields)
202
199
 
203
200
def actionpath_to_urlpath(req, path):
204
201
    """Determines the URL path (relative to the student home) upon which the
229
226
 
230
227
    Does not mutate req.
231
228
    """
232
 
    r = studpath.to_home_path(actionpath_to_urlpath(req, path))
 
229
    (_, _, r) = studpath.url_to_jailpaths(actionpath_to_urlpath(req, path))
233
230
    if r is None:
234
231
        raise ActionError("Invalid path")
235
232
    return r
267
264
    except shutil.Error:
268
265
        raise ActionError("Could not move the file specified")
269
266
 
270
 
def svn_movefile(req, frompath, topath, copy=False):
271
 
    """Performs an svn move, resolving filenames, checking for any errors,
272
 
    and throwing ActionErrors if necessary. Can also be used to do a copy
273
 
    operation instead.
274
 
 
275
 
    frompath and topath are straight paths from the client. Will be checked.
276
 
    """
277
 
    if frompath is None or topath is None:
278
 
        raise ActionError("Required field missing")
279
 
    frompath = actionpath_to_local(req, frompath)
280
 
    topath = actionpath_to_local(req, topath)
281
 
    if not os.path.exists(frompath):
282
 
        raise ActionError("The source file does not exist")
283
 
    if os.path.exists(topath):
284
 
        if frompath == topath:
285
 
            raise ActionError("Source and destination are the same")
286
 
        raise ActionError("A file already exists with that name")
287
 
 
288
 
    try:
289
 
        if copy:
290
 
            svnclient.copy(frompath, topath)
291
 
        else:
292
 
            svnclient.move(frompath, topath)
293
 
    except OSError:
294
 
        raise ActionError("Could not move the file specified")
295
 
    except pysvn.ClientError:
296
 
        raise ActionError("Could not move the file specified")  
297
 
 
298
 
 
299
267
### ACTIONS ###
300
268
 
301
269
def action_delete(req, fields):
403
371
 
404
372
    Reads fields: 'path', 'data' (file upload, multiple), 'unpack'
405
373
    """
 
374
 
406
375
    # Important: Data is "None" if the file submitted is empty.
407
376
    path = fields.getfirst('path')
408
377
    data = fields['data']
421
390
    for datum in data:
422
391
        # Each of the uploaded files
423
392
        filepath = os.path.join(path, datum.filename)
424
 
        filepath_local = studpath.to_home_path(filepath)
425
 
        if os.path.isdir(filepath_local):
426
 
            raise ActionError("A directory already exists "
427
 
                    + "with that name")
428
 
        else:
429
 
            if os.path.exists(filepath_local):
430
 
                raise ActionError("A file already exists with that name")
431
393
        filedata = datum.file
432
394
 
433
395
        if unpack and datum.filename.lower().endswith(".zip"):
437
399
            # filename)
438
400
            try:
439
401
                # First get the entire path (within jail)
440
 
                abspath = studpath.to_home_path(path)
 
402
                _, _, abspath = studpath.url_to_jailpaths(path)
441
403
                abspath = os.path.join(os.sep, abspath)
442
404
                zip.unzip(abspath, filedata)
443
405
            except (OSError, IOError):
444
406
                goterror = True
445
 
            except WillNotOverwrite, e:
446
 
                raise ActionError("File '" + e.filename + "' already exists.")
447
407
        else:
448
408
            # Not a zip file
449
 
            filepath_local = studpath.to_home_path(filepath)
 
409
            (_, _, filepath_local) = studpath.url_to_jailpaths(filepath)
450
410
            if filepath_local is None:
451
411
                raise ActionError("Invalid path")
452
412
 
485
445
    files = fields.getlist('file')
486
446
    if dst is None or src is None or mode is None:
487
447
        raise ActionError("Required field missing")
488
 
 
 
448
    if mode == "copy":
 
449
        copy = True
 
450
    elif mode == "move":
 
451
        copy = False
 
452
    else:
 
453
        raise ActionError("Invalid mode (must be 'copy' or 'move')")
489
454
    dst_local = actionpath_to_local(req, dst)
490
455
    if not os.path.isdir(dst_local):
491
456
        raise ActionError("dst is not a directory")
500
465
        # The destination is found by taking just the basename of the file
501
466
        topath = os.path.join(dst, os.path.basename(file))
502
467
        try:
503
 
            if mode == "copy":
504
 
                movefile(req, frompath, topath, True)
505
 
            elif mode == "move":
506
 
                movefile(req, frompath, topath, False)
507
 
            elif mode == "svncopy":
508
 
                svn_movefile(req, frompath, topath, True)
509
 
            elif mode == "svnmove":
510
 
                svn_movefile(req, frompath, topath, False)
511
 
            else:
512
 
                raise ActionError("Invalid mode (must be '(svn)copy' or '(svn)move')")
 
468
            movefile(req, frompath, topath, copy)
513
469
        except ActionError, message:
514
470
            # Store the error for later; we want to copy as many as possible
515
471
            if errormsg is None:
533
489
    Reads fields: 'path'
534
490
    """
535
491
    paths = fields.getlist('path')
536
 
    user = util.split_path(req.path)[0]
 
492
    user = studpath.url_to_local(req.path)[0]
537
493
    homedir = "/home/%s" % user
538
494
    if len(paths):
539
495
        paths = map(lambda path: actionpath_to_local(req, path), paths)
540
496
    else:
541
 
        paths = [studpath.to_home_path(req.path)]
 
497
        paths = [studpath.url_to_jailpaths(req.path)[2]]
542
498
 
543
499
    # Set all the dirs in home dir world browsable (o+r,o+x)
544
500
    #FIXME: Should really only do those in the direct path not all of the 
568
524
    if len(paths):
569
525
        paths = map(lambda path: actionpath_to_local(req, path), paths)
570
526
    else:
571
 
        paths = [studpath.to_home_path(req.path)]
 
527
        paths = [studpath.url_to_jailpaths(req.path)[2]]
572
528
 
573
529
    try:
574
530
        for path in paths:
665
621
    if len(paths):
666
622
        paths = map(lambda path: actionpath_to_local(req, path), paths)
667
623
    else:
668
 
        paths = [studpath.to_home_path(req.path)]
 
624
        paths = [studpath.url_to_jailpaths(req.path)[2]]
669
625
 
670
626
    try:
671
627
        for path in paths:
714
670
    paths = fields.getlist('path')
715
671
    if len(paths) != 2:
716
672
        raise ActionError("usage: svncheckout url local-path")
717
 
    url = ivle.conf.svn_addr + "/" + urllib.quote(paths[0])
 
673
    url = ivle.conf.svn_addr + "/" + paths[0]
718
674
    local_path = actionpath_to_local(req, str(paths[1]))
719
675
    try:
720
676
        svnclient.callback_get_login = get_login
739
695
def action_svnrepostat(req, fields):
740
696
    """Discovers whether a path exists in a repo under the IVLE SVN root.
741
697
 
742
 
    If it does exist, returns a dict containing its metadata.
743
 
 
744
698
    Reads fields: 'path'
745
699
    """
746
700
    path = fields.getfirst('path')
747
701
    url = ivle.conf.svn_addr + "/" + path
748
 
    svnclient.exception_style = 1
 
702
    svnclient.exception_style = 1 
749
703
 
750
704
    try:
751
705
        svnclient.callback_get_login = get_login
752
 
        info = svnclient.info2(url,
753
 
            revision=pysvn.Revision(pysvn.opt_revision_kind.head))[0][1]
754
 
        return {'svnrevision': info['rev'].number
755
 
                  if info['rev'] and
756
 
                     info['rev'].kind == pysvn.opt_revision_kind.number
757
 
                  else None}
 
706
        svnclient.info2(url)
758
707
    except pysvn.ClientError, e:
759
708
        # Error code 170000 means ENOENT in this revision.
760
709
        if e[1][0][1] == 170000:
761
710
            raise util.IVLEError(404, 'The specified repository path does not exist')
762
711
        else:
763
712
            raise ActionError(str(e[0]))
764
 
            
765
713
 
766
714
# Table of all action functions #
767
715
# Each function has the interface f(req, fields).