~replaceafill/ubuntu/trusty/schooltool/2.8_custom-css

« back to all changes in this revision

Viewing changes to src/schooltool/app/states.py

  • Committer: Gediminas Paulauskas
  • Date: 2014-04-18 16:25:33 UTC
  • mfrom: (1.1.33)
  • Revision ID: menesis@pov.lt-20140418162533-noklnc6b89w2epee
Tags: 1:2.7.0-0ubuntu1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#
 
2
# SchoolTool - common information systems platform for school administration
 
3
# Copyright (c) 2013 Shuttleworth Foundation
 
4
#
 
5
# This program is free software; you can redistribute it and/or modify
 
6
# it under the terms of the GNU General Public License as published by
 
7
# the Free Software Foundation; either version 2 of the License, or
 
8
# (at your option) any later version.
 
9
#
 
10
# This program is distributed in the hope that it will be useful,
 
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
# GNU General Public License for more details.
 
14
#
 
15
# You should have received a copy of the GNU General Public License
 
16
# along with this program; if not, write to the Free Software
 
17
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
18
#
 
19
"""
 
20
Relationship states
 
21
"""
 
22
from persistent import Persistent
 
23
 
 
24
import zope.schema.vocabulary
 
25
from zope.container.contained import Contained
 
26
from zope.container.btree import BTreeContainer
 
27
from zope.container.ordered import OrderedContainer
 
28
from zope.interface import implements, implementer, implementsOnly
 
29
from zope.interface import Interface
 
30
from zope.component import adapts, adapter
 
31
from zope.location.location import locate
 
32
 
 
33
import z3c.form.term
 
34
import z3c.form.widget
 
35
import z3c.form.interfaces
 
36
from z3c.form.browser.select import SelectWidget
 
37
 
 
38
from schooltool.app.app import InitBase, StartUpBase
 
39
from schooltool.app.interfaces import IRelationshipState
 
40
from schooltool.app.interfaces import IRelationshipStateChoice
 
41
from schooltool.app.interfaces import IRelationshipStates
 
42
from schooltool.app.interfaces import IRelationshipStateContainer
 
43
from schooltool.app.interfaces import ISchoolToolApplication
 
44
from schooltool.relationship.temporal import ACTIVE, INACTIVE
 
45
 
 
46
from schooltool.common import SchoolToolMessage as _
 
47
 
 
48
 
 
49
RELATIONSHIP_STATES_APP_KEY = 'schooltool.app.relationships-states'
 
50
 
 
51
 
 
52
class RelationshipState(Persistent, Contained):
 
53
    implements(IRelationshipState)
 
54
 
 
55
    title = None
 
56
    active = ACTIVE
 
57
 
 
58
    def __init__(self, title, active, code=None):
 
59
        self.title = title
 
60
        self.active = ''.join(sorted(set(active)))
 
61
        self.__name__ = code
 
62
 
 
63
    @property
 
64
    def code(self):
 
65
        return self.__name__
 
66
 
 
67
    @code.setter
 
68
    def code(self, name):
 
69
        if name == self.__name__:
 
70
            return
 
71
        container = self.__parent__
 
72
        if container is None:
 
73
            return
 
74
        del container[self.__name__]
 
75
        container[name] = self
 
76
 
 
77
 
 
78
class RelationshipStates(Persistent, Contained):
 
79
    implements(IRelationshipStates)
 
80
 
 
81
    title = None
 
82
    states = None
 
83
    system_titles = None
 
84
    factory = RelationshipState
 
85
 
 
86
    def __init__(self, title):
 
87
        self.title = title
 
88
        self.states = OrderedContainer()
 
89
        locate(self.states, self, 'states')
 
90
        self.system_titles = OrderedContainer()
 
91
        locate(self.system_titles, self, 'system_titles')
 
92
 
 
93
    def __iter__(self):
 
94
        return iter(self.states.values())
 
95
 
 
96
    def getState(self, state_tuple):
 
97
        if state_tuple is None:
 
98
            return None
 
