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

« back to all changes in this revision

Viewing changes to ivle/fileservice_lib/action.py

  • Committer: Matt Giuca
  • Date: 2009-05-19 03:59:52 UTC
  • mto: This revision was merged to the branch mainline in revision 1322.
  • Revision ID: matt.giuca@gmail.com-20090519035952-gzyj2sszy0p0pe9i
More headings and files!

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.
 
94
#
 
95
# action=svnpublish: Set the "published" flag on a file to True.
 
96
#       path:   The path to the file to be published. Can be specified
 
97
#               multiple times.
 
98
#
 
99
# action=svnunpublish: Set the "published" flag on a file to False.
 
100
#       path:   The path to the file to be unpublished. Can be specified
 
101
#               multiple times.
96
102
#
97
103
# action=svncommit: Commit a file(s) or directory(s) to the repository.
98
104
#       path:   The path to the file or directory to be committed. Can be
113
119
#       path:   The path to the directory to be checked (under the IVLE
114
120
#               repository base).
115
121
#
116
 
# action=svncleanup: Recursively clean up the working copy, removing locks,
117
 
#   resuming unfinished operations, etc.
118
 
#       path:   The path to the directory to be cleaned
119
 
#
120
122
# TODO: Implement the following actions:
121
123
#   svnupdate (done?)
122
124
# TODO: Implement ZIP unpacking in putfiles (done?).
136
138
from ivle import (util, studpath, zip)
137
139
from ivle.fileservice_lib.exceptions import WillNotOverwrite
138
140
import ivle.conf
139
 
import ivle.svn
140
 
 
141
 
# Make a Subversion client object (which will log in with this user's
142
 
# credentials, upon request)
143
 
svnclient = ivle.svn.create_auth_svn_client(username=ivle.conf.login,
144
 
                                            password=ivle.conf.svn_pass)
 
141
 
 
142
 
 
143
def get_login(_realm, existing_login, _may_save):
 
144
    """Callback function used by pysvn for authentication.
 
145
    realm, existing_login, _may_save: The 3 arguments passed by pysvn to
 
146
        callback_get_login.
 
147
        The following has been determined empirically, not from docs:
 
148
        existing_login will be the name of the user who owns the process on
 
149
        the first attempt, "" on subsequent attempts. We use this fact.
 
150
    """
 
151
    # Only provide credentials on the _first_ attempt.
 
152
    # If we're being asked again, then it means the credentials failed for
 
153
    # some reason and we should just fail. (This is not desirable, but it's
 
154
    # better than being asked an infinite number of times).
 
155
    return (existing_login != "", str(ivle.conf.login),
 
156
                                  str(ivle.conf.svn_pass), True)
 
157
 
 
158
# Make a Subversion client object
 
159
svnclient = pysvn.Client()
 
160
svnclient.callback_get_login = get_login
145
161
svnclient.exception_style = 0               # Simple (string) exceptions
146
162
 
147
163
DEFAULT_LOGMESSAGE = "No log message supplied."
213
229
 
214
230
    Does not mutate req.
215
231
    """
216
 
    r = studpath.to_home_path(actionpath_to_urlpath(req, path))
 
232
    (_, _, r) = studpath.url_to_jailpaths(actionpath_to_urlpath(req, path))
217
233
    if r is None:
218
234
        raise ActionError("Invalid path")
219
235
    return r
317
333
    """
318
334
    frompath = fields.getfirst('from')
319
335
    topath = fields.getfirst('to')
320
 
    svn = fields.getfirst('svn')
321
 
    if svn:
322
 
        svn_movefile(req, frompath, topath)
323
 
    else:
324
 
        movefile(req, frompath, topath)
 
336
    movefile(req, frompath, topath)
325
337
 
326
338
def action_mkdir(req, fields):
327
339
    """Creates a directory with the given path.
409
421
    for datum in data:
410
422
        # Each of the uploaded files
411
423
        filepath = os.path.join(path, datum.filename)
412
 
        filepath_local = studpath.to_home_path(filepath)
 
424
        (_, _, filepath_local) = studpath.url_to_jailpaths(filepath)
413
425
        if os.path.isdir(filepath_local):
414
426
            raise ActionError("A directory already exists "
415
427
                    + "with that name")
425
437
            # filename)
426
438
            try:
427
439
                # First get the entire path (within jail)
428
 
                abspath = studpath.to_home_path(path)
 
440
                _, _, abspath = studpath.url_to_jailpaths(path)
429
441
                abspath = os.path.join(os.sep, abspath)
430
442
                zip.unzip(abspath, filedata)
431
443
            except (OSError, IOError):
434
446
                raise ActionError("File '" + e.filename + "' already exists.")
435
447
        else:
436
448
            # Not a zip file
437
 
            filepath_local = studpath.to_home_path(filepath)
 
449
            (_, _, filepath_local) = studpath.url_to_jailpaths(filepath)
438
450
            if filepath_local is None:
439
451
                raise ActionError("Invalid path")
440
452
 
521
533
    Reads fields: 'path'
522
534
    """
