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

1080.1.2 by matt.giuca
New module: ivle.database. Classes and utilities for Storm ORM.
1
# IVLE - Informatics Virtual Learning Environment
2
# Copyright (C) 2007-2009 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
# Author: Matt Giuca, Will Grant
19
20
"""
21
Database Classes and Utilities for Storm ORM
22
23
This module provides all of the classes which map to database tables.
24
It also provides miscellaneous utility functions for database interaction.
25
"""
26
1080.1.13 by me at id
ivle.database.User: Add an authenticate() method, and a hash_password()
27
import md5
1080.1.15 by me at id
Give ivle.database.User {password,account}_expired attributes, and get
28
import datetime
1080.1.13 by me at id
ivle.database.User: Add an authenticate() method, and a hash_password()
29
1080.1.4 by matt.giuca
ivle.database: Added User class.
30
from storm.locals import create_database, Store, Int, Unicode, DateTime, \
1080.1.27 by me at id
ivle.database.User: Add an 'active_enrolments' property, which returns a list
31
                         Reference, ReferenceSet, Bool, Storm, Desc
1080.1.2 by matt.giuca
New module: ivle.database. Classes and utilities for Storm ORM.
32
33
import ivle.conf
1080.1.4 by matt.giuca
ivle.database: Added User class.
34
import ivle.caps
1080.1.2 by matt.giuca
New module: ivle.database. Classes and utilities for Storm ORM.
35
1080.1.25 by me at id
ivle.database: Add Subject, Semester and Offering.
36
def _kwarg_init(self, **kwargs):
37
    for k,v in kwargs.items():
38
        if k.startswith('_') or not hasattr(self, k):
39
            raise TypeError("%s got an unexpected keyword argument '%s'"
40
                % self.__class__.__name__, k)
41
        setattr(self, k, v)
42
1080.1.2 by matt.giuca
New module: ivle.database. Classes and utilities for Storm ORM.
43
def get_conn_string():
44
    """
45
    Returns the Storm connection string, generated from the conf file.
46
    """
47
    return "postgres://%s:%s@%s:%d/%s" % (ivle.conf.db_user,
48
        ivle.conf.db_password, ivle.conf.db_host, ivle.conf.db_port,
49
        ivle.conf.db_dbname)
50
51
def get_store():
52
    """
53
    Open a database connection and transaction. Return a storm.store.Store
54
    instance connected to the configured IVLE database.
55
    """
56
    return Store(create_database(get_conn_string()))
1080.1.4 by matt.giuca
ivle.database: Added User class.
57
1080.1.26 by me at id
ivle.database: Add an Enrolment class, and reference(set)s between all of the
58
class User(Storm):
1080.1.4 by matt.giuca
ivle.database: Added User class.
59
    """
60
    Represents an IVLE user.
61
    """
62
    __storm_table__ = "login"
63
64
    id = Int(primary=True, name="loginid")
65
    login = Unicode()
66
    passhash = Unicode()
67
    state = Unicode()
68
    rolenm = Unicode()
69
    unixid = Int()
70
    nick = Unicode()
71
    pass_exp = DateTime()
72
    acct_exp = DateTime()
73
    last_login = DateTime()
74
    svn_pass = Unicode()
75
    email = Unicode()
76
    fullname = Unicode()
77
    studentid = Unicode()
78
    settings = Unicode()
79
80
    def _get_role(self):
81
        if self.rolenm is None:
82
            return None
83
        return ivle.caps.Role(self.rolenm)
84
    def _set_role(self, value):
85
        if not isinstance(value, ivle.caps.Role):
86
            raise TypeError("role must be an ivle.caps.Role")
87
        self.rolenm = unicode(value)
88
    role = property(_get_role, _set_role)
89
1080.1.25 by me at id
ivle.database: Add Subject, Semester and Offering.
90
    __init__ = _kwarg_init
1080.1.4 by matt.giuca
ivle.database: Added User class.
91
92
    def __repr__(self):
