~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-02-27 05:07:09 UTC
  • Revision ID: grantw@unimelb.edu.au-20090227050709-k16kvhyl50nzjbwm
Subject URLs now contain the short name (eg. info1) rather than the code
(eg. 600151).

Show diffs side-by-side

added added

removed removed

Lines of Context:
91
91
# action=svnupdate: Bring a file up to date with the head revision.
92
92
#       path:   The path to the file to be updated. Only one file may be
93
93
#               specified.
94
 
#       revision: The revision number to update to. If not provided this
95
 
#               defaults to HEAD.
96
94
#
97
95
# action=svnpublish: Set the "published" flag on a file to True.
98
96
#       path:   The path to the file to be published. Can be specified
121
119
#       path:   The path to the directory to be checked (under the IVLE
122
120
#               repository base).
123
121
#
124
 
# action=svncleanup: Recursively clean up the working copy, removing locks,
125
 
#   resuming unfinished operations, etc.
126
 
#       path:   The path to the directory to be cleaned
127
 
#
128
122
# TODO: Implement the following actions:
129
123
#   svnupdate (done?)
130
124
# TODO: Implement ZIP unpacking in putfiles (done?).
137
131
import os
138
132
import cStringIO
139
133
import shutil
140
 
import urllib
141
134
 
142
135
import pysvn
143
136
 
144
137
from ivle import (util, studpath, zip)
145
138
from ivle.fileservice_lib.exceptions import WillNotOverwrite
146
139
import ivle.conf
147
 
import ivle.svn
148
 
 
149
 
# Make a Subversion client object (which will log in with this user's
150
 
# credentials, upon request)
151
 
svnclient = ivle.svn.create_auth_svn_client(username=ivle.conf.login,
152
 
                                            password=ivle.conf.svn_pass)
 
140
 
 
141
 
 
142
def get_login(_realm, existing_login, _may_save):
 
143
    """Callback function used by pysvn for authentication.
 
144
    realm, existing_login, _may_save: The 3 arguments passed by pysvn to
 
145
        callback_get_login.
 
146
        The following has been determined empirically, not from docs:
 
147
        existing_login will be the name of the user who owns the process on
 
148
        the first attempt, "" on subsequent attempts. We use this fact.
 
149
    """
 
150
    # Only provide credentials on the _first_ attempt.
 
151
    # If we're being asked again, then it means the credentials failed for
 
152
    # some reason and we should just fail. (This is not desirable, but it's
 
153
    # better than being asked an infinite number of times).
 
154
    return (existing_login != "", str(ivle.conf.login),
 
155
                                  str(ivle.conf.svn_pass), True)
 
156
 
 
157
# Make a Subversion client object
 
158
svnclient = pysvn.Client()
 
159
svnclient.callback_get_login = get_login
153
160
svnclient.exception_style = 0               # Simple (string) exceptions
154
161
 
155
162
DEFAULT_LOGMESSAGE = "No log message supplied."
190
197
    except KeyError:
191
198
        # Default, just send an error but then continue
192
199
        raise ActionError("Unknown action")
193
 
    return action(req, fields)
 
200
    action(req, fields)
194
201
 
195
202
def actionpath_to_urlpath(req, path):
196
203
    """Determines the URL path (relative to the student home) upon which the
221
228
 
222
229
    Does not mutate req.
223
230
    """
224
 
    r = studpath.to_home_path(actionpath_to_urlpath(req, path))
 
231
    (_, _, r) = studpath.url_to_jailpaths(actionpath_to_urlpath(req, path))
225
232
    if r is None:
226
233
        raise ActionError("Invalid path")
227
234
    return r
413
420
    for datum in data:
414
421
        # Each of the uploaded files
415
422
        filepath = os.path.join(path, datum.filename)
416
 
        filepath_local = studpath.to_home_path(filepath)
 
423
        (_, _, filepath_local) = studpath.url_to_jailpaths(filepath)
417
424
        if os.path.isdir(filepath_local):
418
425
            raise ActionError("A directory already exists "
419
426
                    + "with that name")
429
436
            # filename)
430
437
            try:
431
438
                # First get the entire path (within jail)
432
 
                abspath = studpath.to_home_path(path)
 
439
                _, _, abspath = studpath.url_to_jailpaths(path)
433
440
                abspath = os.path.join(os.sep, abspath)
434
441
                zip.unzip(abspath, filedata)
435
442
            except (OSError, IOError):
438
445
                raise ActionError("File '" + e.filename + "' already exists.")
439
446
        else:
440
447
            # Not a zip file
441
 
            filepath_local = studpath.to_home_path(filepath)
 
448
            (_, _, filepath_local) = studpath.url_to_jailpaths(filepath)
442
449
            if filepath_local is None:
443
450
                raise ActionError("Invalid path")
444
451
 
525
532
    Reads fields: 'path'