523
535
    paths = fields.getlist('path')
524
 
    user = util.split_path(req.path)[0]
 
536
    user = studpath.url_to_local(req.path)[0]
525
537
    homedir = "/home/%s" % user
526
538
    if len(paths):
527
539
        paths = map(lambda path: actionpath_to_local(req, path), paths)
528
540
    else:
529
 
        paths = [studpath.to_home_path(req.path)]
 
541
        paths = [studpath.url_to_jailpaths(req.path)[2]]
530
542
 
531
543
    # Set all the dirs in home dir world browsable (o+r,o+x)
532
544
    #FIXME: Should really only do those in the direct path not all of the 
556
568
    if len(paths):
557
569
        paths = map(lambda path: actionpath_to_local(req, path), paths)
558
570
    else:
559
 
        paths = [studpath.to_home_path(req.path)]
 
571
        paths = [studpath.url_to_jailpaths(req.path)[2]]
560
572
 
561
573
    try:
562
574
        for path in paths:
576
588
    Reads fields: 'path' (multiple)
577
589
    """
578
590
    paths = fields.getlist('path')
579
 
    paths = map(lambda path: actionpath_to_local(req, path).decode('utf-8'),
580
 
                paths)
 
591
    paths = map(lambda path: actionpath_to_local(req, path), paths)
581
592
 
582
593
    try:
583
594
        svnclient.add(paths, recurse=True, force=True)
590
601
    Reads fields: 'path' (multiple)
591
602
    """
592
603
    paths = fields.getlist('path')
593
 
    paths = map(lambda path: actionpath_to_local(req, path).decode('utf-8'),
594
 
                paths)
 
604
    paths = map(lambda path: actionpath_to_local(req, path), paths)
595
605
 
596
606
    try:
597
607
        svnclient.remove(paths, force=True)
601
611
def action_svnupdate(req, fields):
602
612
    """Performs a "svn update" to each file specified.
603
613
 
604
 
    Reads fields: 'path' and 'revision'
 
614
    Reads fields: 'path'
605
615
    """
606
616
    path = fields.getfirst('path')
607
 
    revision = fields.getfirst('revision')
608
617
    if path is None:
609
618
        raise ActionError("Required field missing")
610
 
    if revision is None:
611
 
        revision = pysvn.Revision( pysvn.opt_revision_kind.head )
612
 
    else:
613
 
        try:
614
 
            revision = pysvn.Revision(pysvn.opt_revision_kind.number,
615
 
                    int(revision))
616
 
        except ValueError, e:
617
 
            raise ActionError("Bad revision number: '%s'"%revision,)
618
 
    path = actionpath_to_local(req, path).decode('utf-8')
 
619
    path = actionpath_to_local(req, path)
619
620
 
620
621
    try:
621
 
        svnclient.update(path, recurse=True, revision=revision)
 
622
        svnclient.update(path, recurse=True)
622
623
    except pysvn.ClientError, e:
623
624
        raise ActionError(str(e))
624
625
 
630
631
    path = fields.getfirst('path')
631
632
    if path is None:
632
633
        raise ActionError("Required field missing")
633
 
    path = actionpath_to_local(req, path).decode('utf-8')
 
634
    path = actionpath_to_local(req, path)
634
635
 
635
636
    try:
636
637
        svnclient.resolved(path, recurse=True)
643
644
    Reads fields: 'path' (multiple)
644
645
    """
645
646
    paths = fields.getlist('path')
646
 
    paths = map(lambda path: actionpath_to_local(req, path).decode('utf-8'),
647
 
                paths)
 
647
    paths = map(lambda path: actionpath_to_local(req, path), paths)
648
648
 
649
649
    try:
650
650
        svnclient.revert(paths, recurse=True)
651
651
    except pysvn.ClientError, e:
652
652
        raise ActionError(str(e))
653
653
 
 
654
def action_svnpublish(req, fields):
 
655
    """Sets svn property "ivle:published" on each file specified.
 
656
    Should only be called on directories (only effective on directories
 
657
    anyway).
 
658
 
 
659
    Reads fields: 'path'
 
660
 
 
661
    XXX Currently unused by the client (calls action_publish instead, which
 
662
    has a completely different publishing model).
 
663
    """
 
664
    paths = fields.getlist('path')
 
665
    if len(paths):
 
666
        paths = map(lambda path: actionpath_to_local(req, path), paths)
 
667
    else:
 
668
        paths = [studpath.url_to_jailpaths(req.path)[2]]
 
669
 
 
670
    try:
 
671
        for path in paths:
 
672
            # Note: Property value doesn't matter
 
673
            svnclient.propset("ivle:published", "", path, recurse=False)
 
674
    except pysvn.ClientError, e:
 
675
        raise ActionError("Directory could not be published")
 
676
 
 
677
def action_svnunpublish(req, fields):
 
678
    """Deletes svn property "ivle:published" on each file specified.
 
