27
27
from zope.app.container import btree
28
28
from zope.app.security.interfaces import IUnauthenticatedPrincipal
29
29
from zope.component import queryMultiAdapter, queryUtility
30
from zope.component import adapter
31
from zope.interface import implementer
30
32
from zope.event import notify
31
33
from zope.interface import implements
32
34
from zope.lifecycleevent import ObjectModifiedEvent
38
40
from schooltool.app.app import InitBase
39
41
from schooltool.app.interfaces import ISchoolToolApplication
40
42
from schooltool.basicperson.interfaces import IBasicPerson
43
from schooltool.contact.interfaces import IContactable
44
from schooltool.contact.contact import Contact
41
45
from schooltool.course.interfaces import ISectionContainer
42
46
from schooltool.group.interfaces import IGroupContainer
43
47
from schooltool.person.interfaces import IPerson
44
48
from schooltool.schoolyear.interfaces import ISchoolYear
49
from schooltool.schoolyear.interfaces import ISchoolYearContainer
45
50
from schooltool.securitypolicy import crowds
46
51
from schooltool.term.interfaces import IDateManager
47
52
from schooltool.traverser.traverser import NameTraverserPlugin
67
72
def convertIdToNameWithSort(id):
69
74
student = convertIdToPerson(id[:-2])
70
demos = interfaces.IDemographics(student)
72
first_name = demos.parent_first_name
73
last_name = demos.parent_last_name
75
for index, contact in enumerate(IContactable(student).contacts):
76
if id[-1] == str(index + 1):
77
first_name = contact.first_name
78
last_name = contact.last_name
75
first_name = demos.parent2_first_name
76
last_name = demos.parent2_last_name
78
83
person = convertIdToPerson(id)
79
84
first_name = person.first_name
96
101
def convertIdToEmail(id):
98
103
student = convertIdToPerson(id[:-2])
99
demos = interfaces.IDemographics(student)
104
for index, contact in enumerate(IContactable(student).contacts):
105
if id[-1] == str(index + 1):
105
110
return id + '@scienceleadership.org'
118
123
for the purpose of sending emails, but they will be filtered
119
124
out of any application elements that are for staff only."""
121
demos = interfaces.IDemographics(student)
122
responsible = [id for id in [demos.advisor1, demos.advisor2] if id]
126
responsible = [advisor.username for advisor in student.advisors]
124
128
term = queryUtility(IDateManager).current_term
125
129
groups = IGroupContainer(ISchoolYear(term))
136
140
responsible.append(teacher.username)
138
142
responsible.append(student.username)
140
responsible.append(student.username + ':1')
142
responsible.append(student.username + ':2')
143
for index, contact in enumerate(IContactable(student).contacts):
144
responsible.append(student.username + ':%d' % (index + 1))
144
146
return responsible
264
class InterventionNarratives(btree.BTreeContainer):
265
"""Container of Narrative of persons."""
267
implements(interfaces.IInterventionNarratives)
272
return self.__parent__.student
277
class InterventionNarrative(Persistent, Contained):
278
"""Narrative associated with a person.
280
implements(interfaces.IInterventionNarrative)
282
def __init__(self, sectionId, grade='', assessments='', comments=""):
283
self.__name__ = sectionId
285
self.assessments = assessments
286
self.comments = comments
291
return self.__parent__.student
297
term = queryUtility(IDateManager).current_term
300
sections = ISectionContainer(term)
301
if self.__name__ in sections:
302
return sections[self.__name__]
307
266
class InterventionInit(InitBase):
308
267
"""Create the InterventionRoot object."""
311
270
self.app[u'schooltool.interventions'] = InterventionRoot()
273
@adapter(ISchoolYear)
274
@implementer(interfaces.IInterventionSchoolYear)
275
def getSchoolYearInterventionSchoolYear(schoolyear):
276
return getInterventionSchoolYear(schoolyear.__name__)
279
@adapter(ISchoolToolApplication)
280
@implementer(interfaces.IInterventionSchoolYear)
281
def getSchoolToolApplicationInterventionSchoolYear(app):
282
return getInterventionSchoolYear()
285
@adapter(interfaces.IInterventionSchoolYear)
286
@implementer(ISchoolYear)
287
def getInterventionSchoolYearSchoolYear(schoolyear):
288
app = ISchoolToolApplication(None)
289
return ISchoolYearContainer(app)[schoolyear.__name__]
314
292
def getInterventionSchoolYear(schoolYearId=None):
315
293
"""Get InterventionSchoolYear object for the given school yearr.
316
294
If school year not specified, use current school year."""
318
296
app = ISchoolToolApplication(None)
319
297
interventionRoot = app[u'schooltool.interventions']
320
298
if not schoolYearId:
323
schoolYearId = '%s-%s' % (now.year - 1, now.year)
325
schoolYearId = '%s-%s' % (now.year, now.year + 1)
299
term = queryUtility(IDateManager).current_term
300
schoolyear = ISchoolYear(term)
301
schoolYearId = schoolyear.__name__
327
303
interventionSchoolYear = interventionRoot[schoolYearId]
345
321
interventionSchoolYear[studentId] = interventionStudent
346
322
interventionStudent[u'messages'] = InterventionMessages()
347
323
interventionStudent[u'goals'] = InterventionGoals()
348
interventionStudent[u'narratives'] = InterventionNarratives()
349
324
return interventionStudent
369
class InterventionNarrativeNameChooser(NameChooser):
370
"""A name chooser that returns the narrative's section id."""
372
implements(INameChooser)
374
def chooseName(self, name, obj):
375
"""See INameChooser."""
377
self.checkName(n, obj)
381
344
class InterventionStudentTraverserPlugin(NameTraverserPlugin):
382
345
"""Allows traversal to a student's intervention object.
392
355
return interventionStudent
395
class SectionNarrativesProxy(object):
396
"""Proxy used for traversing to a section's narratives."""
398
def __init__(self, section):
399
self.section = section
402
class SectionNarrativesTraverserPlugin(NameTraverserPlugin):
403
"""Allows traversal from a section object to a SectionNarrativesProxy
404
object, which in turn will be used to traverse to the narratives
405
container for a given student.
407
i.e. if you go to localhost/sections/somesec/narratives this traverser
408
will get called instead of standard traverser.
411
traversalName = "narratives"
412
def _traverse(self, request, name):
413
proxyNarratives = SectionNarrativesProxy(self.context)
414
return location.LocationProxy(proxyNarratives, self.context,
417
class SectionNarrativesTraverser(object):
418
"""Allows traversal to a student's narratives container from the
419
section narratives proxy.
421
i.e. if you go to localhost/sections/somesec/narratives/someone this
422
traverser will get called instead of standard traverser. It also wraps the
423
narrative in a location proxy so the url looks like what is above.
425
The whole reason for having this traversal adaptation is to allow
426
the narative add view to know what section the narrative is for.
428
implements(IPublishTraverse)
430
def __init__(self, context, request):
431
self.context = context
432
self.request = request
434
def publishTraverse(self, request, name):
435
interventionStudent = getInterventionStudent(name)
436
narratives = interventionStudent['narratives']
437
narratives = location.LocationProxy(narratives, self.context, name)
441
358
class SectionMessagesProxy(object):
442
359
"""Proxy used for traversing to a section's student messages."""