93
        return "<%s '%s'>" % (type(self).__name__, self.login)
1080.1.5 by matt.giuca
ivle.database.User: Add the missing methods from ivle.user.User.
94
1080.1.13 by me at id
ivle.database.User: Add an authenticate() method, and a hash_password()
95
    def authenticate(self, password):
96
        """Validate a given password against this user.
97
98
        Returns True if the given password matches the password hash for this
99
        User, False if it doesn't match, and None if there is no hash for the
100
        user.
101
        """
102
        if self.passhash is None:
103
            return None
104
        return self.hash_password(password) == self.passhash
105
1080.1.7 by matt.giuca
The new ivle.database.User class is now used in Request and usrmgt, which
106
    def hasCap(self, capability):
1080.1.5 by matt.giuca
ivle.database.User: Add the missing methods from ivle.user.User.
107
        """Given a capability (which is a Role object), returns True if this
108
        User has that capability, False otherwise.
109
        """
110
        return self.role.hasCap(capability)
111
1080.1.15 by me at id
Give ivle.database.User {password,account}_expired attributes, and get
112
    @property
113
    def password_expired(self):
1080.1.5 by matt.giuca
ivle.database.User: Add the missing methods from ivle.user.User.
114
        fieldval = self.pass_exp
1080.1.15 by me at id
Give ivle.database.User {password,account}_expired attributes, and get
115
        return fieldval is not None and datetime.datetime.now() > fieldval
116
117
    @property
118
    def account_expired(self):
1080.1.5 by matt.giuca
ivle.database.User: Add the missing methods from ivle.user.User.
119
        fieldval = self.acct_exp
1080.1.15 by me at id
Give ivle.database.User {password,account}_expired attributes, and get
120
        return fieldval is not None and datetime.datetime.now() > fieldval
1080.1.6 by matt.giuca
ivle.database.User: Added get_by_login method.
121
1080.1.29 by me at id
ivle.database.User: Order 'enrolments' the same way as 'active_enrolments'.
122
    def _get_enrolments(self, justactive):
1080.1.27 by me at id
ivle.database.User: Add an 'active_enrolments' property, which returns a list
123
        return Store.of(self).find(Enrolment,
124
            Enrolment.user_id == self.id,
1080.1.29 by me at id
ivle.database.User: Order 'enrolments' the same way as 'active_enrolments'.
125
            (Enrolment.active == True) if justactive else True,
1080.1.27 by me at id
ivle.database.User: Add an 'active_enrolments' property, which returns a list
126
            Enrolment.offering_id == Offering.id,
127
            Offering.semester_id == Semester.id,
128
            Offering.subject_id == Subject.id).order_by(
129
                Desc(Semester.year),
130
                Desc(Semester.semester),
131
                Desc(Subject.code)
132
            )
133
1080.1.29 by me at id
ivle.database.User: Order 'enrolments' the same way as 'active_enrolments'.
134
    @property
1080.1.31 by me at id
ivle.database.User: Add 'subjects', an attribute containing currently
135
    def subjects(self):
136
        return Store.of(self).find(Subject,
137
            Enrolment.user_id == self.id,
138
            Enrolment.active == True,
139
            Offering.id == Enrolment.offering_id,
140
            Subject.id == Offering.subject_id).config(distinct=True)
141
142
    @property
1080.1.29 by me at id
ivle.database.User: Order 'enrolments' the same way as 'active_enrolments'.
143
    def active_enrolments(self):
144
        '''A sanely ordered list of the user's active enrolments.'''
145
        return self._get_enrolments(True)
146
147
    @property
148
    def enrolments(self):
149
        '''A sanely ordered list of all of the user's enrolments.'''
150
        return self._get_enrolments(False) 
1080.1.27 by me at id
ivle.database.User: Add an 'active_enrolments' property, which returns a list
151
1080.1.13 by me at id
ivle.database.User: Add an authenticate() method, and a hash_password()
152
    @staticmethod
153
    def hash_password(password):
