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

1079 by William Grant
Merge setup-refactor branch. This completely breaks existing installations;
1
# IVLE - Informatics Virtual Learning Environment
2
# Copyright (C) 2007-2008 The University of Melbourne
3
#
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
18
# Module: util
19
# Author: Matt Giuca
20
# Date: 12/12/2007
21
22
# Contains common utility functions.
23
24
import os
25
26
class IVLEError(Exception):
1213 by William Grant
Drop ivle.util.make_path (replaced by Request.make_path) and fix docstrings.
27
    """Legacy general IVLE exception.
28
29
    This is the old "standard" exception class for IVLE errors. It is only
30
    used in fileservice, and should not be used in any new code.
1079 by William Grant
Merge setup-refactor branch. This completely breaks existing installations;
31
    """
32
    def __init__(self, httpcode, message=None):
33
        self.httpcode = httpcode
34
        self.message = message
35
        self.args = (httpcode, message)
36
37
class IVLEJailError(Exception):
1213 by William Grant
Drop ivle.util.make_path (replaced by Request.make_path) and fix docstrings.
38
    """Exception proxying an in-jail error.
39
1079 by William Grant
Merge setup-refactor branch. This completely breaks existing installations;
40
    This exception indicates an error that occurred inside an IVLE CGI script
41
    inside the jail. It should never be raised directly - only by the 
42
    interpreter.
43
44
    Information will be retrieved from it, and then treated as a normal
45
    error.
46
    """
47
    def __init__(self, type_str, message, info):
48
        self.type_str = type_str
49
        self.message = message
50
        self.info = info
51
52
class FakeObject(object):
53
    """ A representation of an object that can't be Pickled """
54
    def __init__(self, type, name, attrib={}):
55
        self.type = type
56
        self.name = name
57
        self.attrib = attrib
58
59
    def __repr__(self):
60
        return "<Fake %s %s>"%(self.type, self.name)
61
62
def split_path(path):
63
    """Given a path, returns a tuple consisting of the top-level directory in
64
    the path, and the rest of the path. Note that both items in the tuple will
65
    NOT begin with a slash, regardless of whether the original path did. Also
66
    normalises the path.
67
68
    Always returns a pair of strings, except for one special case, in which
69
    the path is completely empty (or just a single slash). In this case the
70
    return value will be (None, ''). But still always returns a pair.
71
72
    Examples:
73
74
    >>> split_path("")
75
    (None, '')
76
    >>> split_path("/")
77
    (None, '')
78
    >>> split_path("home")
79
    ('home', '')
80
    >>> split_path("home/docs/files")
81
    ('home', 'docs/files')
82
    >>> split_path("//home/docs/files")
83
    ('', 'home/docs/files')
84
    """
85
    path = os.path.normpath(path)
86
    # Ignore the opening slash
87
    if path.startswith(os.sep):
88
        path = path[len(os.sep):]
89
    if path == '' or path == '.':
90
        return (None, '')
91
    splitpath = path.split(os.sep, 1)
92
    if len(splitpath) == 1:
93
        return (splitpath[0], '')
94
    else:
95
        return tuple(splitpath)
96
97
def incomplete_utf8_sequence(byteseq):
1213 by William Grant
Drop ivle.util.make_path (replaced by Request.make_path) and fix docstrings.
98
    """Calculate the completeness of a UTF-8 encoded string.
99
1079 by William Grant
Merge setup-refactor branch. This completely breaks existing installations;
100
    Given a UTF-8-encoded byte sequence (str), returns the number of bytes at
101
    the end of the string which comprise an incomplete UTF-8 character
102
    sequence.
103
104
    If the string is empty or ends with a complete character OR INVALID
105
    sequence, returns 0.
106
    Otherwise, returns 1-3 indicating the number of bytes in the final
107
    incomplete (but valid) character sequence.
108
109
    Does not check any bytes before the final sequence for correctness.
110
111
    >>> incomplete_utf8_sequence("")
112
    0
113
    >>> incomplete_utf8_sequence("xy")
114
    0
115
    >>> incomplete_utf8_sequence("xy\xc3\xbc")
116
    0
117
    >>> incomplete_utf8_sequence("\xc3")
118
    1
119
    >>> incomplete_utf8_sequence("\xbc\xc3")
120
    1
121
    >>> incomplete_utf8_sequence("xy\xbc\xc3")
122
    1
123
    >>> incomplete_utf8_sequence("xy\xe0\xa0")
124
    2
125
    >>> incomplete_utf8_sequence("xy\xf4")
126
    1
127
    >>> incomplete_utf8_sequence("xy\xf4\x8f")
128
    2
129
    >>> incomplete_utf8_sequence("xy\xf4\x8f\xa0")
130
    3
131
    """
132
    count = 0
133
    expect = None
134
    for b in byteseq[::-1]:
135
        b = ord(b)
136
        count += 1
137
        if b & 0x80 == 0x0:
138
            # 0xxxxxxx (single-byte character)
139
            expect = 1
140
            break
141
        elif b & 0xc0 == 0x80:
142
            # 10xxxxxx (subsequent byte)
143
            pass
144
        elif b & 0xe0 == 0xc0:
145
            # 110xxxxx (start of 2-byte sequence)
146
            expect = 2
147
            break
148
        elif b & 0xf0 == 0xe0:
149
            # 1110xxxx (start of 3-byte sequence)
150
            expect = 3
151
            break
152
        elif b & 0xf8 == 0xf0:
153
            # 11110xxx (start of 4-byte sequence)
154
            expect = 4
155
            break
156
        else:
157
            # Invalid byte
158
            return 0
159
160
        if count >= 4:
161
            # Seen too many "subsequent bytes", invalid
162
            return 0
163
164
    if expect is None:
165
        # We never saw a "first byte", invalid
166
        return 0
167
168
    # We now know expect and count
169
    if count >= expect:
170
        # Complete, or we saw an invalid sequence
171
        return 0
172
    elif count < expect:
173
        # Incomplete
174
        return count
1080.1.7 by matt.giuca
The new ivle.database.User class is now used in Request and usrmgt, which
175
176
def object_to_dict(attrnames, obj):
1213 by William Grant
Drop ivle.util.make_path (replaced by Request.make_path) and fix docstrings.
177
    """Convert an object into a dictionary.
178
179
    This takes a shallow copy of the object.
180
181
    @param attrnames: Set (or iterable) of names of attributes to be copied
182
                      into the dictionary. (We don't auto-lookup, because this
183
                      function needs to be used on magical objects).
1080.1.7 by matt.giuca
The new ivle.database.User class is now used in Request and usrmgt, which
184
    """
185
    return dict((k, getattr(obj, k))
186
        for k in attrnames if not k.startswith('_'))