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

« back to all changes in this revision

Viewing changes to ivle/database.py

  • Committer: dcoles
  • Date: 2008-02-13 04:10:55 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:443
Added Forum application along with unmodifed version of phpBB3 "Olympus" 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
 
27
 
import md5
28
 
import datetime
29
 
 
30
 
from storm.locals import create_database, Store, Int, Unicode, DateTime, \
31
 
                         Reference, ReferenceSet, Bool, Storm, Desc
32
 
 
33
 
import ivle.conf
34
 
import ivle.caps
35
 
 
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
 
 
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()))
57
 
 
58
 
class User(Storm):
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
 
 
90
 
    __init__ = _kwarg_init
91
 
 
92
 
    def __repr__(self):
93
 
        return "<%s '%s'>" % (type(self).__name__, self.login)
94
 
 
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
 
 
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.
109
 
        """
110
 
        return self.role.hasCap(capability)
111
 
 
112
 
    @property
113
 
    def password_expired(self):
114
 
        fieldval = self.pass_exp
115
 
        return fieldval is not None and datetime.datetime.now() > fieldval
116
 
 
117
 
    @property
118
 
    def account_expired(self):
119
 
        fieldval = self.acct_exp
120
 
        return fieldval is not None and datetime.datetime.now() > fieldval
121
 
 
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(
129
 
                Desc(Semester.year),
130
 
                Desc(Semester.semester),
131
 
                Desc(Subject.code)
132
 
            )
133
 
 
134
 
    @property
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
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) 
151
 
 
152
 
    @staticmethod
153
 
    def hash_password(password):
154
 
        return md5.md5(password).hexdigest()
155
 
 
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
 
        """
162
 
        return store.find(cls, cls.login == unicode(login)).one()
163
 
 
164
 
class Subject(Storm):
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
 
 
173
 
    offerings = ReferenceSet(id, 'Offering.subject_id')
174
 
 
175
 
    __init__ = _kwarg_init
176
 
 
177
 
    def __repr__(self):
178
 
        return "<%s '%s'>" % (type(self).__name__, self.short_name)
179
 
 
180
 
class Semester(Storm):
181
 
    __storm_table__ = "semester"
182
 
 
183
 
    id = Int(primary=True, name="semesterid")
184
 
    year = Unicode()
185
 
    semester = Unicode()
186
 
    active = Bool()
187
 
 
188
 
    offerings = ReferenceSet(id, 'Offering.semester_id')
189
 
 
190
 
    __init__ = _kwarg_init
191
 
 
192
 
    def __repr__(self):
193
 
        return "<%s %s/%s>" % (type(self).__name__, self.year, self.semester)
194
 
 
195
 
class Offering(Storm):
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
 
 
205
 
    enrolments = ReferenceSet(id, 'Enrolment.offering_id')
206
 
 
207
 
    __init__ = _kwarg_init
208
 
 
209
 
    def __repr__(self):
210
 
        return "<%s %r in %r>" % (type(self).__name__, self.subject,
211
 
                                  self.semester)
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)