99
        meaning, code = state_tuple
 
100
        state = self.states.get(code)
 
101
        return state
 
102
 
 
103
    def getTitle(self, state_tuple):
 
104
        state = self.getState(state_tuple)
 
105
        if state is None:
 
106
            return None
 
107
        return state.title
 
108
 
 
109
    def getDescription(self, state_tuple):
 
110
        if state_tuple is None:
 
111
            return None
 
112
        meaning, code = state_tuple
 
113
        state = self.system_titles.get(meaning)
 
114
        return state
 
115
 
 
116
    @classmethod
 
117
    def overlap(cls, codes, other):
 
118
        for code in codes:
 
119
            if code in other:
 
120
                return True
 
121
        return False
 
122
 
 
123
    def add(self, *args, **kw):
 
124
        state = self.factory(*args, **kw)
 
125
        self.states[state.code] = state
 
126
 
 
127
    def describe(self, active, title):
 
128
        active = ''.join(sorted(set(active)))
 
129
        self.system_titles[active] = title
 
130
 
 
131
 
 
132
class RelationshipStateContainer(BTreeContainer):
 
133
    implements(IRelationshipStateContainer)
 
134
 
 
135
 
 
136
class VivifyStateContainer(object):
 
137
 
 
138
    def __call__(self):
 
139
        if RELATIONSHIP_STATES_APP_KEY not in self.app:
 
140
            self.app[RELATIONSHIP_STATES_APP_KEY] = RelationshipStateContainer()
 
141
 
 
142
 
 
143
class StateInit(VivifyStateContainer, InitBase):
 
144
    pass
 
145
 
 
146
 
 
147
class StateStartUp(VivifyStateContainer, StartUpBase):
 
148
    pass
 
149
 
 
150
 
 
151
class StateStartUpBase(StartUpBase):
 
152
 
 
153
    after = ('schooltool.app.states', )
 
154
    states_name = None
 
155
    states_title = u''
 
156
 
 
157
    def populate(self, states):
 
158
        states.describe(ACTIVE, _('Active'))
 
159
        states.describe(INACTIVE, _('Inactive'))
 
160
 
 
161
    def create(self, title):
 
162
        return RelationshipStates(title)
 
163
 
 
164
    def __call__(self):
 
165
        if self.states_name is None:
 
166
            raise NotImplementedError()
 
167
        container = IRelationshipStateContainer(self.app)
 
168
        if self.states_name not in container:
 
169
            try:
 
170
                container[self.states_name] = self.create(self.states_title)
 
171
                self.populate(container[self.states_name])
 
172
            except Exception, e:
 
173
                try:
 
174
                    del container[self.states_name]
 
175
                except Exception:
 
176
                    pass
 
177
                raise e
 
178
 
 
179
 
 
180
@adapter(ISchoolToolApplication)
 
181
@implementer(IRelationshipStateContainer)
 
182
def getStateContainer(app):
 
183
    return app[RELATIONSHIP_STATES_APP_KEY]
 
184
 
 
185
 
 
186
class RelationshipStateTerms(z3c.form.term.Terms):
 
187
 
 
188
    adapts(Interface, z3c.form.interfaces.IFormLayer, Interface,
 
189
           IRelationshipStateChoice, z3c.form.interfaces.IWidget)
 
190
    implementsOnly(z3c.form.interfaces.ITerms)
 
191
 
 
192
    def __init__(self, context, request, form, field, widget):
 
193
        self.context = context
 
194
        self.request = request
 
195
        self.form = form
 
196
        self.field = field
 
197
        self.widget = widget
 
198
        self.terms = self.getVocabulary()
 
199
 
 
200
    def getVocabulary(self):
 
201
        app = ISchoolToolApplication(None)
 
202
        container = IRelationshipStateContainer(app)
 
203
        relationships = container.get(self.field.source)
 
204
        terms = [
 
205
            zope.schema.vocabulary.SimpleTerm(
 
206
                state, token=state.__name__, title=state.title)
 
207
            for state in relationships.states.values()]
 
