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

« back to all changes in this revision

Viewing changes to lib/fileservice_lib/action.py

  • Committer: mattgiuca
  • Date: 2008-03-09 21:24:37 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:676
usrmgt-server: Moved SVN checkout code from activate_me into a separate
action, do_checkout, which is called by activate_me. This allows you to do
checkouts later on.

userservice: Added do_checkout action to userservice.

Show diffs side-by-side

added added

removed removed

Lines of Context:
62
62
#               will create a directory instead and unpack the ZIP file
63
63
#               into it.
64
64
#
 
65
# action=mkdir: Create a directory. The parent dir must exist.
 
66
#       path:   The path to a file which does not exist, but whose parent
 
67
#               does. The dir will be made with this name.
 
68
#
65
69
# The differences between putfile and putfiles are:
66
70
# * putfile can only accept a single file.
67
71
# * putfile can accept string data, doesn't have to be a file upload.
68
72
# * putfile ignores the upload filename, the entire filename is specified on
69
73
#       path. putfiles calls files after the name on the user's machine.
70
74
#
71
 
# Clipboard-based actions. Cut/copy/paste work in the same way as modern
72
 
# file browsers, by keeping a server-side clipboard of files that have been
73
 
# cut and copied. The clipboard is stored in the session data, so it persists
74
 
# across navigation, tabs and browser windows, but not across browser
75
 
# sessions.
76
 
77
 
# action=copy: Write file(s) to the session-based clipboard. Overrides any
78
 
#               existing clipboard data. Does not actually copy the file.
79
 
#               The files are physically copied when the clipboard is pasted.
80
 
#       path:   The path to the file or directory to copy. Can be specified
81
 
#               multiple times.
82
 
83
 
# action=cut: Write file(s) to the session-based clipboard. Overrides any
84
 
#               existing clipboard data. Does not actually move the file.
85
 
#               The files are physically moved when the clipboard is pasted.
86
 
#       path:   The path to the file or directory to cut. Can be specified
87
 
#               multiple times.
88
 
89
 
# action=paste: Copy or move the files stored in the clipboard. Clears the
90
 
#               clipboard. The files are copied or moved to a specified dir.
91
 
#       path:   The path to the DIRECTORY to paste the files to. Must not
 
75
# action=paste: Copy or move the files to a specified dir.
 
76
#       src:    The path to the DIRECTORY to get the files from (relative).
 
77
#       dst:    The path to the DIRECTORY to paste the files to. Must not
92
78
#               be a file.
 
79
#       mode:   'copy' or 'move'
 
80
#       file:   File to be copied or moved, relative to src, to a destination
 
81
#               relative to dst. Can be specified multiple times.
93
82
#
94
83
# Subversion actions.
95
84
# action=svnadd: Add an existing file(s) to version control.
119
108
#               recursively.
120
109
#       logmsg: Text of the log message. Optional. There is a default log
121
110
#               message if unspecified.
 
111
# action=svncheckout: Checkout a file/directory from the repository.
 
112
#       path:   The [repository] path to the file or directory to be
 
113
#               checked out.
122
114
123
115
# TODO: Implement the following actions:
124
116
#   putfiles, svnrevert, svnupdate, svncommit
136
128
import pysvn
137
129
 
138
130
from common import (util, studpath, zip)
 
131
import conf
 
132
 
 
133
def get_login(_realm, _username, _may_save):
 
134
    """Return the subversion credentials for the user."""
 
135
    return (True, conf.login, conf.passwd, True)
139
136
 
140
137
# Make a Subversion client object
141
138
svnclient = pysvn.Client()
 
139
svnclient.callback_get_login = get_login
142
140
 
143
141
DEFAULT_LOGMESSAGE = "No log message supplied."
144
142
 
287
285
    topath = fields.getfirst('to')
288
286
    movefile(req, frompath, topath)
289
287
 
 
288
def action_mkdir(req, fields):
 
289
    """Creates a directory with the given path.
 
290
    Reads fields: 'path'
 
291
    """
 
292
    path = fields.getfirst('path')
 
293
    if path is None:
 
