1
# IVLE - Informatics Virtual Learning Environment
2
# Copyright (C) 2007-2009 The University of Melbourne
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.
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.
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
18
# Author: Matt Giuca, Will Grant
21
Database Classes and Utilities for Storm ORM
23
This module provides all of the classes which map to database tables.
24
It also provides miscellaneous utility functions for database interaction.
30
from storm.locals import create_database, Store, Int, Unicode, DateTime, \
31
Reference, ReferenceSet, Bool, Storm, Desc
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)
43
def get_conn_string():
45
Returns the Storm connection string, generated from the conf file.
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,
53
Open a database connection and transaction. Return a storm.store.Store
54
instance connected to the configured IVLE database.
56
return Store(create_database(get_conn_string()))
60
Represents an IVLE user.
62
__storm_table__ = "login"
64
id = Int(primary=True, name="loginid")
73
last_login = DateTime()
81
if self.rolenm is 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)
90
__init__ = _kwarg_init
93
return "<%s '%s'>" % (type(self).__name__, self.login)
95
def authenticate(self, password):
96
"""Validate a given password against this user.
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
102
if self.passhash is None:
104
return self.hash_password(password) == self.passhash
106
def hasCap(self, capability):
107
"""Given a capability (which is a Role object), returns True if this
108
User has that capability, False otherwise.
110
return self.role.hasCap(capability)
113
def password_expired(self):
114
fieldval = self.pass_exp
115
return fieldval is not None and datetime.datetime.now() > fieldval
118
def account_expired(self):
119
fieldval = self.acct_exp
120
return fieldval is not None and datetime.datetime.now() > fieldval
122
def _get_enrolments(self, justactive):
123
return Store.of(self).find(Enrolment,
124
Enrolment.user_id == self.id,
125
(Enrolment.active == True) if justactive else True,
126
Enrolment.offering_id == Offering.id,
127
Offering.semester_id == Semester.id,
128
Offering.subject_id == Subject.id).order_by(
130
Desc(Semester.semester),
135
def active_enrolments(self):
136
'''A sanely ordered list of the user's active enrolments.'''
137
return self._get_enrolments(True)
140
def enrolments(self):
141
'''A sanely ordered list of all of the user's enrolments.'''
142
return self._get_enrolments(False)
145
def hash_password(password):
146
return md5.md5(password).hexdigest()
149
def get_by_login(cls, store, login):
151
Get the User from the db associated with a given store and
154
return store.find(cls, cls.login == unicode(login)).one()
156
class Subject(Storm):
157
__storm_table__ = "subject"
159
id = Int(primary=True, name="subjectid")
160
code = Unicode(name="subj_code")
161
name = Unicode(name="subj_name")
162
short_name = Unicode(name="subj_short_name")
165
offerings = ReferenceSet(id, 'Offering.subject_id')
167
__init__ = _kwarg_init
170
return "<%s '%s'>" % (type(self).__name__, self.short_name)
172
class Semester(Storm):
173
__storm_table__ = "semester"
175
id = Int(primary=True, name="semesterid")
180
offerings = ReferenceSet(id, 'Offering.semester_id')
182
__init__ = _kwarg_init
185
return "<%s %s/%s>" % (type(self).__name__, self.year, self.semester)
187
class Offering(Storm):
188
__storm_table__ = "offering"
190
id = Int(primary=True, name="offeringid")
191
subject_id = Int(name="subject")
192
subject = Reference(subject_id, Subject.id)
193
semester_id = Int(name="semesterid")
194
semester = Reference(semester_id, Semester.id)
195
groups_student_permissions = Unicode()
197
enrolments = ReferenceSet(id, 'Enrolment.offering_id')
199
__init__ = _kwarg_init
202
return "<%s %r in %r>" % (type(self).__name__, self.subject,
205
class Enrolment(Storm):
206
__storm_table__ = "enrolment"
207
__storm_primary__ = "user_id", "offering_id"
209
user_id = Int(name="loginid")
210
user = Reference(user_id, User.id)
211
offering_id = Int(name="offeringid")
212
offering = Reference(offering_id, Offering.id)
216
__init__ = _kwarg_init
219
return "<%s %r in %r>" % (type(self).__name__, self.user,