208
        vocabulary = zope.schema.vocabulary.SimpleVocabulary(terms)
 
209
        return vocabulary
 
210
 
 
211
 
 
212
class RelationshipStateChoice(zope.schema.Field):
 
213
    implements(IRelationshipStateChoice)
 
214
 
 
215
    source = None
 
216
 
 
217
    def __init__(self, source=None, **kw):
 
218
        self.source = source
 
219
        zope.schema.Field.__init__(self, **kw)
 
220
 
 
221
 
 
222
@adapter(IRelationshipStateChoice, z3c.form.interfaces.IFormLayer)
 
223
@implementer(z3c.form.interfaces.IFieldWidget)
 
224
def RelationshipStateFieldWidget(field, request):
 
225
    return z3c.form.widget.FieldWidget(field, SelectWidget(request))
 
226
 
 
227
 
 
228
class GroupMembershipStatesStartup(StateStartUpBase):
 
229
 
 
230
    states_name = 'group-membership'
 
231
    states_title = _('Group Membership')
 
232
 
 
233
    def populate(self, states):
 
234
        super(GroupMembershipStatesStartup, self).populate(states)
 
235
        states.add(_('Pending'), INACTIVE, 'i')
 
236
        states.add(_('Member'), ACTIVE, 'a')
 
237
        states.add(_('Suspended'), INACTIVE, 's')
 
238
        states.add(_('Removed'), INACTIVE, 'r')
 
239
 
 
240
 
 
241
GRADUATED = 'c'
 
242
PREENROLLED = 'p'
 
243
 
 
244
 
 
245
class StudentMembershipStatesStartup(StateStartUpBase):
 
246
 
 
247
    states_name = 'student-enrollment'
 
248
    states_title = _('Student Enrollment')
 
249
 
 
250
    def populate(self, states):
 
251
        super(StudentMembershipStatesStartup, self).populate(states)
 
252
        states.add(_('Pending'), INACTIVE, 'i')
 
253
        states.add(_('Pre-enrolled'), INACTIVE+PREENROLLED, 'p')
 
254
        states.add(_('Enrolled'), ACTIVE, 'a')
 
255
        states.add(_('Graduated/Active'), ACTIVE+GRADUATED, 'c')
 
256
        states.add(_('Graduated/Inactive'), INACTIVE+GRADUATED, 'r')
 
257
        states.add(_('Withdrawn'), INACTIVE, 'w')
 
258
        states.describe(INACTIVE+PREENROLLED, _('Pre-enrolled'))
 
259
        states.describe(ACTIVE+GRADUATED, _('Graduated/Active'))
 
260
        states.describe(INACTIVE+GRADUATED, _('Graduated/Inactive'))
 
261
 
 
262
 
 
263
class LeadershipStatesStartUp(StateStartUpBase):
 
264
 
 
265
    states_name = 'asset-leaders'
 
266
    states_title = _('Leaders')
 
267
 
 
268
    def populate(self, states):
 
269
        super(LeadershipStatesStartUp, self).populate(states)
 
270
        states.add(_('Active'), ACTIVE, 'a')
 
271
        states.add(_('Inactive'), INACTIVE, 'i')
 
272
 
 
273
 
 
274
class StudentLevelsStatesStartup(StateStartUpBase):
 
275
 
 
276
    states_name = 'student-levels'
 
277
    states_title = _('Student Levels')
 
278
 
 
279
    def populate(self, states):
 
280
        super(StudentLevelsStatesStartup, self).populate(states)
 
281
        states.add(_('Pre-enrolled'), INACTIVE+PREENROLLED, 'p')
 
282
        states.add(_('Enrolled'), ACTIVE, 'a')
 
283
        states.add(_('Graduated'), INACTIVE+GRADUATED, 'c')
 
284
        states.add(_('Inactive'), INACTIVE, 'i')
 
285
        states.describe(INACTIVE+PREENROLLED, _('Pre-enrolled'))
 
286
        states.describe(INACTIVE+GRADUATED, _('Graduated'))