679
 
 
680
    Reads fields: 'path'
 
681
 
 
682
    XXX Currently unused by the client (calls action_unpublish instead, which
 
683
    has a completely different publishing model).
 
684
    """
 
685
    paths = fields.getlist('path')
 
686
    paths = map(lambda path: actionpath_to_local(req, path), paths)
 
687
 
 
688
    try:
 
689
        for path in paths:
 
690
            svnclient.propdel("ivle:published", path, recurse=False)
 
691
    except pysvn.ClientError, e:
 
692
        raise ActionError("Directory could not be unpublished")
 
693
 
654
694
def action_svncommit(req, fields):
655
695
    """Performs a "svn commit" to each file specified.
656
696
 
657
697
    Reads fields: 'path' (multiple), 'logmsg' (optional)
658
698
    """
659
699
    paths = fields.getlist('path')
660
 
    if len(paths):
661
 
        paths = map(lambda path:actionpath_to_local(req,path).decode('utf-8'),
662
 
                    paths)
663
 
    else:
664
 
        paths = [studpath.to_home_path(req.path).decode('utf-8')]
665
 
    logmsg = str(fields.getfirst('logmsg',
666
 
                 DEFAULT_LOGMESSAGE)).decode('utf-8')
 
700
    paths = map(lambda path: actionpath_to_local(req, str(path)), paths)
 
701
    logmsg = str(fields.getfirst('logmsg', DEFAULT_LOGMESSAGE))
667
702
    if logmsg == '': logmsg = DEFAULT_LOGMESSAGE
668
703
 
669
704
    try:
681
716
        raise ActionError("usage: svncheckout url local-path")
682
717
    url = ivle.conf.svn_addr + "/" + urllib.quote(paths[0])
683
718
    local_path = actionpath_to_local(req, str(paths[1]))
684
 
    url = url.decode('utf-8')
685
 
    local_path = local_path.decode('utf-8')
686
719
    try:
 
720
        svnclient.callback_get_login = get_login
687
721
        svnclient.checkout(url, local_path, recurse=True)
688
722
    except pysvn.ClientError, e:
689
723
        raise ActionError(str(e))
695
729
    """
696
730
    path = fields.getfirst('path')
697
731
    logmsg = fields.getfirst('logmsg')
698
 
    url = (ivle.conf.svn_addr + "/" + urllib.quote(path)).decode('utf-8')
 
732
    url = ivle.conf.svn_addr + "/" + path
699
733
    try:
 
734
        svnclient.callback_get_login = get_login
700
735
        svnclient.mkdir(url, log_message=logmsg)
701
736
    except pysvn.ClientError, e:
702
737
        raise ActionError(str(e))
709
744
    Reads fields: 'path'
710
745
    """
711
746
    path = fields.getfirst('path')
712
 
    url = (ivle.conf.svn_addr + "/" + urllib.quote(path)).decode('utf-8')
 
747
    url = ivle.conf.svn_addr + "/" + path
713
748
    svnclient.exception_style = 1
714
749
 
715
750
    try:
 
751
        svnclient.callback_get_login = get_login
716
752
        info = svnclient.info2(url,
717
753
            revision=pysvn.Revision(pysvn.opt_revision_kind.head))[0][1]
718
754
        return {'svnrevision': info['rev'].number
722
758
    except pysvn.ClientError, e:
723
759
        # Error code 170000 means ENOENT in this revision.
724
760
        if e[1][0][1] == 170000:
725
 
            req.status = 404
726
 
            raise ActionError('The specified repository path does not exist')
 
761
            raise util.IVLEError(404, 'The specified repository path does not exist')
727
762
        else:
728
763
            raise ActionError(str(e[0]))
729
 
 
730
 
 
731
 
def action_svncleanup(req, fields):
732
 
    """Recursively clean up the working copy, removing locks, resuming 
733
 
    unfinished operations, etc.
734
 
        path:   The path to be cleaned"""
735
 
 
736
 
    path = fields.getfirst('path')
737
 
    if path is None:
738
 
        raise ActionError("Required field missing")
739
 
    path = actionpath_to_local(req, path).decode('utf-8')
740
 
 
741
 
    try:
742
 
        svnclient.cleanup(path)
743
 
    except pysvn.ClientError, e:
744
 
        raise ActionError(str(e))
745
 
 
 
764
            
746
765
 
747
766
# Table of all action functions #
748
767
# Each function has the interface f(req, fields).
762
781
    "svnupdate" : action_svnupdate,
763
782
    "svnresolved" : action_svnresolved,
764
783
    "svnrevert" : action_svnrevert,
 
784
    "svnpublish" : action_svnpublish,
 
785
    "svnunpublish" : action_svnunpublish,
765
786
    "svncommit" : action_svncommit,
766
787
    "svncheckout" : action_svncheckout,
767
788
    "svnrepomkdir" : action_svnrepomkdir,
768
789
    "svnrepostat" : action_svnrepostat,
769
 
    "svncleanup" : action_svncleanup,
770
790
}