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

« back to all changes in this revision

Viewing changes to lib/fileservice_lib/action.py

  • Committer: dcoles
  • Date: 2008-02-25 02:26:39 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:562
Added new app: Diff (SVN diff application)
setup.py: Added diffservice script to jail scripts

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
 
#
69
65
# The differences between putfile and putfiles are:
70
66
# * putfile can only accept a single file.
71
67
# * putfile can accept string data, doesn't have to be a file upload.
72
68
# * putfile ignores the upload filename, the entire filename is specified on
73
69
#       path. putfiles calls files after the name on the user's machine.
74
70
#
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
 
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
78
92
#               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.
82
93
#
83
94
# Subversion actions.
84
95
# action=svnadd: Add an existing file(s) to version control.
285
296
    topath = fields.getfirst('to')
286
297
    movefile(req, frompath, topath)
287
298
 
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
 
 
303
299
def action_putfile(req, fields):
304
300
    """Writes data to a file, overwriting it if it exists and creating it if
305
301
    it doesn't.
310
306
    # Important: Data is "None" if the file submitted is empty.
311
307
    path = fields.getfirst('path')
312
308
    data = fields.getfirst('data')
313
 
    if path is None:
 
309
    if path is None or data is None:
314
310
        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 = ""
319
311
    path = actionpath_to_local(req, path)
320
312
 
321
313
    if data is not None:
387
379
            raise ActionError(
388
380
                "Could not write to one or more of the target files")
389
381
 
 
382
def action_copy_or_cut(req, fields, mode):
 
383
    """Marks specified files on the clipboard, stored in the
 
384
    browser session. Sets clipboard for either a cut or copy operation
 
385
    as specified.
 
386
 
 
387
    Reads fields: 'path'
 
388
    """
 
389
    # The clipboard object created conforms to the JSON clipboard
 
390
    # specification given at the top of listing.py.
 
391
    # Note that we do not check for the existence of files here. That is done
 
392
    # in the paste operation.
 
393
    files = fields.getlist('path')
 
394
    clipboard = { "mode" : mode, "base" : req.path, "files" : files }
 
395
    session = req.get_session()
 
396
    session['clipboard'] = clipboard
 
397
    session.save()
 
398
 
 
399
def action_copy(req, fields):
 
400
    """Marks specified files on the clipboard, stored in the
 
401
    browser session. Sets clipboard for a "copy" action.
 
402
 
 
403
    Reads fields: 'path'
 
404
    """
 
405
    action_copy_or_cut(req, fields, "copy")
 
406
 
 
407
def action_cut(req, fields):
 
408
    """Marks specified files on the clipboard, stored in the
 
409
    browser session. Sets clipboard for a "cut" action.
 
410
 
 
411
    Reads fields: 'path'
 
412
    """
 
413
    action_copy_or_cut(req, fields, "cut")
 
414
 
390
415
def action_paste(req, fields):
391
 
    """Performs the copy or move action with the files specified.
392
 
    Copies/moves the files to the specified directory.
 
416
    """Performs the copy or move action with the files stored on
 
417
    the clipboard in the browser session. Copies/moves the files
 
418
    to the specified directory. Clears the clipboard.
393
419
 
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.
 
420
    Reads fields: 'path'
400
421
    """
401
422
    errormsg = None
402
423
 
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:
 
424
    todir = fields.getfirst('path')
 
425
    if todir is None:
408
426
        raise ActionError("Required field missing")
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")
 
427
    todir_local = actionpath_to_local(req, todir)
 
428
    if not os.path.isdir(todir_local):
 
429
        raise ActionError("Target is not a directory")
 
430
 
 
431
    session = req.get_session()
 
432
    try:
 
433
        clipboard = session['clipboard']
 
434
        files = clipboard['files']
 
435
        base = clipboard['base']
 
436
        if clipboard['mode'] == "copy":
 
437
            copy = True
 
438
        else:
 
439
            copy = False
 
440
    except KeyError:
 
441
        raise ActionError("Clipboard was empty")
418
442
 
419
443
    errorfiles = []
420
444
    for file in files:
421
445
        # The source must not be interpreted as relative to req.path
422
446
        # Add a slash (relative to top-level)
423
 
        if src[:1] != '/':
424
 
            src = '/' + src
425
 
        frompath = os.path.join(src, file)
 
447
        frompath = os.sep + os.path.join(base, file)
426
448
        # The destination is found by taking just the basename of the file
427
 
        topath = os.path.join(dst, os.path.basename(file))
 
449
        topath = os.path.join(todir, os.path.basename(file))
428
450
        try:
429
451
            movefile(req, frompath, topath, copy)
430
452
        except ActionError, message:
437
459
            # Add this file to errorfiles; it will be put back on the
438
460
            # clipboard for possible future pasting.
439
461
            errorfiles.append(file)
440
 
    if errormsg is not None:
 
462
    # If errors occured, augment the clipboard and raise ActionError
 
463
    if len(errorfiles) > 0:
 
464
        clipboard['files'] = errorfiles
 
465
        session['clipboard'] = clipboard
 
466
        session.save()
441
467
        raise ActionError(errormsg)
442
468
 
443
 
    # XXX errorfiles contains a list of files that couldn't be pasted.
444
 
    # we currently do nothing with this.
 
469
    # Success: Clear the clipboard
 
470
    del session['clipboard']
 
471
    session.save()
445
472
 
446
473
def action_svnadd(req, fields):
447
474
    """Performs a "svn add" to each file specified.
492
519
    Reads fields: 'path'
493
520
    """
494
521
    paths = fields.getlist('path')
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]]
 
522
    paths = map(lambda path: actionpath_to_local(req, path), paths)
499
523
 
500
524
    try:
501
525
        for path in paths:
555
579
actions_table = {
556
580
    "remove" : action_remove,
557
581
    "move" : action_move,
558
 
    "mkdir" : action_mkdir,
559
582
    "putfile" : action_putfile,
560
583
    "putfiles" : action_putfiles,
 
584
 
 
585
    "copy" : action_copy,
 
586
    "cut" : action_cut,
561
587
    "paste" : action_paste,
562
588
 
563
589
    "svnadd" : action_svnadd,