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

« back to all changes in this revision

Viewing changes to ivle/util.py

  • Committer: William Grant
  • Date: 2009-05-14 02:30:46 UTC
  • mfrom: (1165.3.86 submissions-admin)
  • Revision ID: grantw@unimelb.edu.au-20090514023046-ujf6ay6rf6iioz9s
Merge submissions-admin.

Offering staff can now administer projects and view their projects'
submissions. A tool is also provided to create archives of each submission.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
# Contains common utility functions.
23
23
 
24
24
import os
 
25
import sys
 
26
import stat
25
27
 
26
28
class IVLEError(Exception):
27
29
    """Legacy general IVLE exception.
94
96
    else:
95
97
        return tuple(splitpath)
96
98
 
 
99
def relpath(path, start=os.path.curdir):
 
100
    """Return a relative version of a path.
 
101
    XXX Backported from Python 2.6 posixpath.py.
 
102
    """
 
103
 
 
104
    if not path:
 
105
        raise ValueError("no path specified")
 
106
 
 
107
    start_list = os.path.abspath(start).split(os.path.sep)
 
108
    path_list = os.path.abspath(path).split(os.path.sep)
 
109
 
 
110
    # Work out how much of the filepath is shared by start and path.
 
111
    i = len(os.path.commonprefix([start_list, path_list]))
 
112
 
 
113
    rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:]
 
114
    if not rel_list:
 
115
        return os.path.curdir
 
116
    return os.path.join(*rel_list)
 
117
 
97
118
def incomplete_utf8_sequence(byteseq):
98
119
    """Calculate the completeness of a UTF-8 encoded string.
99
120
 
184
205
    """
185
206
    return dict((k, getattr(obj, k))
186
207
        for k in attrnames if not k.startswith('_'))
 
208
 
 
209
def safe_rmtree(path, ignore_errors=False, onerror=None):
 
210
    """Recursively delete a directory tree.
 
211
 
 
212
    Copied from shutil.rmtree from Python 2.6, which does not follow symbolic
 
213
    links (it is otherwise unsafe to call as root on untrusted directories; do
 
214
    not use shutil.rmtree in this case, as you may be running Python 2.5).
 
215
 
 
216
    If ignore_errors is set, errors are ignored; otherwise, if onerror
 
217
    is set, it is called to handle the error with arguments (func,
 
218
    path, exc_info) where func is os.listdir, os.remove, or os.rmdir;
 
219
    path is the argument to that function that caused it to fail; and
 
220
    exc_info is a tuple returned by sys.exc_info().  If ignore_errors
 
221
    is false and onerror is None, an exception is raised.
 
222
 
 
223
    """
 
224
    if ignore_errors:
 
225
        def onerror(*args):
 
226
            pass
 
227
    elif onerror is None:
 
228
        def onerror(*args):
 
229
            raise
 
230
    try:
 
231
        if os.path.islink(path):
 
232
            # symlinks to directories are forbidden, see bug #1669
 
233
            raise OSError("Cannot call safe_rmtree on a symbolic link")
 
234
    except OSError:
 
235
        onerror(os.path.islink, path, sys.exc_info())
 
236
        # can't continue even if onerror hook returns
 
237
        return
 
238
    names = []
 
239
    try:
 
240
        names = os.listdir(path)
 
241
    except os.error, err:
 
242
        onerror(os.listdir, path, sys.exc_info())
 
243
    for name in names:
 
244
        fullname = os.path.join(path, name)
 
245
        try:
 
246
            mode = os.lstat(fullname).st_mode
 
247
        except os.error:
 
248
            mode = 0
 
249
        if stat.S_ISDIR(mode):
 
250
            safe_rmtree(fullname, ignore_errors, onerror)
 
251
        else:
 
252
            try:
 
253
                os.remove(fullname)
 
254
            except os.error, err:
 
255
                onerror(os.remove, fullname, sys.exc_info())
 
256
    try:
 
257
        os.rmdir(path)
 
258
    except os.error:
 
259
        onerror(os.rmdir, path, sys.exc_info())