526
533
    """
527
534
    paths = fields.getlist('path')
528
 
    user = util.split_path(req.path)[0]
 
535
    user = studpath.url_to_local(req.path)[0]
529
536
    homedir = "/home/%s" % user
530
537
    if len(paths):
531
538
        paths = map(lambda path: actionpath_to_local(req, path), paths)
532
539
    else:
533
 
        paths = [studpath.to_home_path(req.path)]
 
540
        paths = [studpath.url_to_jailpaths(req.path)[2]]
534
541
 
535
542
    # Set all the dirs in home dir world browsable (o+r,o+x)
536
543
    #FIXME: Should really only do those in the direct path not all of the 
560
567
    if len(paths):
561
568
        paths = map(lambda path: actionpath_to_local(req, path), paths)
562
569
    else:
563
 
        paths = [studpath.to_home_path(req.path)]
 
570
        paths = [studpath.url_to_jailpaths(req.path)[2]]
564
571
 
565
572
    try:
566
573
        for path in paths:
603
610
def action_svnupdate(req, fields):
604
611
    """Performs a "svn update" to each file specified.
605
612
 
606
 
    Reads fields: 'path' and 'revision'
 
613
    Reads fields: 'path'
607
614
    """
608
615
    path = fields.getfirst('path')
609
 
    revision = fields.getfirst('revision')
610
616
    if path is None:
611
617
        raise ActionError("Required field missing")
612
 
    if revision is None:
613
 
        revision = pysvn.Revision( pysvn.opt_revision_kind.head )
614
 
    else:
615
 
        try:
616
 
            revision = pysvn.Revision(pysvn.opt_revision_kind.number,
617
 
                    int(revision))
618
 
        except ValueError, e:
619
 
            raise ActionError("Bad revision number: '%s'"%revision,)
620
618
    path = actionpath_to_local(req, path)
621
619
 
622
620
    try:
623
 
        svnclient.update(path, recurse=True, revision=revision)
 
621
        svnclient.update(path, recurse=True)
624
622
    except pysvn.ClientError, e:
625
623
        raise ActionError(str(e))
626
624
 
666
664
    if len(paths):
667
665
        paths = map(lambda path: actionpath_to_local(req, path), paths)
668
666
    else:
669
 
        paths = [studpath.to_home_path(req.path)]
 
667
        paths = [studpath.url_to_jailpaths(req.path)[2]]
670
668
 
671
669
    try:
672
670
        for path in paths:
715
713
    paths = fields.getlist('path')
716
714
    if len(paths) != 2:
717
715
        raise ActionError("usage: svncheckout url local-path")
718
 
    url = ivle.conf.svn_addr + "/" + urllib.quote(paths[0])
 
716
    url = ivle.conf.svn_addr + "/" + paths[0]
719
717
    local_path = actionpath_to_local(req, str(paths[1]))
720
718
    try:
 
719
        svnclient.callback_get_login = get_login
721
720
        svnclient.checkout(url, local_path, recurse=True)
722
721
    except pysvn.ClientError, e:
723
722
        raise ActionError(str(e))
729
728
    """
730
729
    path = fields.getfirst('path')
731
730
    logmsg = fields.getfirst('logmsg')
732
 
    url = ivle.conf.svn_addr + "/" + urllib.quote(path)
 
731
    url = ivle.conf.svn_addr + "/" + path
733
732
    try:
 
733
        svnclient.callback_get_login = get_login
734
734
        svnclient.mkdir(url, log_message=logmsg)
735
735
    except pysvn.ClientError, e:
736
736
        raise ActionError(str(e))
738
738
def action_svnrepostat(req, fields):
739
739
    """Discovers whether a path exists in a repo under the IVLE SVN root.
740
740
 
741
 
    If it does exist, returns a dict containing its metadata.
742
 
 
743
741
    Reads fields: 'path'
744
742
    """
745
743
    path = fields.getfirst('path')
746
 
    url = ivle.conf.svn_addr + "/" + urllib.quote(path)
747
 
    svnclient.exception_style = 1
 
744
    url = ivle.conf.svn_addr + "/" + path
 
745
    svnclient.exception_style = 1 
748
746
 
749
747
    try:
750
 
        info = svnclient.info2(url,
751
 
            revision=pysvn.Revision(pysvn.opt_revision_kind.head))[0][1]
752
 
        return {'svnrevision': info['rev'].number
753
 
                  if info['rev'] and
754
 
                     info['rev'].kind == pysvn.opt_revision_kind.number
755
 
                  else None}
 
748
        svnclient.callback_get_login = get_login
 
749
        svnclient.info2(url)
756
750
    except pysvn.ClientError, e:
757
751
        # Error code 170000 means ENOENT in this revision.
758
752
        if e[1][0][1] == 170000:
759
753
            raise util.IVLEError(404, 'The specified repository path does not exist')
760
754
        else:
761
755
            raise ActionError(str(e[0]))
762
 
 
763
 
 
764
 
def action_svncleanup(req, fields):
765
 
    """Recursively clean up the working copy, removing locks, resuming 
766
 
    unfinished operations, etc.
767
 
        path:   The path to be cleaned"""
768
 
 
769
 
    path = fields.getfirst('path')
770
 
    if path is None:
771
 
        raise ActionError("Required field missing")
772
 
    path = actionpath_to_local(req, path)
773
 
 
774
 
    try:
775
 
        svnclient.cleanup(path)
776
 
    except pysvn.ClientError, e:
777
 
        raise ActionError(str(e))
778
 
 
 
756
            
779
757
 
780
758
# Table of all action functions #
781
759
# Each function has the interface f(req, fields).
801
779
    "svncheckout" : action_svncheckout,
802
780
    "svnrepomkdir" : action_svnrepomkdir,
803
781
    "svnrepostat" : action_svnrepostat,
804
 
    "svncleanup" : action_svncleanup,
805
782
}