154
        return md5.md5(password).hexdigest()
155
1080.1.6 by matt.giuca
ivle.database.User: Added get_by_login method.
156
    @classmethod
157
    def get_by_login(cls, store, login):
158
        """
159
        Get the User from the db associated with a given store and
160
        login.
161
        """
1080.1.7 by matt.giuca
The new ivle.database.User class is now used in Request and usrmgt, which
162
        return store.find(cls, cls.login == unicode(login)).one()
1080.1.25 by me at id
ivle.database: Add Subject, Semester and Offering.
163
1080.1.26 by me at id
ivle.database: Add an Enrolment class, and reference(set)s between all of the
164
class Subject(Storm):
1080.1.25 by me at id
ivle.database: Add Subject, Semester and Offering.
165
    __storm_table__ = "subject"
166
167
    id = Int(primary=True, name="subjectid")
168
    code = Unicode(name="subj_code")
169
    name = Unicode(name="subj_name")
170
    short_name = Unicode(name="subj_short_name")
171
    url = Unicode()
172
1080.1.26 by me at id
ivle.database: Add an Enrolment class, and reference(set)s between all of the
173
    offerings = ReferenceSet(id, 'Offering.subject_id')
174
1080.1.25 by me at id
ivle.database: Add Subject, Semester and Offering.
175
    __init__ = _kwarg_init
176
177
    def __repr__(self):
178
        return "<%s '%s'>" % (type(self).__name__, self.short_name)
179
1080.1.26 by me at id
ivle.database: Add an Enrolment class, and reference(set)s between all of the
180
class Semester(Storm):
1080.1.25 by me at id
ivle.database: Add Subject, Semester and Offering.
181
    __storm_table__ = "semester"
182
183
    id = Int(primary=True, name="semesterid")
184
    year = Unicode()
185
    semester = Unicode()
186
    active = Bool()
187
1080.1.26 by me at id
ivle.database: Add an Enrolment class, and reference(set)s between all of the
188
    offerings = ReferenceSet(id, 'Offering.semester_id')
189
1080.1.25 by me at id
ivle.database: Add Subject, Semester and Offering.
190
    __init__ = _kwarg_init
191
192
    def __repr__(self):
193
        return "<%s %s/%s>" % (type(self).__name__, self.year, self.semester)
194
1080.1.26 by me at id
ivle.database: Add an Enrolment class, and reference(set)s between all of the
195
class Offering(Storm):
1080.1.25 by me at id
ivle.database: Add Subject, Semester and Offering.
196
    __storm_table__ = "offering"
197
198
    id = Int(primary=True, name="offeringid")
199
    subject_id = Int(name="subject")
200
    subject = Reference(subject_id, Subject.id)
201
    semester_id = Int(name="semesterid")
202
    semester = Reference(semester_id, Semester.id)
203
    groups_student_permissions = Unicode()
204
1080.1.26 by me at id
ivle.database: Add an Enrolment class, and reference(set)s between all of the
205
    enrolments = ReferenceSet(id, 'Enrolment.offering_id')
206
1080.1.25 by me at id
ivle.database: Add Subject, Semester and Offering.
207
    __init__ = _kwarg_init
208
209
    def __repr__(self):
210
        return "<%s %r in %r>" % (type(self).__name__, self.subject,
211
                                  self.semester)
1080.1.26 by me at id
ivle.database: Add an Enrolment class, and reference(set)s between all of the
212
213
class Enrolment(Storm):
214
    __storm_table__ = "enrolment"
215
    __storm_primary__ = "user_id", "offering_id"
216
217
    user_id = Int(name="loginid")
218
    user = Reference(user_id, User.id)
219
    offering_id = Int(name="offeringid")
220
    offering = Reference(offering_id, Offering.id)
221
    notes = Unicode()
222
    active = Bool()
223
224
    __init__ = _kwarg_init
225
226
    def __repr__(self):
227
        return "<%s %r in %r>" % (type(self).__name__, self.user,
228
                                  self.offering)