294
        raise ActionError("Required field missing")
 
295
    path = actionpath_to_local(req, path)
 
296
 
 
297
    # Create the directory
 
298
    try:
 
299
        os.mkdir(path)
 
300
    except OSError:
 
301
        raise ActionError("Could not create directory")
 
302
 
290
303
def action_putfile(req, fields):
291
304
    """Writes data to a file, overwriting it if it exists and creating it if
292
305
    it doesn't.
297
310
    # Important: Data is "None" if the file submitted is empty.
298
311
    path = fields.getfirst('path')
299
312
    data = fields.getfirst('data')
300
 
    if path is None or data is None:
 
313
    if path is None:
301
314
        raise ActionError("Required field missing")
 
315
    if data is None:
 
316
        # Workaround - field reader treats "" as None, so this is the only
 
317
        # way to allow blank file uploads
 
318
        data = ""
302
319
    path = actionpath_to_local(req, path)
303
320
 
304
321
    if data is not None:
370
387
            raise ActionError(
371
388
                "Could not write to one or more of the target files")
372
389
 
373
 
def action_copy_or_cut(req, fields, mode):
374
 
    """Marks specified files on the clipboard, stored in the
375
 
    browser session. Sets clipboard for either a cut or copy operation
376
 
    as specified.
377
 
 
378
 
    Reads fields: 'path'
379
 
    """
380
 
    # The clipboard object created conforms to the JSON clipboard
381
 
    # specification given at the top of listing.py.
382
 
    # Note that we do not check for the existence of files here. That is done
383
 
    # in the paste operation.
384
 
    files = fields.getlist('path')
385
 
    clipboard = { "mode" : mode, "base" : req.path, "files" : files }
386
 
    session = req.get_session()
387
 
    session['clipboard'] = clipboard
388
 
    session.save()
389
 
 
390
 
def action_copy(req, fields):
391
 
    """Marks specified files on the clipboard, stored in the
392
 
    browser session. Sets clipboard for a "copy" action.
393
 
 
394
 
    Reads fields: 'path'
395
 
    """
396
 
    action_copy_or_cut(req, fields, "copy")
397
 
 
398
 
def action_cut(req, fields):
399
 
    """Marks specified files on the clipboard, stored in the
400
 
    browser session. Sets clipboard for a "cut" action.
401
 
 
402
 
    Reads fields: 'path'
403
 
    """
404
 
    action_copy_or_cut(req, fields, "cut")
405
 
 
406
390
def action_paste(req, fields):
407
 
    """Performs the copy or move action with the files stored on
408
 
    the clipboard in the browser session. Copies/moves the files
409
 
    to the specified directory. Clears the clipboard.
 
391
    """Performs the copy or move action with the files specified.
 
392
    Copies/moves the files to the specified directory.
410
393
 
411
 
    Reads fields: 'path'
 
394
    Reads fields: 'src', 'dst', 'mode', 'file' (multiple).
 
395
    src: Base path that all the files are relative to (source).
 
396
    dst: Destination path to paste into.
 
397
    mode: 'copy' or 'move'.
 
398
    file: (Multiple) Files relative to base, which will be copied
 
399
        or moved to new locations relative to path.
412
400
    """
413
401
    errormsg = None
414
402
 
415
 
    todir = fields.getfirst('path')
416
 
    if todir is None:
 
403
    dst = fields.getfirst('dst')
 
404
    src = fields.getfirst('src')
 
405
    mode = fields.getfirst('mode')
 
406
    files = fields.getlist('file')
 
407
    if dst is None or src is None or mode is None:
417
408
        raise ActionError("Required field missing")
418
 
    todir_local = actionpath_to_local(req, todir)
419
 
    if not os.path.isdir(todir_local):
420
 
        raise ActionError("Target is not a directory")
421
 
 
422
 
    session = req.get_session()
423
 
    try:
424
 
        clipboard = session['clipboard']
425
 
        files = clipboard['files']
426
 
        base = clipboard['base']
427
 
        if clipboard['mode'] == "copy":
428
 
            copy = True
429
 
        else:
430
 
            copy = False
