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

« back to all changes in this revision

Viewing changes to ivle/util.py

  • Committer: dcoles
  • Date: 2008-07-18 02:40:58 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:912
Makeuser: Makeuser will now chown all files in a users home directory to the
unixid provided by the database. This means remakeallusers.py can be used to
update everyones unixids after a database change. The makeuser script will also 
no longer generate a random unixid when one is not given on the command line.

Database: Change to database so that a sequence is used by default. The allowed  
range is 1000-29999 (let's start at 5000, because 1000+ is used by adduser.  
Reference: http://www.debian.org/doc/debian-policy/ch-opersys.html)
See SF Bug '[ 2012190 ] Student UID generation'
Migration script will reallocate all users a new unixid from the sequence.

Usermgt-Server: Now no longer generates a random unixid. Rely on the database 
to come up with a new sequence number.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
import datetime
26
 
 
27
 
import ivle.conf
28
 
 
29
 
class IVLEError(Exception):
30
 
    """
31
 
    This is the "standard" exception class for IVLE errors.
32
 
    It is the ONLY exception which should propagate to the top - it will then
33
 
    be displayed to the user as an HTTP error with the given code.
34
 
 
35
 
    All other exceptions are considered IVLE bugs and should not occur
36
 
    (they will display a traceback).
37
 
 
38
 
    This error should not be raised directly. Call req.throw_error.
39
 
    """
40
 
    def __init__(self, httpcode, message=None):
41
 
        self.httpcode = httpcode
42
 
        self.message = message
43
 
        self.args = (httpcode, message)
44
 
 
45
 
class IVLEJailError(Exception):
46
 
    """
47
 
    This exception indicates an error that occurred inside an IVLE CGI script
48
 
    inside the jail. It should never be raised directly - only by the 
49
 
    interpreter.
50
 
 
51
 
    Information will be retrieved from it, and then treated as a normal
52
 
    error.
53
 
    """
54
 
    def __init__(self, type_str, message, info):
55
 
        self.type_str = type_str
56
 
        self.message = message
57
 
        self.info = info
58
 
 
59
 
class FakeObject(object):
60
 
    """ A representation of an object that can't be Pickled """
61
 
    def __init__(self, type, name, attrib={}):
62
 
        self.type = type
63
 
        self.name = name
64
 
        self.attrib = attrib
65
 
 
66
 
    def __repr__(self):
67
 
        return "<Fake %s %s>"%(self.type, self.name)
68
 
 
69
 
def make_path(path):
70
 
    """Given a path relative to the IVLE root, makes the path relative to the
71
 
    site root using ivle.conf.root_dir. This path can be used in URLs sent to
72
 
    the client."""
73
 
    return os.path.join(ivle.conf.root_dir, path)
74
 
 
75
 
def split_path(path):
76
 
    """Given a path, returns a tuple consisting of the top-level directory in
77
 
    the path, and the rest of the path. Note that both items in the tuple will
78
 
    NOT begin with a slash, regardless of whether the original path did. Also
79
 
    normalises the path.
80
 
 
81
 
    Always returns a pair of strings, except for one special case, in which
82
 
    the path is completely empty (or just a single slash). In this case the
83
 
    return value will be (None, ''). But still always returns a pair.
84
 
 
85
 
    Examples:
86
 
 
87
 
    >>> split_path("")
88
 
    (None, '')
89
 
    >>> split_path("/")
90
 
    (None, '')
91
 
    >>> split_path("home")
92
 
    ('home', '')
93
 
    >>> split_path("home/docs/files")
94
 
    ('home', 'docs/files')
95
 
    >>> split_path("//home/docs/files")
96
 
    ('', 'home/docs/files')
97
 
    """
98
 
    path = os.path.normpath(path)
99
 
    # Ignore the opening slash
100
 
    if path.startswith(os.sep):
101
 
        path = path[len(os.sep):]
102
 
    if path == '' or path == '.':
103
 
        return (None, '')
104
 
    splitpath = path.split(os.sep, 1)
105
 
    if len(splitpath) == 1:
106
 
        return (splitpath[0], '')
107
 
    else:
108
 
        return tuple(splitpath)
109
 
 
110
 
def incomplete_utf8_sequence(byteseq):
111
 
    """
112
 
    str -> int
113
 
    Given a UTF-8-encoded byte sequence (str), returns the number of bytes at
114
 
    the end of the string which comprise an incomplete UTF-8 character
115
 
    sequence.
116
 
 
117
 
    If the string is empty or ends with a complete character OR INVALID
118
 
    sequence, returns 0.
119
 
    Otherwise, returns 1-3 indicating the number of bytes in the final
120
 
    incomplete (but valid) character sequence.
121
 
 
122
 
    Does not check any bytes before the final sequence for correctness.
123
 
 
124
 
    >>> incomplete_utf8_sequence("")
125
 
    0
126
 
    >>> incomplete_utf8_sequence("xy")
127
 
    0
128
 
    >>> incomplete_utf8_sequence("xy\xc3\xbc")
129
 
    0
130
 
    >>> incomplete_utf8_sequence("\xc3")
131
 
    1
132
 
    >>> incomplete_utf8_sequence("\xbc\xc3")
133
 
    1
134
 
    >>> incomplete_utf8_sequence("xy\xbc\xc3")
135
 
    1
136
 
    >>> incomplete_utf8_sequence("xy\xe0\xa0")
137
 
    2
138
 
    >>> incomplete_utf8_sequence("xy\xf4")
139
 
    1
140
 
    >>> incomplete_utf8_sequence("xy\xf4\x8f")
141
 
    2
142
 
    >>> incomplete_utf8_sequence("xy\xf4\x8f\xa0")
143
 
    3
144
 
    """
145
 
    count = 0
146
 
    expect = None
147
 
    for b in byteseq[::-1]:
148
 
        b = ord(b)
149
 
        count += 1
150
 
        if b & 0x80 == 0x0:
151
 
            # 0xxxxxxx (single-byte character)
152
 
            expect = 1
153
 
            break
154
 
        elif b & 0xc0 == 0x80:
155
 
            # 10xxxxxx (subsequent byte)
156
 
            pass
157
 
        elif b & 0xe0 == 0xc0:
158
 
            # 110xxxxx (start of 2-byte sequence)
159
 
            expect = 2
160
 
            break
161
 
        elif b & 0xf0 == 0xe0:
162
 
            # 1110xxxx (start of 3-byte sequence)
163
 
            expect = 3
164
 
            break
165
 
        elif b & 0xf8 == 0xf0:
166
 
            # 11110xxx (start of 4-byte sequence)
167
 
            expect = 4
168
 
            break
169
 
        else:
170
 
            # Invalid byte
171
 
            return 0
172
 
 
173
 
        if count >= 4:
174
 
            # Seen too many "subsequent bytes", invalid
175
 
            return 0
176
 
 
177
 
    if expect is None:
178
 
        # We never saw a "first byte", invalid
179
 
        return 0
180
 
 
181
 
    # We now know expect and count
182
 
    if count >= expect:
183
 
        # Complete, or we saw an invalid sequence
184
 
        return 0
185
 
    elif count < expect:
186
 
        # Incomplete
187
 
        return count
188
 
 
189
 
def object_to_dict(attrnames, obj):
190
 
    """
191
 
    Convert an object into a dictionary. This takes a shallow copy of the
192
 
    object.
193
 
    attrnames: Set (or iterable) of names of attributes to be copied into the
194
 
        dictionary. (We don't auto-lookup, because this function needs to be
195
 
        used on magical objects).
196
 
    """
197
 
    return dict((k, getattr(obj, k))
198
 
        for k in attrnames if not k.startswith('_'))