431
 
    except KeyError:
432
 
        raise ActionError("Clipboard was empty")
 
409
    if mode == "copy":
 
410
        copy = True
 
411
    elif mode == "move":
 
412
        copy = False
 
413
    else:
 
414
        raise ActionError("Invalid mode (must be 'copy' or 'move')")
 
415
    dst_local = actionpath_to_local(req, dst)
 
416
    if not os.path.isdir(dst_local):
 
417
        raise ActionError("dst is not a directory")
433
418
 
434
419
    errorfiles = []
435
420
    for file in files:
436
421
        # The source must not be interpreted as relative to req.path
437
422
        # Add a slash (relative to top-level)
438
 
        frompath = os.sep + os.path.join(base, file)
 
423
        if src[:1] != '/':
 
424
            src = '/' + src
 
425
        frompath = os.path.join(src, file)
439
426
        # The destination is found by taking just the basename of the file
440
 
        topath = os.path.join(todir, os.path.basename(file))
 
427
        topath = os.path.join(dst, os.path.basename(file))
441
428
        try:
442
429
            movefile(req, frompath, topath, copy)
443
430
        except ActionError, message:
450
437
            # Add this file to errorfiles; it will be put back on the
451
438
            # clipboard for possible future pasting.
452
439
            errorfiles.append(file)
453
 
    # If errors occured, augment the clipboard and raise ActionError
454
 
    if len(errorfiles) > 0:
455
 
        clipboard['files'] = errorfiles
456
 
        session['clipboard'] = clipboard
457
 
        session.save()
 
440
    if errormsg is not None:
458
441
        raise ActionError(errormsg)
459
442
 
460
 
    # Success: Clear the clipboard
461
 
    del session['clipboard']
462
 
    session.save()
 
443
    # XXX errorfiles contains a list of files that couldn't be pasted.
 
444
    # we currently do nothing with this.
463
445
 
464
446
def action_svnadd(req, fields):
465
447
    """Performs a "svn add" to each file specified.
510
492
    Reads fields: 'path'
511
493
    """
512
494
    paths = fields.getlist('path')
513
 
    paths = map(lambda path: actionpath_to_local(req, path), paths)
 
495
    if len(paths):
 
496
        paths = map(lambda path: actionpath_to_local(req, path), paths)
 
497
    else:
 
498
        paths = [studpath.url_to_jailpaths(req.path)[2]]
514
499
 
515
500
    try:
516
501
        for path in paths:
548
533
    except pysvn.ClientError:
549
534
        raise ActionError("One or more files could not be committed")
550
535
 
 
536
def action_svncheckout(req, fields):
 
537
    """Performs a "svn checkout" of each path specified.
 
538
 
 
539
    Reads fields: 'path'    (multiple)
 
540
    """
 
541
    paths = fields.getlist('path')
 
542
    if len(paths) != 2:
 
543
        raise ActionError("usage: svncheckout url local-path")
 
544
    url = conf.svn_addr + "/" + login + "/" + paths[0]
 
545
    local_path = actionpath_to_local(req, str(paths[1]))
 
546
    try:
 
547
        svnclient.callback_get_login = get_login
 
548
        svnclient.checkout(url, local_path, recurse=True)
 
549
    except pysvn.ClientError:
 
550
        raise ActionError("One or more files could not be checked out")
 
551
 
551
552
# Table of all action functions #
552
553
# Each function has the interface f(req, fields).
553
554
 
554
555
actions_table = {
555
556
    "remove" : action_remove,
556
557
    "move" : action_move,
 
558
    "mkdir" : action_mkdir,
557
559
    "putfile" : action_putfile,
558
560
    "putfiles" : action_putfiles,
559
 
 
560
 
    "copy" : action_copy,
561
 
    "cut" : action_cut,
562
561
    "paste" : action_paste,
563
562
 
564
563
    "svnadd" : action_svnadd,
567
566
    "svnpublish" : action_svnpublish,
568
567
    "svnunpublish" : action_svnunpublish,
569
568
    "svncommit" : action_svncommit,
 
569
    "svncheckout" : action_svncheckout,
570
570
}