Merge lp:~aelkner/schooltool/schooltool.sla_august_fixes into lp:~schooltool-owners/schooltool/sla

Proposed by Alan Elkner
Status: Merged
Merge reported by: Justas Sadzevičius
Merged at revision: not available
Proposed branch: lp:~aelkner/schooltool/schooltool.sla_august_fixes
Merge into: lp:~schooltool-owners/schooltool/sla
Diff against target: None lines
To merge this branch: bzr merge lp:~aelkner/schooltool/schooltool.sla_august_fixes
Reviewer Review Type Date Requested Status
Justas Sadzevičius (community) Approve
Review via email: mp+10637@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Justas Sadzevičius (justas.sadzevicius) wrote :

Why were the generations removed?

Existing databases are marked (AFAIK) as evolved to version 1. This will confuse developers in future, when they try to evolve to version 1 and deployed databases fail.

Maybe it's sufficient to just make the evolve1.py do nothing?

review: Needs Information
Revision history for this message
Alan Elkner (aelkner) wrote :

Do whatever you feel is best here. I just removed the evolution script because SLA is going to be the only user of that package, and they certainly don't need it anymore. But if you think it's better to leave it in there, I'll defer to your better judgment.

Revision history for this message
Justas Sadzevičius (justas.sadzevicius) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== removed directory 'src/schooltool/intervention'
2=== removed file 'src/schooltool/intervention/README.txt'
3--- src/schooltool/intervention/README.txt 2009-07-23 04:51:31 +0000
4+++ src/schooltool/intervention/README.txt 1970-01-01 00:00:00 +0000
5@@ -1,372 +0,0 @@
6-=====================
7-Student Interventions
8-=====================
9-
10-This package supplies the school with a number of objects for tracking
11-interventions with students who are having either acedemic or behavioral
12-problems. Objects include messages passed between concerned faculty members
13-and goals that are established for the student.
14-
15-Let's import some zope stuff before we use it.
16-
17- >>> from zope.component import provideHandler, provideUtility
18- >>> from zope.component import provideAdapter
19- >>> from zope.component import Interface
20- >>> from zope.app.container.interfaces import (IObjectAddedEvent,
21- ... IObjectRemovedEvent)
22- >>> from zope.interface.verify import verifyObject
23-
24-Let's set up the app object.
25-
26- >>> from schooltool.app.interfaces import ISchoolToolApplication
27- >>> from schooltool.testing import setup as stsetup
28- >>> app = stsetup.setUpSchoolToolSite()
29-
30-We'll need a schoolyear and current term.
31-
32- >>> from schooltool.schoolyear.schoolyear import getSchoolYearContainer
33- >>> from schooltool.term.interfaces import ITermContainer
34- >>> from schooltool.term.term import getTermContainer
35- >>> from schooltool.term.term import getSchoolYearForTerm
36- >>> provideAdapter(getTermContainer, [Interface], ITermContainer)
37- >>> provideAdapter(getSchoolYearForTerm)
38- >>> provideAdapter(getSchoolYearContainer)
39-
40- >>> from datetime import date
41- >>> from schooltool.schoolyear.interfaces import ISchoolYearContainer
42- >>> from schooltool.schoolyear.schoolyear import SchoolYear
43- >>> schoolyear = SchoolYear("Sample", date(2004, 9, 1), date(2005, 12, 20))
44- >>> ISchoolYearContainer(app)['2004-2005'] = schoolyear
45-
46- >>> from schooltool.term.term import Term
47- >>> term = Term('Sample', date(2004, 9, 1), date(2004, 12, 20))
48- >>> terms = ITermContainer(app)
49- >>> terms['2004-fall'] = term
50-
51- >>> from schooltool.term.tests import setUpDateManagerStub
52- >>> setUpDateManagerStub(date(2004, 9, 1), term)
53-
54-We will need an adapter to get the schooltool application.
55-
56- >>> from zope.component import provideAdapter
57- >>> provideAdapter(lambda context: app,
58- ... adapts=[None],
59- ... provides=ISchoolToolApplication)
60-
61-We'll also need an adapter to get the dublincore info of an object.
62-
63- >>> import zope.dublincore.annotatableadapter
64- >>> import zope.dublincore.interfaces
65- >>> provideAdapter(factory=zope.dublincore.annotatableadapter.ZDCAnnotatableAdapter,
66- ... provides=zope.dublincore.interfaces.IWriteZopeDublinCore)
67-
68-
69-Interventions
70--------------
71-
72-Now we get to the heart of the matter, the interventions themselves. We start
73-with the root container of all of the interventions. The test aparatus will
74-have set this up for us like the application init handler would do.
75-
76- >>> from schooltool.intervention import intervention, interfaces
77- >>> interventionRoot = app['schooltool.interventions']
78- >>> verifyObject(interfaces.IInterventionRoot, interventionRoot)
79- True
80- >>> len(interventionRoot)
81- 0
82-
83-The intervention root container contains InterventionSchoolYear objects,
84-keyed by the school year's id, which in turn contain InterventionStudent
85-objects for each student that is under intervention during that school year.
86-We have a handy function that will return to us the InterventionStudent
87-object for a given student, school year pair. If the InterventionSchoolYear
88-object is missing, it will create it. If the InterventionStudent object is
89-missing, it will create that as well.
90-
91-Let's create a student and not specify the school year. We will then test this
92-function does what we expect. In addition to creating the student's
93-intervention container, it will place the messages and goals containers in it.
94-
95- >>> from schooltool.basicperson.person import BasicPerson
96- >>> jdoe = BasicPerson('jdoe', 'John', 'Doe')
97- >>> app['persons']['jdoe'] = jdoe
98- >>> jdoeIntervention = intervention.getInterventionStudent(jdoe.__name__)
99- >>> verifyObject(interfaces.IInterventionStudent, jdoeIntervention)
100- True
101- >>> jdoeIntervention.student is jdoe
102- True
103- >>> [key for key in interventionRoot]
104- [u'2004-2005']
105- >>> interventionSchoolYear = intervention.getInterventionSchoolYear()
106- >>> verifyObject(interfaces.IInterventionSchoolYear, interventionSchoolYear)
107- True
108- >>> [key for key in interventionSchoolYear]
109- [u'jdoe']
110- >>> [key for key in jdoeIntervention]
111- [u'goals', u'messages']
112- >>> jdoeMessages = jdoeIntervention['messages']
113- >>> verifyObject(interfaces.IInterventionMessages, jdoeMessages)
114- True
115- >>> jdoeMessages.student is jdoe
116- True
117- >>> len(jdoeMessages)
118- 0
119- >>> jdoeGoals = jdoeIntervention['goals']
120- >>> verifyObject(interfaces.IInterventionGoals, jdoeGoals)
121- True
122- >>> jdoeGoals.student is jdoe
123- True
124- >>> len(jdoeGoals)
125- 0
126-
127-Intervention Messagess
128-----------------------
129-
130-Now we will create some InterventionMessage objects for the student and put
131-them in the student's InterventionMessages container.
132-
133-First, we'll need to register the object added handler that sends the message
134-to the recipients as an email as well as the dummy mail sender that we need
135-for testing.
136-
137- >>> from zope.sendmail.interfaces import IMailDelivery
138- >>> from schooltool.intervention import sendmail
139- >>> provideHandler(sendmail.sendInterventionMessageEmail,
140- ... adapts=(interfaces.IInterventionMessage, IObjectAddedEvent))
141- >>> provideUtility(sendmail.TestMailDelivery(), name='intervention',
142- ... provides=IMailDelivery)
143-
144-We will create person objects for some teachers and advisors.
145-
146- >>> teacher1 = BasicPerson('teacher1', '1', 'Teacher')
147- >>> app['persons']['teacher1'] = teacher1
148- >>> teacher2 = BasicPerson('teacher2', '2', 'Teacher')
149- >>> app['persons']['teacher2'] = teacher2
150- >>> advisor1 = BasicPerson('advisor1', '1', 'Advisor')
151- >>> app['persons']['advisor1'] = advisor1
152- >>> advisor2 = BasicPerson('advisor2', '2', 'Advisor')
153- >>> app['persons']['advisor2'] = advisor2
154-
155-Now we'll create a message and add it to the container. Upon adding the message
156-the dummy mail sender will print out the email that would otherwise be sent to
157-a real smtp server. We'll also note that the message's student property will
158-be the correct student.
159-
160- >>> body = "John has been a bad student."
161- >>> message1 = intervention.InterventionMessage(teacher1.username,
162- ... [teacher2.username, advisor1.username], body)
163- >>> verifyObject(interfaces.IInterventionMessage, message1)
164- True
165- >>> jdoeMessages['1'] = message1
166- Content-Type: text/plain; charset="utf-8"
167- MIME-Version: 1.0
168- Content-Transfer-Encoding: 7bit
169- From: teacher1@scienceleadership.org
170- To: advisor1@scienceleadership.org, teacher2@scienceleadership.org
171- Subject: INTERVENTION MESSAGE: John Doe
172- Date: ...
173- <BLANKLINE>
174- 1 Teacher writes:
175- <BLANKLINE>
176- John has been a bad student.
177- >>> message1.student is jdoe
178- True
179-
180-We'll create another message with different sender and recipients and add it
181-to the container. The difference will be reflected in the email messge.
182-
183- >>> body = "John still needs to learn to behave."
184- >>> message2 = intervention.InterventionMessage(teacher2.username,
185- ... [advisor1.username, advisor2.username], body)
186- >>> jdoeMessages['2'] = message2
187- Content-Type: text/plain; charset="utf-8"
188- MIME-Version: 1.0
189- Content-Transfer-Encoding: 7bit
190- From: teacher2@scienceleadership.org
191- To: advisor1@scienceleadership.org, advisor2@scienceleadership.org
192- Subject: INTERVENTION MESSAGE: John Doe
193- Date: ...
194- <BLANKLINE>
195- 2 Teacher writes:
196- <BLANKLINE>
197- John still needs to learn to behave.
198-
199-Intervention Goals
200-------------------
201-
202-First, we'll need to register the object added handler that sends an email
203-to the persons responsible for a goal when the goal is added.
204-
205- >>> provideHandler(sendmail.sendInterventionGoalAddEmail,
206- ... adapts=(interfaces.IInterventionGoal, IObjectAddedEvent))
207-
208-Let's create some InterventionGoal objects for the student and put them in
209-the student's InterventionGoals container. We'll note that emails will
210-be sent when a goal is added to the goals container.
211-
212- >>> from datetime import date
213- >>> goal1 = intervention.InterventionGoal('bad behaviour', 'be nicer',
214- ... 'smart', 'nicer to clasmates', 'teach manners', date(2004, 9, 1),
215- ... [advisor1.username, advisor2.username])
216- >>> verifyObject(interfaces.IInterventionGoal, goal1)
217- True
218- >>> jdoeGoals['1'] = goal1
219- Content-Type: text/plain; charset="utf-8"
220- MIME-Version: 1.0
221- Content-Transfer-Encoding: 7bit
222- From:
223- To: advisor1@scienceleadership.org, advisor2@scienceleadership.org
224- Subject: INTERVENTION GOAL ADDED: John Doe
225- Date: ...
226- <BLANKLINE>
227- The following goal was added for John Doe:
228- <BLANKLINE>
229- Presenting concerns
230- -------------------
231- <BLANKLINE>
232- bad behaviour
233- <BLANKLINE>
234- Goal
235- ----
236- <BLANKLINE>
237- be nicer
238- <BLANKLINE>
239- Strengths
240- ---------
241- <BLANKLINE>
242- smart
243- <BLANKLINE>
244- Indicators
245- ----------
246- <BLANKLINE>
247- nicer to clasmates
248- <BLANKLINE>
249- Intervention
250- ------------
251- <BLANKLINE>
252- teach manners
253- <BLANKLINE>
254- Timeline
255- --------
256- <BLANKLINE>
257- ...
258- <BLANKLINE>
259- Persons responsible
260- -------------------
261- <BLANKLINE>
262- 1 Advisor
263- 2 Advisor
264- <BLANKLINE>
265- Intervention Center
266- -------------------
267- <BLANKLINE>
268- http://127.0.0.1/schooltool.interventions/2004-2005/jdoe
269- <BLANKLINE>
270- >>> goal1.student is jdoe
271- True
272-
273-Let's add a second one.
274-
275- >>> goal2 = intervention.InterventionGoal('bad grades', 'passing grades',
276- ... 'friendly', 'grades are passing', 'tutor student', date.today(),
277- ... [teacher1.username, advisor2.username])
278- >>> jdoeGoals['2'] = goal2
279- Content-Type: text/plain; charset="utf-8"
280- MIME-Version: 1.0
281- Content-Transfer-Encoding: 7bit
282- From:
283- To: advisor2@scienceleadership.org, teacher1@scienceleadership.org
284- Subject: INTERVENTION GOAL ADDED: John Doe
285- Date: ...
286- <BLANKLINE>
287- The following goal was added for John Doe:
288- <BLANKLINE>
289- Presenting concerns
290- -------------------
291- <BLANKLINE>
292- bad grades
293- <BLANKLINE>
294- Goal
295- ----
296- <BLANKLINE>
297- passing grades
298- <BLANKLINE>
299- Strengths
300- ---------
301- <BLANKLINE>
302- friendly
303- <BLANKLINE>
304- Indicators
305- ----------
306- <BLANKLINE>
307- grades are passing
308- <BLANKLINE>
309- Intervention
310- ------------
311- <BLANKLINE>
312- tutor student
313- <BLANKLINE>
314- Timeline
315- --------
316- <BLANKLINE>
317- ...
318- <BLANKLINE>
319- Persons responsible
320- -------------------
321- <BLANKLINE>
322- 2 Advisor
323- 1 Teacher
324- <BLANKLINE>
325- Intervention Center
326- -------------------
327- <BLANKLINE>
328- http://127.0.0.1/schooltool.interventions/2004-2005/jdoe
329- <BLANKLINE>
330-
331-We chose date.today() as the timeline for our goals because we wanted to test
332-right away the method in our sendmail module that notifies the persons
333-responsible via email when the timeline has been reached for a goal. We'll
334-call this method and see the email messages that get generated. Also, we'll
335-need to add the schooltool manager user that's expected by the routine to be
336-present.
337-
338- >>> from schooltool.intervention import sendmail
339- >>> manager_user = BasicPerson('manager', 'SchoolTool', 'Manager')
340- >>> app['persons']['manager'] = manager_user
341- >>> notified = sendmail.sendInterventionGoalNotifyEmails()
342- Content-Type: text/plain; charset="utf-8"
343- MIME-Version: 1.0
344- Content-Transfer-Encoding: 7bit
345- From: manager@scienceleadership.org
346- To: advisor1@scienceleadership.org, advisor2@scienceleadership.org
347- Subject: INTERVENTION GOAL DUE: John Doe
348- Date: ...
349- <BLANKLINE>
350- Please follow the link below to update the follow up notes and, if
351- appropriate, the goal met status of the intervention goal for John Doe.
352- <BLANKLINE>
353- http://127.0.0.1/schooltool.interventions/.../jdoe/goals/1/@@editGoal.html
354- <BLANKLINE>
355- Content-Type: text/plain; charset="utf-8"
356- MIME-Version: 1.0
357- Content-Transfer-Encoding: 7bit
358- From: manager@scienceleadership.org
359- To: advisor2@scienceleadership.org, teacher1@scienceleadership.org
360- Subject: INTERVENTION GOAL DUE: John Doe
361- Date: ...
362- <BLANKLINE>
363- Please follow the link below to update the follow up notes and, if
364- appropriate, the goal met status of the intervention goal for John Doe.
365- <BLANKLINE>
366- http://127.0.0.1/schooltool.interventions/.../jdoe/goals/2/@@editGoal.html
367- <BLANKLINE>
368- >>> len(notified)
369- 2
370-
371-If we call the same routine again, we will get nothing because the notified
372-flags have been set on the goals.
373-
374- >>> notified = sendmail.sendInterventionGoalNotifyEmails()
375- >>> len(notified)
376- 0
377-
378
379=== removed file 'src/schooltool/intervention/__init__.py'
380--- src/schooltool/intervention/__init__.py 2009-07-23 07:08:31 +0000
381+++ src/schooltool/intervention/__init__.py 1970-01-01 00:00:00 +0000
382@@ -1,13 +0,0 @@
383-# Make a package.
384-
385-def registerTestSetup():
386- from schooltool.testing import registry
387-
388- def addInterventionRoot(app):
389- from schooltool.intervention import intervention
390- app['schooltool.interventions'] = intervention.InterventionRoot()
391- registry.register('ApplicationContainers', addInterventionRoot)
392-
393-registerTestSetup()
394-del registerTestSetup
395-
396
397=== removed directory 'src/schooltool/intervention/browser'
398=== removed file 'src/schooltool/intervention/browser/README.txt'
399--- src/schooltool/intervention/browser/README.txt 2009-07-23 04:51:31 +0000
400+++ src/schooltool/intervention/browser/README.txt 1970-01-01 00:00:00 +0000
401@@ -1,847 +0,0 @@
402-=====================
403-Student Interventions
404-=====================
405-
406-These are the functional tests for the intervention package.
407-
408-First we need to set up the school.
409-
410- >>> from schooltool.app.browser.ftests import setup
411- >>> setup.setUpBasicSchool()
412- >>> manager = setup.logIn('manager', 'schooltool')
413-
414-
415-Interventions
416--------------
417-
418-Now we come to the main intervention center that gives us access to all of the
419-intervention data associated with a given student for a given school year.
420-We'll create some teachers and students and put them in some sections.
421-We will also create a principal and guidance counselor and put them in the
422-adminstators group. These users will show up as part of the list of persons
423-responsible for any student and will also have permission to work with the
424-intervention of any student.
425-
426- >>> from schooltool.intervention.browser.ftests import addPerson, addCourseSectionMembers
427- >>> addPerson('Teacher1', 'Teacher1', 'teacher1', 'pwd', groups=['teachers'])
428- >>> addPerson('Teacher2', 'Teacher2', 'teacher2', 'pwd', groups=['teachers'])
429- >>> addPerson('Student1', 'Student1', 'student1', 'pwd', groups=['students'])
430- >>> addPerson('Student2', 'Student2', 'student2', 'pwd', groups=['students'])
431- >>> addPerson('Student3', 'Student3', 'student3', 'pwd', groups=['students'])
432- >>> addCourseSectionMembers('course1', 'section1', ['Teacher1'],
433- ... ['Student1', 'Student3'])
434- >>> addCourseSectionMembers('course2', 'section2', ['Teacher2'],
435- ... ['Student2'])
436- >>> addPerson('Counselor', 'Counselor', 'counselor', 'pwd', groups=['administrators'])
437- >>> addPerson('Principal', 'Principal', 'principal', 'pwd', groups=['administrators'])
438-
439-Let's add a parent contact and an advisor which will show up when adding goals
440-and messages.
441-
442- >>> manager.getLink('Manage').click()
443- >>> manager.getLink('Persons').click()
444- >>> manager.getLink('Student1').click()
445- >>> manager.getLink('Contacts').click()
446- >>> manager.getLink('Create new contact').click()
447- >>> manager.getControl('First name').value = 'Parent1'
448- >>> manager.getControl('Last name').value = 'Parent1'
449- >>> manager.getControl('Email').value = 'parent@somewhere.com'
450- >>> manager.getControl('Add').click()
451-
452- >>> manager.getLink('Advisors').click()
453- >>> manager.getControl(name='add_item.teacher2').value = 'checked'
454- >>> manager.getControl('Add').click()
455-
456-To navigate to a student's intervention, we have the 'Intervention' tab located
457-at the top. It will call up a search box to allow us to find the student we
458-want.
459-
460- >>> manager.getLink('Intervention').click()
461- >>> print manager.contents
462- <BLANKLINE>
463- ...Find Now...
464- ...Clear...
465- ...Enter any part of a student's name or select a filter
466- from the drop-down to find an intervention...
467- ...Listing all students currently disabled...
468-
469-Search for any student with at least one goal.
470-
471- >>> manager.getControl(name='ADDITIONAL_FILTER').value = ['WITH_GOAL']
472- >>> manager.getControl(name='SEARCH_BUTTON').click()
473- >>> print manager.contents
474- <BLANKLINE>
475- ...
476- <option value="">All students</option>
477- <option selected="selected" value="WITH_GOAL">With set goals</option>
478- ...
479- ...There are no students that match the search criteria...
480-
481- >>> manager.getControl(name='CLEAR_SEARCH').click()
482- >>> print manager.contents
483- <BLANKLINE>
484- ...
485- <option selected="selected" value="">All students</option>
486- <option value="WITH_GOAL">With set goals</option>
487- ...
488-
489-We'll enter something that is not in either student's name.
490-
491- >>> manager.getControl(name='SEARCH').value = 'somebody'
492- >>> manager.getControl(name='SEARCH_BUTTON').click()
493- >>> print manager.contents
494- <BLANKLINE>
495- ...Find Now...
496- ...Clear...
497- ...There are no students that match the search criteria...
498-
499-We'll enter something that is in both students' names.
500-
501- >>> manager.getControl(name='SEARCH').value = 'Student'
502- >>> manager.getControl(name='SEARCH_BUTTON').click()
503- >>> print manager.contents
504- <BLANKLINE>
505- ...Find Now...
506- ...Clear...
507- ...Student1 Student1...
508- ...Student2 Student2...
509-
510-We'll hit the clear button to get us back to an empty search.
511-
512- >>> manager.getControl(name='CLEAR_SEARCH').click()
513- >>> print manager.contents
514- <BLANKLINE>
515- ...Find Now...
516- ...Clear...
517- ...Enter any part of a student's name...
518-
519-We'll enter something that is only in student1's name.
520-
521- >>> manager.getControl(name='SEARCH').value = '1'
522- >>> manager.getControl(name='SEARCH_BUTTON').click()
523- >>> print manager.contents
524- <BLANKLINE>
525- ...Find Now...
526- ...Clear...
527- ...Student1 Student1...
528- >>> 'Student2' not in manager.contents
529- True
530-
531-Now let's click on student1's link to call up the Intervention Center for
532-that student.
533-
534- >>> manager.getLink('Student1 Student1').click()
535- >>> print manager.contents
536- <BLANKLINE>
537- ...Intervention Center for...
538- ...Student1 Student1...
539- ...Messages and Observations...
540- ...There are none...
541- ...New Message...
542- ...Goals and Interventions...
543- ...There are none...
544- ...New Goal...
545- ...Change of Status Messages...
546- ...There are none...
547- ...New Status Message...
548-
549-Another way of getting to a student's intervention center is using the
550-link found on the student's view page.
551-
552- >>> manager.getLink('Manage').click()
553- >>> manager.getLink('Persons').click()
554- >>> manager.getLink('Student1').click()
555- >>> manager.getLink('Intervention Center').click()
556- >>> print manager.contents
557- <BLANKLINE>
558- ...Intervention Center for...
559- ...Student1 Student1...
560-
561-
562-Intervention Messages
563----------------------
564-
565-The first thing we'll add is a new message. Calling up the add view, we'll
566-note that the list of possible recipients will include, in order, the student's
567-advisors, the school administrators, the student's teachers, the student,
568-and the student's parents. Advisors and parents will have all caps prefixes
569-before their names to make it easier for the user to pick them out. Also,
570-the advisors will be pre-checked.
571-
572- >>> manager.getLink('New Message').click()
573- >>> print manager.contents
574- <BLANKLINE>
575- ...Recipients...
576- ...checked="checked"...
577- ...ADVISOR: Teacher2...
578- ...Counselor...
579- ...Principal...
580- ...Teacher1...
581- ...Student1...
582- ...PARENT: Parent1...
583-
584-We'll test how the add view handles missing input. We'll need to uncheck the
585-advisor to make the recipients input cause the error.
586-
587- >>> manager.getControl(name='person.teacher2').value = False
588- >>> manager.getControl(name='UPDATE_SUBMIT').click()
589- >>> print manager.contents
590- <BLANKLINE>
591- ...There are <strong>2</strong> input errors...
592- ...Required data was not supplied...
593- ...Required input is missing...
594-
595-We'll fill in the required fields and hit the Add button. Note that upon
596-successfully adding the message, an email will appear in the output. This
597-is the result of the dummy mail sender that we use during testing that prints
598-emails that would otherwise be sent to the smtp mail server that a live
599-environment would have configured. Also note that the parent's email address
600-will be picked up from the student's demos.
601-
602- >>> manager.getControl(name='person.teacher1').value = True
603- >>> manager.getControl(name='person.student1:1').value = True
604- >>> manager.getControl(name='field.body').value = 'hi'
605- >>> manager.getControl(name='UPDATE_SUBMIT').click()
606- Content-Type: text/plain; charset="utf-8"
607- MIME-Version: 1.0
608- Content-Transfer-Encoding: 7bit
609- From: manager@scienceleadership.org
610- To: parent@somewhere.com, teacher1@scienceleadership.org
611- Subject: INTERVENTION MESSAGE: Student1 Student1
612- Date: ...
613- <BLANKLINE>
614- SchoolTool Administrator writes:
615- <BLANKLINE>
616- hi
617-
618-Note that the successfully added message appears in the Intervention Center
619-with the username of the sender, in this case, manager.
620-
621- >>> print manager.contents
622- <BLANKLINE>
623- ...Messages and Observations...
624- ...Message from SchoolTool Administrator...
625- ...New Message...
626-
627-Let's make sure we can view the message that we just added.
628-
629- >>> manager.getLink('Message from SchoolTool Administrator').click()
630- >>> print manager.contents
631- <BLANKLINE>
632- ...Message from: SchoolTool Administrator...
633- ...To:...
634- ...Parent1 Parent1...
635- ...Teacher1 Teacher1...
636- ...Message body...
637- ...hi...
638-
639-We should be able to return to the Intervention Center with a link.
640-
641- >>> manager.getLink('Intervention Center').click()
642- >>> print manager.contents
643- <BLANKLINE>
644- ...Messages and Observations...
645- ...Message from SchoolTool Administrator...
646- ...New Message...
647-
648-We'll add a second message to test the system's handling of multiple
649-messages. Messages are sorted by date.
650-
651- >>> manager.getLink('New Message').click()
652- >>> manager.getControl(name='person.teacher1').value = True
653- >>> manager.getControl(name='field.body').value = 'hello again'
654- >>> manager.getControl(name='UPDATE_SUBMIT').click()
655- Content-Type: text/plain; charset="utf-8"
656- MIME-Version: 1.0
657- Content-Transfer-Encoding: 7bit
658- From: manager@scienceleadership.org
659- To: teacher1@scienceleadership.org, teacher2@scienceleadership.org
660- Subject: INTERVENTION MESSAGE: Student1 Student1
661- Date: ...
662- <BLANKLINE>
663- SchoolTool Administrator writes:
664- <BLANKLINE>
665- hello again
666- >>> print manager.contents
667- <BLANKLINE>
668- ...Messages and Observations...
669- ...student1/messages/2...Message from SchoolTool Administrator...
670- ...student1/messages/1...Message from SchoolTool Administrator...
671- ...New Message...
672-
673-There is a button that allows us to call up the report that presents all of
674-the messages together. The messages are sorted by creation date.
675-
676- >>> manager.getLink('View All Messages').click()
677- >>> print manager.contents
678- <BLANKLINE>
679- ...Messages regarding Student1 Student1...
680- ...Message sent by SchoolTool Administrator...
681- ...To:...
682- ...Teacher1 Teacher1...
683- ...Teacher2 Teacher2...
684- ...hello again...
685- ...Message sent by SchoolTool Administrator...
686- ...To:...
687- ...Parent1 Parent1...
688- ...Teacher1 Teacher1...
689- ...hi...
690-
691-We'll return the the Intervention Center.
692-
693- >>> manager.getLink('Intervention Center').click()
694- >>> print manager.contents
695- <BLANKLINE>
696- ...Messages and Observations...
697- ...Message from SchoolTool Administrator...
698- ...Message from SchoolTool Administrator...
699- ...New Message...
700-
701-Intervention Goals
702-------------------
703-
704-The next thing to start adding is Goals. We'll test how the add view
705-handles missing input while we're at it. To make the persons responsible
706-field have missing data, we'll need to uncheck the advisor that comes
707-pre-checked.
708-
709- >>> from datetime import date
710- >>> manager.getLink('New Goal').click()
711- >>> manager.getControl(name='person.teacher2').value = False
712- >>> manager.getControl(name='UPDATE_SUBMIT').click()
713- >>> print manager.contents
714- <BLANKLINE>
715- ...There are <strong>7</strong> input errors...
716- ...Presenting concerns...
717- ...Required input is missing...
718- ...Goal...
719- ...Required input is missing...
720- ...Strengths...
721- ...Required input is missing...
722- ...Indicators...
723- ...Required input is missing...
724- ...Intervention...
725- ...Required input is missing...
726- ...Timeline...
727- ...Required input is missing...
728- ...Persons responsible...
729- ...Required data was not supplied...
730- ...checked="checked"...
731- ...Goal Not Met...
732- ...Goal Met...
733-
734-Now we'll fill in the required fields. We'll include the student and the
735-parent in the persons responsible list to demostrate how adding the goal
736-will split the email by staff and students/parents. Students and parents
737-will not get a link back to the intervention center in their email.
738-
739- >>> manager.getControl('Presenting concerns').value = 'Poor attendence'
740- >>> manager.getControl(name='field.goal').value = 'Get student to come in more often'
741- >>> manager.getControl('Strengths').value = 'Attentive when there'
742- >>> manager.getControl('Indicators').value = 'Student appears at least 4 time a week'
743- >>> manager.getControl('Intervention').value = 'Call parents to arrange better attendence'
744- >>> manager.getControl('Timeline').value = str(date.today())
745- >>> manager.getControl(name='person.teacher1').value = True
746- >>> manager.getControl(name='person.student1').value = True
747- >>> manager.getControl(name='person.student1:1').value = True
748- >>> manager.getControl(name='goal_met').value = ['Yes']
749- >>> manager.getControl(name='UPDATE_SUBMIT').click()
750- Content-Type: text/plain; charset="utf-8"
751- MIME-Version: 1.0
752- Content-Transfer-Encoding: 7bit
753- From: manager@scienceleadership.org
754- To: teacher1@scienceleadership.org
755- Subject: INTERVENTION GOAL ADDED: Student1 Student1
756- Date: ...
757- <BLANKLINE>
758- The following goal was added for Student1 Student1:
759- <BLANKLINE>
760- Presenting concerns
761- -------------------
762- <BLANKLINE>
763- Poor attendence
764- <BLANKLINE>
765- Goal
766- ----
767- <BLANKLINE>
768- Get student to come in more often
769- <BLANKLINE>
770- Strengths
771- ---------
772- <BLANKLINE>
773- Attentive when there
774- <BLANKLINE>
775- Indicators
776- ----------
777- <BLANKLINE>
778- Student appears at least 4 time a week
779- <BLANKLINE>
780- Intervention
781- ------------
782- <BLANKLINE>
783- Call parents to arrange better attendence
784- <BLANKLINE>
785- Timeline
786- --------
787- <BLANKLINE>
788- ...
789- <BLANKLINE>
790- Persons responsible
791- -------------------
792- <BLANKLINE>
793- Parent1 Parent1
794- Student1 Student1
795- Teacher1 Teacher1
796- <BLANKLINE>
797- Intervention Center
798- -------------------
799- <BLANKLINE>
800- http://localhost/schooltool.interventions/2005-2006/student1
801- <BLANKLINE>
802- Content-Type: text/plain; charset="utf-8"
803- MIME-Version: 1.0
804- Content-Transfer-Encoding: 7bit
805- From: manager@scienceleadership.org
806- To: parent@somewhere.com, student1@scienceleadership.org
807- Subject: INTERVENTION GOAL ADDED: Student1 Student1
808- Date: ...
809- <BLANKLINE>
810- The following goal was added for Student1 Student1:
811- <BLANKLINE>
812- Presenting concerns
813- -------------------
814- <BLANKLINE>
815- Poor attendence
816- <BLANKLINE>
817- Goal
818- ----
819- <BLANKLINE>
820- Get student to come in more often
821- <BLANKLINE>
822- Strengths
823- ---------
824- <BLANKLINE>
825- Attentive when there
826- <BLANKLINE>
827- Indicators
828- ----------
829- <BLANKLINE>
830- Student appears at least 4 time a week
831- <BLANKLINE>
832- Intervention
833- ------------
834- <BLANKLINE>
835- Call parents to arrange better attendence
836- <BLANKLINE>
837- Timeline
838- --------
839- <BLANKLINE>
840- ...
841- <BLANKLINE>
842- Persons responsible
843- -------------------
844- <BLANKLINE>
845- Parent1 Parent1
846- Student1 Student1
847- Teacher1 Teacher1
848-
849-Note that the successfully added goal appears in the Intervention Center as
850-'Goal 1'.
851-
852- >>> print manager.contents
853- <BLANKLINE>
854- ...Goals and Interventions...
855- ...Goal 1...
856- ...New Goal...
857-
858-Let's make sure we can view the message that we just added.
859-
860- >>> manager.getLink('Goal 1').click()
861- >>> print manager.contents
862- <BLANKLINE>
863- ...Presenting concerns...
864- ...Poor attendence...
865- ...Goal...
866- ...Get student to come in more often...
867- ...Strengths...
868- ...Attentive when there...
869- ...Indicators...
870- ...Student appears at least 4 time a week...
871- ...Intervention...
872- ...Call parents to arrange better attendence...
873- ...Timeline...
874- ...Persons responsible...
875- ...Parent1 Parent1...
876- ...Student1 Student1...
877- ...Teacher1 Teacher1...
878- ...Goal met...
879- ...Yes...
880- ...Follow up notes...
881-
882-Now that we've added a goal, let's edit it's strengths attribute and see that
883-the change is reflected in the goal's view.
884-
885- >>> manager.getLink('Edit').click()
886- >>> print manager.contents
887- <BLANKLINE>
888- ...Goal Not Met...
889- ...checked="checked"...
890- ...Goal Met...
891- >>> manager.getControl('Strengths').value = 'Good listener'
892- >>> manager.getControl(name='UPDATE_SUBMIT').click()
893- >>> print manager.contents
894- <BLANKLINE>
895- ...Strengths...
896- ...Good listener...
897- ...Indicators...
898-
899-We should be able to return to the Intervention Center with a link.
900-
901- >>> manager.getLink('Intervention Center').click()
902- >>> print manager.contents
903- <BLANKLINE>
904- ...Goals and Interventions...
905- ...Goal 1...
906- ...New Goal...
907-
908-Let's add a second goal to test our handling of multiple goals both in the
909-notification view and the goals report.
910-
911- >>> manager.getLink('New Goal').click()
912- >>> manager.getControl('Presenting concerns').value = 'Rude behavior'
913- >>> manager.getControl(name='field.goal').value = 'Get student to be more polite'
914- >>> manager.getControl('Strengths').value = 'Good grades'
915- >>> manager.getControl('Indicators').value = 'Student no longer offends classmates'
916- >>> manager.getControl('Intervention').value = 'Call parents to alert them to bad manners'
917- >>> manager.getControl('Timeline').value = str(date.today())
918- >>> manager.getControl(name='person.teacher2').value = False
919- >>> manager.getControl(name='person.teacher1').value = True
920- >>> manager.getControl(name='UPDATE_SUBMIT').click()
921- Content-Type: text/plain; charset="utf-8"
922- MIME-Version: 1.0
923- Content-Transfer-Encoding: 7bit
924- From: manager@scienceleadership.org
925- To: teacher1@scienceleadership.org
926- Subject: INTERVENTION GOAL ADDED: Student1 Student1
927- Date: ...
928- <BLANKLINE>
929- The following goal was added for Student1 Student1:
930- <BLANKLINE>
931- Presenting concerns
932- -------------------
933- <BLANKLINE>
934- Rude behavior
935- <BLANKLINE>
936- Goal
937- ----
938- <BLANKLINE>
939- Get student to be more polite
940- <BLANKLINE>
941- Strengths
942- ---------
943- <BLANKLINE>
944- Good grades
945- <BLANKLINE>
946- Indicators
947- ----------
948- <BLANKLINE>
949- Student no longer offends classmates
950- <BLANKLINE>
951- Intervention
952- ------------
953- <BLANKLINE>
954- Call parents to alert them to bad manners
955- <BLANKLINE>
956- Timeline
957- --------
958- <BLANKLINE>
959- ...
960- <BLANKLINE>
961- Persons responsible
962- -------------------
963- <BLANKLINE>
964- Teacher1 Teacher1
965- <BLANKLINE>
966- Intervention Center
967- -------------------
968- <BLANKLINE>
969- http://localhost/schooltool.interventions/2005-2006/student1
970- >>> print manager.contents
971- <BLANKLINE>
972- ...Goals and Interventions...
973- ...Goal 1...
974- ...Goal 2...
975- ...New Goal...
976-
977-There is a button that allows us to call up the report that presents all of
978-the goals together. Its output is a concatonation of what the view of goal 1
979-and the view of goal 2 would present.
980-
981- >>> manager.getLink('View All Goals').click()
982- >>> print manager.contents
983- <BLANKLINE>
984- ...Presenting concerns...
985- ...Poor attendence...
986- ...Goal...
987- ...Get student to come in more often...
988- ...Strengths...
989- ...Good listener...
990- ...Indicators...
991- ...Student appears at least 4 time a week...
992- ...Intervention...
993- ...Call parents to arrange better attendence...
994- ...Timeline...
995- ...Persons responsible...
996- ...Parent1 Parent1...
997- ...Student1 Student1...
998- ...Teacher1 Teacher1...
999- ...Goal met...
1000- ...Yes...
1001- ...Follow up notes...
1002- ...Presenting concerns...
1003- ...Rude behavior...
1004- ...Goal...
1005- ...Get student to be more polite...
1006- ...Strengths...
1007- ...Good grades...
1008- ...Indicators...
1009- ...Student no longer offends classmates...
1010- ...Intervention...
1011- ...Call parents to alert them to bad manners...
1012- ...Timeline...
1013- ...Persons responsible...
1014- ...Teacher1 Teacher1...
1015- ...Goal met...
1016- ...No...
1017- ...Follow up notes...
1018-
1019-We have a view that can be called up at any time that will send emails for
1020-goals that have come due today (we set up our goals to be due today). This
1021-view will best be called automatically from a cron job making it a completely
1022-automated system. Note that student and parent entered in the first goal will
1023-not receive this email.
1024-
1025- >>> manager.open('http://localhost/schooltool.interventions/notifyGoals.html')
1026- Content-Type: text/plain; charset="utf-8"
1027- MIME-Version: 1.0
1028- Content-Transfer-Encoding: 7bit
1029- From: manager@scienceleadership.org
1030- To: teacher1@scienceleadership.org
1031- Subject: INTERVENTION GOAL DUE: Student1 Student1
1032- Date: ...
1033- <BLANKLINE>
1034- Please follow the link below to update the follow up notes and, if
1035- appropriate, the goal met status of the intervention goal for Student1 Student1.
1036- <BLANKLINE>
1037- http://localhost/schooltool.interventions/2005-2006/student1/goals/1/@@editGoal.html
1038- Content-Type: text/plain; charset="utf-8"
1039- MIME-Version: 1.0
1040- Content-Transfer-Encoding: 7bit
1041- From: manager@scienceleadership.org
1042- To: teacher1@scienceleadership.org
1043- Subject: INTERVENTION GOAL DUE: Student1 Student1
1044- Date: ...
1045- <BLANKLINE>
1046- Please follow the link below to update the follow up notes and, if
1047- appropriate, the goal met status of the intervention goal for Student1 Student1.
1048- <BLANKLINE>
1049- http://localhost/schooltool.interventions/2005-2006/student1/goals/2/@@editGoal.html
1050-
1051- >>> print manager.contents
1052- <BLANKLINE>
1053- ...The following goals had notifications sent to the persons responsible:...
1054- ...Student1 Student1 goal 1...
1055- ...Student1 Student1 goal 2...
1056-
1057-Now that the goals have been marked as notified, calling up the view again will
1058-yield nothing.
1059-
1060- >>> manager.open('http://localhost/schooltool.interventions/notifyGoals.html')
1061- >>> print manager.contents
1062- <BLANKLINE>
1063- ...There are no goals that need notification...
1064-
1065-Let's get back to intervention startup page and search for any student
1066-with at least one goal.
1067-
1068- >>> manager.getLink('Intervention').click()
1069- >>> manager.getControl(name='ADDITIONAL_FILTER').value = ['WITH_GOAL']
1070- >>> manager.getControl(name='SEARCH_BUTTON').click()
1071- >>> print manager.contents
1072- <BLANKLINE>
1073- ...
1074- ...Student1 Student1...
1075-
1076- >>> manager.getControl(name='CLEAR_SEARCH').click()
1077-
1078-
1079-Change of Status Messages
1080--------------------------
1081-
1082-There is a need for special change of status messages that would rarely be
1083-sent and should be organized at the bottom part of the Intervention Center.
1084-The most extreme example of changing a student's status would be to expel
1085-the student from school. Messages of that nature and less extreme can be
1086-added using the separate 'Change of Status Messages' section of the student's
1087-Intervention Center.
1088-
1089-
1090- >>> manager.getLink('Intervention').click()
1091- >>> manager.getControl(name='SEARCH').value = 'Student'
1092- >>> manager.getControl(name='SEARCH_BUTTON').click()
1093- >>> manager.getLink('Student1').click()
1094-
1095- >>> manager.getLink('New Status Message').click()
1096- >>> manager.getControl(name='person.teacher2').value = False
1097- >>> manager.getControl(name='person.teacher1').value = True
1098- >>> manager.getControl(name='field.body').value = 'hello'
1099- >>> manager.getControl(name='UPDATE_SUBMIT').click()
1100- Content-Type: text/plain; charset="utf-8"
1101- MIME-Version: 1.0
1102- Content-Transfer-Encoding: 7bit
1103- From: manager@scienceleadership.org
1104- To: teacher1@scienceleadership.org
1105- Subject: INTERVENTION STATUS CHANGE: Student1 Student1
1106- Date: ...
1107- <BLANKLINE>
1108- SchoolTool Administrator writes:
1109- <BLANKLINE>
1110- hello
1111- >>> print manager.contents
1112- <BLANKLINE>
1113- ...Messages and Observations...
1114- ...Message from SchoolTool Administrator...
1115- ...Message from SchoolTool Administrator...
1116- ...New Message...
1117- ...Change of Status Messages...
1118- ...Change of Status Message from SchoolTool Administrator...
1119- ...New Status Message...
1120-
1121-Let's make sure we can view the message that we just added.
1122-
1123- >>> manager.getLink('Change of Status Message from SchoolTool Administrator').click()
1124- >>> print manager.contents
1125- <BLANKLINE>
1126- ...Change of Status Message from: SchoolTool Administrator...
1127- ...To:...
1128- ...Teacher1 Teacher1...
1129- ...Message body...
1130- ...hello...
1131-
1132-There is a view for viewing all change of status messages together as there
1133-is with normal messages.
1134-
1135- >>> manager.getLink('Intervention Center').click()
1136- >>> manager.getLink('View All Status Messages').click()
1137- >>> print manager.contents
1138- <BLANKLINE>
1139- ...Change of Status Messages regarding Student1 Student1...
1140- ...Message sent by SchoolTool Administrator...
1141- ...To:...
1142- ...Teacher1 Teacher1...
1143- ...hello...
1144-
1145-Section intervention view
1146--------------------------
1147-
1148-The section intervention view gives quick access to various
1149-intervention views for students in the section.
1150-
1151- >>> manager.getLink('Manage').click()
1152- >>> manager.getLink('School Years').click()
1153- >>> manager.getLink('2005-2006').click()
1154- >>> manager.getLink('Spring').click()
1155- >>> manager.getLink('Sections').click()
1156- >>> manager.getLink('section1').click()
1157- >>> manager.getLink('Interventions').click()
1158-
1159-The Messages tab is the default. The provided links allow the teacher to
1160-preview existing and compose new messages. Note that status messages are
1161-ignored when displaying message count for the student.
1162-
1163- >>> print manager.contents
1164- <BLANKLINE>
1165- ...course1 - section1's Student Interventions...
1166- ...Intervention...
1167- <p>Messages</p> ...
1168- <a ...Goals</a> ...
1169- ...Student1 Student1...
1170- ...View Messages (2)...
1171- ...Write New...
1172- ...Student3 Student3...
1173- ...View Messages (0)...
1174- ...Write New...
1175-
1176-The Goals tab provides shortcuts to viewing student goals.
1177-
1178- >>> manager.getLink('Goals').click()
1179- >>> print manager.contents
1180- <BLANKLINE>
1181- ...course1 - section1's Student Interventions...
1182- ...Intervention...
1183- <a ...Messages</a> ...
1184- <p>Goals</p> ...
1185- ...Student1 Student1...
1186- ...View Goals (2)...
1187- ...Student3 Student3...
1188- ...View Goals (0)...
1189-
1190-Security
1191---------
1192-
1193-We will allow only managers, administrators and teachers to access
1194-interventions. Teachers do not need to have the student in their class
1195-to work with an intervention. They just need to be in the teachers group.
1196-
1197- >>> teacher2 = setup.logIn('teacher1', 'pwd')
1198- >>> principal = setup.logIn('principal', 'pwd')
1199- >>> student1 = setup.logIn('student1', 'pwd')
1200-
1201-Teacher2 should have no problem accessing the intervention for Student3,
1202-even though he does not teach that student.
1203-
1204- >>> teacher2.getLink('Intervention').click()
1205- >>> teacher2.getControl(name='SEARCH').value = 'Student3'
1206- >>> teacher2.getControl(name='SEARCH_BUTTON').click()
1207- >>> teacher2.getLink('Student3 Student3').click()
1208- >>> print teacher2.contents
1209- <BLANKLINE>
1210- ...Intervention Center for...
1211- ...Student3 Student3...
1212-
1213-Our principal doesn't teach anyone, but he will have no problem accessing the
1214-same intervention.
1215-
1216- >>> principal.open(teacher2.url)
1217- >>> print principal.contents
1218- <BLANKLINE>
1219- ...Intervention Center for...
1220- ...Student3 Student3...
1221-
1222-Our site manager doesn't teach anyone, but he will have no problem accessing the
1223-same intervention.
1224-
1225- >>> manager.open(teacher2.url)
1226- >>> print manager.contents
1227- <BLANKLINE>
1228- ...Intervention Center for...
1229- ...Student3 Student3...
1230-
1231-A student shall not be allowed to look at an intervention.
1232-
1233- >>> student1.open(teacher2.url)
1234- Traceback (most recent call last):
1235- ...
1236- Unauthorized: ...
1237-
1238-And of course, unauthenticated users shouldn't be able to get to a student's
1239-intervention center.
1240-
1241- >>> from zope.testbrowser.testing import Browser
1242- >>> unauth = Browser()
1243- >>> unauth.handleErrors = False
1244- >>> unauth.open(teacher2.url)
1245- Traceback (most recent call last):
1246- ...
1247- Unauthorized: ...
1248-
1249
1250=== removed file 'src/schooltool/intervention/browser/__init__.py'
1251--- src/schooltool/intervention/browser/__init__.py 2008-04-18 04:35:30 +0000
1252+++ src/schooltool/intervention/browser/__init__.py 1970-01-01 00:00:00 +0000
1253@@ -1,1 +0,0 @@
1254-#
1255
1256=== removed file 'src/schooltool/intervention/browser/configure.zcml'
1257--- src/schooltool/intervention/browser/configure.zcml 2009-07-23 07:08:31 +0000
1258+++ src/schooltool/intervention/browser/configure.zcml 1970-01-01 00:00:00 +0000
1259@@ -1,320 +0,0 @@
1260-<?xml version="1.0" encoding="utf-8"?>
1261-<configure xmlns="http://namespaces.zope.org/browser"
1262- xmlns:zope="http://namespaces.zope.org/zope"
1263- xmlns:z3c="http://namespaces.zope.org/z3c"
1264- i18n_domain="schooltool">
1265-
1266- <!-- form macros -->
1267- <z3c:macro
1268- name="widget-row"
1269- template="macros.pt"
1270- layer="schooltool.intervention.browser.skin.IInterventionLayer"
1271- />
1272-
1273- <!-- Navigation Tab and Startup View -->
1274- <navigationViewlet
1275- name="Intervention"
1276- for="*"
1277- manager="schooltool.skin.skin.INavigationManager"
1278- template="intervention_tab.pt"
1279- permission="schooltool.view"
1280- link="intervention.html"
1281- order="310"
1282- />
1283- <page
1284- name="intervention.html"
1285- for="schooltool.intervention.interfaces.IInterventionSchoolYear"
1286- class=".intervention.InterventionStartupView"
1287- template="intervention_startup.pt"
1288- permission="schooltool.view"
1289- />
1290-
1291- <!-- Interventions -->
1292- <configure package="schooltool.skin">
1293- <addform
1294- label="New Message"
1295- name="addMessage.html"
1296- schema="schooltool.intervention.interfaces.IInterventionMessage"
1297- fields="recipients body"
1298- arguments="recipients body"
1299- content_factory="schooltool.intervention.intervention.InterventionMessage"
1300- permission="schooltool.edit"
1301- template="templates/simple_add.pt"
1302- class="schooltool.intervention.browser.intervention.InterventionMessageAddView">
1303- <widget field="description" height="5" />
1304- </addform>
1305- <addform
1306- label="New Status Message"
1307- name="addStatusMessage.html"
1308- schema="schooltool.intervention.interfaces.IInterventionMessage"
1309- fields="recipients body"
1310- arguments="recipients body"
1311- content_factory="schooltool.intervention.intervention.InterventionMessage"
1312- permission="schooltool.edit"
1313- template="templates/simple_add.pt"
1314- class="schooltool.intervention.browser.intervention.InterventionStatusMessageAddView">
1315- <widget field="description" height="5" />
1316- </addform>
1317- </configure>
1318- <addform
1319- label="New Goal"
1320- name="addGoal.html"
1321- schema="schooltool.intervention.interfaces.IInterventionGoal"
1322- fields="presenting_concerns goal strengths indicators intervention timeline persons_responsible goal_met follow_up_notes"
1323- arguments="presenting_concerns goal strengths indicators intervention timeline persons_responsible"
1324- keyword_arguments="goal_met follow_up_notes"
1325- content_factory="schooltool.intervention.intervention.InterventionGoal"
1326- permission="schooltool.edit"
1327- template="goal_add.pt"
1328- class="schooltool.intervention.browser.intervention.InterventionGoalAddView">
1329- <widget field="presenting_concerns" width="54" height="10" />
1330- <widget field="goal" width="54" height="10" />
1331- <widget field="strengths" width="54" height="10" />
1332- <widget field="indicators" width="54" height="10" />
1333- <widget field="intervention" width="54" height="10" />
1334- <widget field="follow_up_notes" width="54" height="10" />
1335- </addform>
1336- <editform
1337- label="Edit Goal"
1338- name="editGoal.html"
1339- for="schooltool.intervention.interfaces.IInterventionGoal"
1340- schema="schooltool.intervention.interfaces.IInterventionGoal"
1341- fields="presenting_concerns goal strengths indicators intervention timeline persons_responsible goal_met follow_up_notes"
1342- template="goal_edit.pt"
1343- permission="schooltool.edit"
1344- class="schooltool.intervention.browser.intervention.InterventionGoalEditView"
1345- title="Edit Goal">
1346- <widget field="presenting_concerns" width="54" height="10" />
1347- <widget field="goal" width="54" height="10" />
1348- <widget field="strengths" width="54" height="10" />
1349- <widget field="indicators" width="54" height="10" />
1350- <widget field="intervention" width="54" height="10" />
1351- <widget field="follow_up_notes" width="54" height="10" />
1352- </editform>
1353- <page
1354- name="index.html"
1355- for="schooltool.intervention.interfaces.IInterventionStudent"
1356- class=".intervention.InterventionStudentView"
1357- template="intervention.pt"
1358- permission="schooltool.edit"
1359- layer=".skin.IInterventionLayer"
1360- />
1361- <page
1362- name="allMessages.html"
1363- for="schooltool.intervention.interfaces.IInterventionMessages"
1364- class=".intervention.InterventionMessagesView"
1365- template="intervention_messages.pt"
1366- permission="schooltool.edit"
1367- layer=".skin.IInterventionLayer"
1368- />
1369- <page
1370- name="allStatusMessages.html"
1371- for="schooltool.intervention.interfaces.IInterventionMessages"
1372- class=".intervention.InterventionStatusMessagesView"
1373- template="intervention_messages.pt"
1374- permission="schooltool.edit"
1375- layer=".skin.IInterventionLayer"
1376- />
1377- <page
1378- name="index.html"
1379- for="schooltool.intervention.interfaces.IInterventionMessage"
1380- class=".intervention.InterventionMessageView"
1381- template="intervention_message.pt"
1382- permission="schooltool.edit"
1383- layer=".skin.IInterventionLayer"
1384- />
1385- <page
1386- name="allGoals.html"
1387- for="schooltool.intervention.interfaces.IInterventionGoals"
1388- class=".intervention.InterventionGoalsView"
1389- template="goals_report.pt"
1390- permission="schooltool.edit"
1391- layer=".skin.IInterventionLayer"
1392- />
1393- <page
1394- name="index.html"
1395- for="schooltool.intervention.interfaces.IInterventionGoal"
1396- class=".intervention.InterventionGoalView"
1397- template="intervention_goal.pt"
1398- permission="schooltool.edit"
1399- layer=".skin.IInterventionLayer"
1400- />
1401-
1402- <resource name="sla_report_logo.png"
1403- file="sla_logo.png"
1404- layer="schooltool.skin.ISchoolToolLayer" />
1405-
1406- <!-- Special view for notifying persons responsible for goals that
1407- have come due -->
1408- <page
1409- name="notifyGoals.html"
1410- for="schooltool.intervention.interfaces.IInterventionRoot"
1411- class=".intervention.NotifyGoalsView"
1412- template="notify_goals.pt"
1413- permission="schooltool.edit"
1414- layer=".skin.IInterventionLayer"
1415- />
1416-
1417- <!-- Intervention reports -->
1418- <navigationViewlet
1419- name="schooltool.intervention.reports_action"
1420- for="*"
1421- manager="schooltool.skin.IActionMenuManager"
1422- permission="schooltool.view"
1423- template="reportsViewlet.pt"
1424- class=".reports.ReportsViewlet"
1425- title="Reports"
1426- />
1427- <viewletManager
1428- name="schooltool.intervention.reports_action_manager"
1429- permission="zope.Public"
1430- provides=".reports.IReportsViewletManager"
1431- class="schooltool.skin.skin.OrderedViewletManager"
1432- />
1433-
1434- <!-- Report menu item resources -->
1435- <resource
1436- name="reportsViewlet.css"
1437- file="reportsViewlet.css"
1438- layer="schooltool.skin.ISchoolToolLayer" />
1439- <viewlet
1440- name="reports_viewlet_css"
1441- for="*"
1442- manager="schooltool.skin.ICSSManager"
1443- class=".reports.ReportsCSSViewlet"
1444- permission="zope.View"
1445- />
1446- <resource
1447- name="reportsViewlet.js"
1448- file="reportsViewlet.js"
1449- layer="schooltool.skin.ISchoolToolLayer" />
1450- <viewlet
1451- name="reports_viewlet_js"
1452- for="*"
1453- manager="schooltool.skin.IJavaScriptManager"
1454- class=".reports.ReportsJSViewlet"
1455- permission="zope.View"
1456- />
1457-
1458- <!-- Intervention entry points from a section -->
1459- <page
1460- name="interventions.html"
1461- for="schooltool.course.interfaces.ISection"
1462- class=".intervention.SectionInterventionsView"
1463- template="section_interventions.pt"
1464- permission="schooltool.edit"
1465- layer=".skin.IInterventionLayer"
1466- />
1467-
1468- <!-- Other resources -->
1469- <resource
1470- name="section_interventions.css"
1471- file="section_interventions.css"
1472- layer="schooltool.skin.ISchoolToolLayer" />
1473-
1474- <!-- Container views -->
1475- <containerViews
1476- for="schooltool.intervention.interfaces.IInterventionMessages"
1477- contents="schooltool.view"
1478- add="schooltool.edit"
1479- />
1480- <containerViews
1481- for="schooltool.intervention.interfaces.IInterventionGoals"
1482- contents="schooltool.view"
1483- add="schooltool.edit"
1484- />
1485-
1486- <!-- Action menu buttons -->
1487- <configure package="schooltool.skin">
1488- <navigationViewlet
1489- name="schoolyear_interventions"
1490- for="schooltool.schoolyear.interfaces.ISchoolYear"
1491- manager="schooltool.skin.IActionMenuManager"
1492- template="templates/actionsViewlet.pt"
1493- permission="schooltool.edit"
1494- link="intervention/intervention.html"
1495- title="Interventions"
1496- />
1497- <navigationViewlet
1498- name="interventions"
1499- for="schooltool.course.interfaces.ISection"
1500- manager="schooltool.skin.IActionMenuManager"
1501- template="templates/actionsViewlet.pt"
1502- permission="schooltool.edit"
1503- link="@@interventions.html"
1504- title="Interventions"
1505- />
1506- <navigationViewlet
1507- name="intervention"
1508- for="schooltool.basicperson.interfaces.IBasicPerson"
1509- manager="schooltool.skin.IActionMenuManager"
1510- template="templates/actionsViewlet.pt"
1511- permission="schooltool.edit"
1512- link="intervention"
1513- title="Intervention Center"
1514- />
1515- <navigationViewlet
1516- name="message_return"
1517- for="schooltool.intervention.interfaces.IInterventionMessage"
1518- manager="schooltool.skin.IActionMenuManager"
1519- template="templates/actionsViewlet.pt"
1520- permission="schooltool.edit"
1521- link="../.."
1522- title="Intervention Center"
1523- />
1524- <navigationViewlet
1525- name="messages_return"
1526- for="schooltool.intervention.interfaces.IInterventionMessages"
1527- manager="schooltool.skin.IActionMenuManager"
1528- template="templates/actionsViewlet.pt"
1529- permission="schooltool.edit"
1530- link=".."
1531- title="Intervention Center"
1532- />
1533- <navigationViewlet
1534- name="goal_edit"
1535- for="schooltool.intervention.interfaces.IInterventionGoal"
1536- manager="schooltool.skin.IActionMenuManager"
1537- template="templates/actionsViewlet.pt"
1538- permission="schooltool.edit"
1539- link="@@editGoal.html"
1540- title="Edit"
1541- />
1542- <navigationViewlet
1543- name="goals_return"
1544- for="schooltool.intervention.interfaces.IInterventionGoals"
1545- manager="schooltool.skin.IActionMenuManager"
1546- template="templates/actionsViewlet.pt"
1547- permission="schooltool.edit"
1548- link=".."
1549- title="Intervention Center"
1550- />
1551- <navigationViewlet
1552- name="goal_return"
1553- for="schooltool.intervention.interfaces.IInterventionGoal"
1554- manager="schooltool.skin.IActionMenuManager"
1555- template="templates/actionsViewlet.pt"
1556- permission="schooltool.edit"
1557- link="../.."
1558- title="Intervention Center"
1559- />
1560- </configure>
1561-
1562- <!-- Widget registration -->
1563- <zope:view
1564- type="zope.publisher.interfaces.browser.IBrowserRequest"
1565- for="schooltool.intervention.interfaces.IPersonListField"
1566- provides="zope.app.form.interfaces.IInputWidget"
1567- factory=".widgets.PersonListWidget"
1568- permission="zope.Public"
1569- />
1570- <zope:view
1571- type="zope.publisher.interfaces.browser.IBrowserRequest"
1572- for="schooltool.intervention.interfaces.IGoalMetField"
1573- provides="zope.app.form.interfaces.IInputWidget"
1574- factory=".widgets.GoalMetWidget"
1575- permission="zope.Public"
1576- />
1577-
1578-</configure>
1579-
1580
1581=== removed file 'src/schooltool/intervention/browser/ftesting.zcml'
1582--- src/schooltool/intervention/browser/ftesting.zcml 2008-05-07 04:53:56 +0000
1583+++ src/schooltool/intervention/browser/ftesting.zcml 1970-01-01 00:00:00 +0000
1584@@ -1,28 +0,0 @@
1585-<?xml version="1.0" encoding="utf-8"?>
1586-<configure xmlns="http://namespaces.zope.org/zope"
1587- xmlns:browser="http://namespaces.zope.org/browser"
1588- i18n_domain="schooltool">
1589-
1590- <include package="schooltool.stapp2007" />
1591- <include package="schooltool.dashboard" />
1592- <include package="schooltool.gradebook" />
1593- <include package="schooltool.requirement" />
1594- <include package="schooltool.timetable" />
1595- <include package="schooltool.intervention" />
1596-
1597- <interface
1598- interface="schooltool.intervention.browser.ftests.IInterventionFtestingSkin"
1599- type="zope.publisher.interfaces.browser.IBrowserSkinType"
1600- name="Intervention"
1601- />
1602-
1603- <browser:defaultSkin name="Intervention" />
1604-
1605- <utility
1606- provides="zope.sendmail.interfaces.IMailDelivery"
1607- name="intervention"
1608- factory="schooltool.intervention.sendmail.TestMailDelivery"
1609- />
1610-
1611-</configure>
1612-
1613
1614=== removed file 'src/schooltool/intervention/browser/ftests.py'
1615--- src/schooltool/intervention/browser/ftests.py 2009-01-31 03:24:01 +0000
1616+++ src/schooltool/intervention/browser/ftests.py 1970-01-01 00:00:00 +0000
1617@@ -1,101 +0,0 @@
1618-#
1619-# SchoolTool - common information systems platform for school administration
1620-# Copyright (c) 2005 Shuttleworth Foundation
1621-#
1622-# This program is free software; you can redistribute it and/or modify
1623-# it under the terms of the GNU General Public License as published by
1624-# the Free Software Foundation; either version 2 of the License, or
1625-# (at your option) any later version.
1626-#
1627-# This program is distributed in the hope that it will be useful,
1628-# but WITHOUT ANY WARRANTY; without even the implied warranty of
1629-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1630-# GNU General Public License for more details.
1631-#
1632-# You should have received a copy of the GNU General Public License
1633-# along with this program; if not, write to the Free Software
1634-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1635-#
1636-"""
1637-Functional tests for schooltool.sla.
1638-
1639-$Id: ftests.py 6558 2007-01-10 17:17:03Z ignas $
1640-"""
1641-
1642-import unittest
1643-import os
1644-
1645-from schooltool.app.browser.ftests import setup
1646-from schooltool.testing.functional import collect_ftests
1647-from schooltool.testing.functional import ZCMLLayer
1648-from schooltool.skin.skin import ISchoolToolSkin
1649-from schooltool.basicperson.browser.skin import IBasicPersonLayer
1650-from schooltool.intervention.browser.skin import IInterventionLayer
1651-
1652-
1653-class IInterventionFtestingSkin(IInterventionLayer, IBasicPersonLayer, ISchoolToolSkin):
1654- """Skin for Intervention functional tests."""
1655-
1656-
1657-dir = os.path.abspath(os.path.dirname(__file__))
1658-filename = os.path.join(dir, 'ftesting.zcml')
1659-
1660-intervention_functional_layer = ZCMLLayer(filename,
1661- __name__,
1662- 'intervention_functional_layer')
1663-
1664-
1665-def addPerson(first_name, last_name, username, password, groups=None,
1666- browser=None):
1667- """Add a person.
1668-
1669- If username is not specified, it will be taken to be name.lower().
1670-
1671- If password is not specified, it will be taken to be username + 'pwd'.
1672- """
1673- if browser is None:
1674- browser = setup.logInManager()
1675- browser.getLink('Manage').click()
1676- browser.getLink('Persons').click()
1677- browser.getLink('New Person').click()
1678- browser.getControl('First name').value = first_name
1679- browser.getControl('Last name').value = last_name
1680- browser.getControl('Username').value = username
1681- browser.getControl('Password').value = password
1682- browser.getControl('Confirm').value = password
1683- browser.getControl('Add').click()
1684-
1685- if groups:
1686- browser.open('http://localhost/persons/%s' % username)
1687- browser.getLink('edit groups').click()
1688- for group in groups:
1689- browser.getControl(name='add_item.%s' % group).value = True
1690- browser.getControl('Add').click()
1691- browser.open('http://localhost/persons')
1692-
1693-def addCourseSectionMembers(course, section, teachers, students):
1694- setup.addCourse(course, '2005-2006')
1695- setup.addSection(course, '2005-2006', 'Spring', section)
1696- manager = setup.logInManager()
1697- manager.getLink('Manage').click()
1698- manager.getLink('School Years').click()
1699- manager.getLink('2005-2006').click()
1700- manager.getLink('Spring').click()
1701- manager.getLink('Sections').click()
1702- manager.getLink(section).click()
1703- manager.getLink('edit instructors').click()
1704- for teacher in teachers:
1705- manager.getControl(teacher).click()
1706- manager.getControl('Add').click()
1707- manager.getControl('OK').click()
1708- manager.getLink('edit individuals').click()
1709- for student in students:
1710- manager.getControl(student).click()
1711- manager.getControl('Add').click()
1712- manager.getControl('OK').click()
1713-
1714-def test_suite():
1715- return collect_ftests(layer=intervention_functional_layer)
1716-
1717-if __name__ == '__main__':
1718- unittest.main(defaultTest='test_suite')
1719
1720=== removed file 'src/schooltool/intervention/browser/goal_add.pt'
1721--- src/schooltool/intervention/browser/goal_add.pt 2008-04-27 18:16:36 +0000
1722+++ src/schooltool/intervention/browser/goal_add.pt 1970-01-01 00:00:00 +0000
1723@@ -1,96 +0,0 @@
1724-<html metal:use-macro="context/@@standard_macros/page" i18n:domain="schooltool">
1725-<body>
1726-
1727-<span metal:fill-slot="zonki" i18n:translate="">
1728- <img src="zonki.png" alt="SchoolTool" i18n:attributes="alt"
1729- tal:attributes="src context/++resource++zonki-question.png" />
1730-</span>
1731-
1732-<div metal:fill-slot="body">
1733-
1734-<style type="text/css">
1735- td {
1736- padding-left:4px;
1737- }
1738-</style>
1739-
1740- <form tal:attributes="action request/URL"
1741- method="post" enctype="multipart/form-data">
1742-
1743- <h1 tal:condition="view/label"
1744- tal:content="view/label"
1745- >Edit something</h1>
1746-
1747- <p tal:define="status view/update"
1748- tal:condition="status"
1749- tal:content="nothing" />
1750-
1751- <p tal:condition="view/errors" i18n:translate="">
1752- There are <strong tal:content="python:len(view.errors)"
1753- i18n:name="num_errors">6</strong> input errors.
1754- </p>
1755-
1756-<table border="1" style="margin-top: 1ex; margin-bottom: 1ex;">
1757- <tr>
1758- <td>
1759- <div class="row" tal:define="widget nocall:view/presenting_concerns_widget">
1760- <div metal:use-macro="context/@@form_macros/widget_row" />
1761- </div>
1762- </td>
1763- <td>
1764- <div class="row" tal:define="widget nocall:view/goal_widget">
1765- <div metal:use-macro="context/@@form_macros/widget_row" />
1766- </div>
1767- </td>
1768- <td>
1769- <div class="row" tal:define="widget nocall:view/strengths_widget">
1770- <div metal:use-macro="context/@@form_macros/widget_row" />
1771- </div>
1772- </td>
1773- </tr>
1774-
1775- <tr>
1776- <td>
1777- <div class="row" tal:define="widget nocall:view/indicators_widget">
1778- <div metal:use-macro="context/@@form_macros/widget_row" />
1779- </div>
1780- </td>
1781- <td>
1782- <div class="row" tal:define="widget nocall:view/intervention_widget">
1783- <div metal:use-macro="context/@@form_macros/widget_row" />
1784- </div>
1785- </td>
1786- <td>
1787- <div class="row" tal:define="widget nocall:view/timeline_widget">
1788- <div metal:use-macro="context/@@form_macros/widget_row" />
1789- </div>
1790- </td>
1791- </tr>
1792-
1793- <tr>
1794- <td>
1795- <div class="row" tal:define="widget nocall:view/persons_responsible_widget">
1796- <div metal:use-macro="context/@@form_macros/widget_row" />
1797- </div>
1798- </td>
1799- <td>
1800- <div class="row" tal:define="widget nocall:view/goal_met_widget">
1801- <div metal:use-macro="context/@@form_macros/widget_row" />
1802- </div>
1803- </td>
1804- <td>
1805- <div class="row" tal:define="widget nocall:view/follow_up_notes_widget">
1806- <div metal:use-macro="context/@@form_macros/widget_row" />
1807- </div>
1808- </td>
1809- </tr>
1810-</table>
1811-
1812- <tal:block metal:use-macro="view/@@standard_macros/add-button" />
1813- <tal:block metal:use-macro="view/@@standard_macros/cancel-button" />
1814-
1815- </form>
1816-
1817-</div>
1818-</body>
1819-</html>
1820
1821=== removed file 'src/schooltool/intervention/browser/goal_edit.pt'
1822--- src/schooltool/intervention/browser/goal_edit.pt 2008-04-27 18:16:36 +0000
1823+++ src/schooltool/intervention/browser/goal_edit.pt 1970-01-01 00:00:00 +0000
1824@@ -1,96 +0,0 @@
1825-<html metal:use-macro="context/@@standard_macros/page" i18n:domain="schooltool">
1826-<body>
1827-
1828-<span metal:fill-slot="zonki" i18n:translate="">
1829- <img src="zonki.png" alt="SchoolTool" i18n:attributes="alt"
1830- tal:attributes="src context/++resource++zonki-question.png" />
1831-</span>
1832-
1833-<div metal:fill-slot="body">
1834-
1835-<style type="text/css">
1836- td {
1837- padding-left:4px;
1838- }
1839-</style>
1840-
1841- <form tal:attributes="action request/URL"
1842- method="post" enctype="multipart/form-data">
1843-
1844- <h1 tal:condition="view/label"
1845- tal:content="view/label"
1846- >Edit something</h1>
1847-
1848- <p tal:define="status view/update"
1849- tal:condition="status"
1850- tal:content="nothing" />
1851-
1852- <p tal:condition="view/errors" i18n:translate="">
1853- There are <strong tal:content="python:len(view.errors)"
1854- i18n:name="num_errors">6</strong> input errors.
1855- </p>
1856-
1857-<table border="1" style="margin-top: 1ex; margin-bottom: 1ex;">
1858- <tr>
1859- <td>
1860- <div class="row" tal:define="widget nocall:view/presenting_concerns_widget">
1861- <div metal:use-macro="context/@@form_macros/widget_row" />
1862- </div>
1863- </td>
1864- <td>
1865- <div class="row" tal:define="widget nocall:view/goal_widget">
1866- <div metal:use-macro="context/@@form_macros/widget_row" />
1867- </div>
1868- </td>
1869- <td>
1870- <div class="row" tal:define="widget nocall:view/strengths_widget">
1871- <div metal:use-macro="context/@@form_macros/widget_row" />
1872- </div>
1873- </td>
1874- </tr>
1875-
1876- <tr>
1877- <td>
1878- <div class="row" tal:define="widget nocall:view/indicators_widget">
1879- <div metal:use-macro="context/@@form_macros/widget_row" />
1880- </div>
1881- </td>
1882- <td>
1883- <div class="row" tal:define="widget nocall:view/intervention_widget">
1884- <div metal:use-macro="context/@@form_macros/widget_row" />
1885- </div>
1886- </td>
1887- <td>
1888- <div class="row" tal:define="widget nocall:view/timeline_widget">
1889- <div metal:use-macro="context/@@form_macros/widget_row" />
1890- </div>
1891- </td>
1892- </tr>
1893-
1894- <tr>
1895- <td>
1896- <div class="row" tal:define="widget nocall:view/persons_responsible_widget">
1897- <div metal:use-macro="context/@@form_macros/widget_row" />
1898- </div>
1899- </td>
1900- <td>
1901- <div class="row" tal:define="widget nocall:view/goal_met_widget">
1902- <div metal:use-macro="context/@@form_macros/widget_row" />
1903- </div>
1904- </td>
1905- <td>
1906- <div class="row" tal:define="widget nocall:view/follow_up_notes_widget">
1907- <div metal:use-macro="context/@@form_macros/widget_row" />
1908- </div>
1909- </td>
1910- </tr>
1911-</table>
1912-
1913- <tal:block metal:use-macro="view/@@standard_macros/apply-button" />
1914- <tal:block metal:use-macro="view/@@standard_macros/cancel-button" />
1915-
1916- </form>
1917-
1918-</div>
1919-</body>
1920-</html>
1921
1922=== removed file 'src/schooltool/intervention/browser/goal_met.pt'
1923--- src/schooltool/intervention/browser/goal_met.pt 2008-05-03 02:01:01 +0000
1924+++ src/schooltool/intervention/browser/goal_met.pt 1970-01-01 00:00:00 +0000
1925@@ -1,14 +0,0 @@
1926-<div>
1927- <ul>
1928- <li>
1929- <input type="radio" name="goal_met" value="No"
1930- tal:attributes="checked view/goal_not_met" />
1931- <span>Goal Not Met</span>
1932- </li>
1933- <li>
1934- <input type="radio" name="goal_met" value="Yes"
1935- tal:attributes="checked view/goal_met" />
1936- <span>Goal Met</span>
1937- </li>
1938- </ul>
1939-</div>
1940
1941=== removed file 'src/schooltool/intervention/browser/goals_report.pt'
1942--- src/schooltool/intervention/browser/goals_report.pt 2008-05-01 02:51:11 +0000
1943+++ src/schooltool/intervention/browser/goals_report.pt 1970-01-01 00:00:00 +0000
1944@@ -1,81 +0,0 @@
1945-<html metal:use-macro="view/@@standard_macros/page" i18n:domain="schooltool">
1946-<head>
1947- <title metal:fill-slot="title" tal:content="string: Goals for: ${context/student/first_name} ${context/student/last_name}" />
1948-</head>
1949-<body>
1950- <h1 metal:fill-slot="content-header" i18n:translate="">
1951- <span tal:replace="string: Goals for: ${context/student/first_name} ${context/student/last_name}" />
1952- </h1>
1953-
1954-<metal:block metal:fill-slot="body">
1955-
1956-<style type="text/css">
1957- td {
1958- width: 30em;
1959- height: 10em;
1960- vertical-align: top;
1961- padding-left:4px;
1962- }
1963-</style>
1964-
1965-<table border="1" style="margin-top: 1ex;">
1966-<tal:block repeat="goal view/goals">
1967- <tr>
1968- <td colspan="3" style="height: 1em;">
1969- <h2 i18n:translate="" tal:content="goal/heading">Heading</h2>
1970- </td>
1971- </tr>
1972- <tr>
1973- <td>
1974- <h3 i18n:translate="">Presenting concerns:</h3>
1975- <p tal:content="goal/presenting_concerns" />
1976- </td>
1977- <td>
1978- <h3 i18n:translate="">Goal:</h3>
1979- <p tal:content="goal/goal" />
1980- </td>
1981- <td>
1982- <h3 i18n:translate="">Strengths:</h3>
1983- <p tal:content="goal/strengths" />
1984- </td>
1985- </tr>
1986-
1987- <tr>
1988- <td>
1989- <h3 i18n:translate="">Indicators:</h3>
1990- <p tal:content="goal/indicators" />
1991- </td>
1992- <td>
1993- <h3 i18n:translate="">Intervention:</h3>
1994- <p tal:content="goal/intervention" />
1995- </td>
1996- <td>
1997- <h3 i18n:translate="">Timeline:</h3>
1998- <p tal:content="goal/timeline" />
1999- </td>
2000- </tr>
2001-
2002- <tr>
2003- <td>
2004- <h3 i18n:translate="" tal:content="string: Persons responsible:${goal/notified}">Persons responsible:</h3>
2005- <ul>
2006- <li tal:repeat="person goal/persons_responsible">
2007- <span tal:content="person" />
2008- </li>
2009- </ul>
2010- </td>
2011- <td>
2012- <h3 i18n:translate="">Goal met:</h3>
2013- <p tal:content="goal/goal_met" />
2014- </td>
2015- <td>
2016- <h3 i18n:translate="">Follow up notes:</h3>
2017- <p tal:content="goal/follow_up_notes" />
2018- </td>
2019- </tr>
2020-</tal:block>
2021-</table>
2022-
2023-</metal:block>
2024-</body>
2025-</html>
2026
2027=== removed file 'src/schooltool/intervention/browser/intervention.pt'
2028--- src/schooltool/intervention/browser/intervention.pt 2009-07-29 04:50:33 +0000
2029+++ src/schooltool/intervention/browser/intervention.pt 1970-01-01 00:00:00 +0000
2030@@ -1,135 +0,0 @@
2031-<tal:defs define="dummy view/update" />
2032-<html metal:use-macro="view/@@standard_macros/page" i18n:domain="schooltool.sla">
2033-<head>
2034- <title metal:fill-slot="title"
2035- i18n:translate="">
2036- Student Intervention Center
2037- </title>
2038-</head>
2039-<body>
2040-
2041-<h1 metal:fill-slot="content-header"
2042- i18n:translate="">Intervention Center for
2043- <a href="" tal:content="view/studentName"
2044- tal:attributes="href view/studentURL">
2045- Student
2046- </a>
2047-</h1>
2048-
2049-<metal:block metal:fill-slot="body">
2050- <form method="post"
2051- tal:attributes="action string:${context/@@absolute_url}">
2052- <label for="schoolyear" i18n:translate=""><b>School Year</b></label>
2053- <select name="schoolyear"
2054- onchange="this.form.submit()">
2055- <tal:block repeat="schoolyear view/schoolyears">
2056- <option value="1"
2057- tal:condition="python:schoolyear['title'] != view.currentSchoolYear"
2058- tal:attributes="value schoolyear/title"
2059- tal:content="schoolyear/title" />
2060- <option value="1" selected="selected"
2061- tal:condition="python:schoolyear['title'] == view.currentSchoolYear"
2062- tal:attributes="value schoolyear/title"
2063- tal:content="schoolyear/title" />
2064- </tal:block>
2065- </select>
2066- </form>
2067- <br />
2068- <fieldset>
2069- <legend><b>Messages and Observations</b><legend>
2070- <tal:if condition="not: view/messages">
2071- <ul><li>There are none.<br /></li></ul>
2072- </tal:if>
2073- <tal:if condition="view/messages">
2074- <ul>
2075- <li tal:repeat="message view/messages">
2076- <a href="" tal:content="message/text"
2077- tal:attributes="href message/url">
2078- Message
2079- </a>
2080- </li>
2081- </ul>
2082- </tal:if>
2083- <a class="button-ok" href="" title="New Message"
2084- tal:condition="view/isCurrentSchoolYear"
2085- tal:attributes="href view/newMessageURL">
2086- New Message
2087- </a>
2088- <a class="button-ok" href="" title="View All Messages"
2089- tal:attributes="href view/allMessagesURL">
2090- View All Messages
2091- </a>
2092- </fieldset>
2093- <br />
2094- <fieldset>
2095- <legend><b>Goals and Interventions</b><legend>
2096- <tal:if condition="not: view/goals">
2097- <ul><li>There are none.<br /></li></ul>
2098- </tal:if>
2099- <tal:if condition="view/goals">
2100- <ul>
2101- <li tal:repeat="goal view/goals">
2102- <a href="" tal:content="goal/text"
2103- tal:attributes="href goal/url">
2104- Goal
2105- </a>
2106- </li>
2107- </ul>
2108- </tal:if>
2109- <a class="button-ok" href="" title="New Goal"
2110- tal:condition="view/isCurrentSchoolYear"
2111- tal:attributes="href view/newGoalURL">
2112- New Goal
2113- </a>
2114- <a class="button-ok" href="" title="View All Goals"
2115- tal:attributes="href view/allGoalsURL">
2116- View All Goals
2117- </a>
2118- </fieldset>
2119- <br />
2120- <fieldset>
2121- <legend><b>Report Sheets</b><legend>
2122- <tal:if condition="not: view/sheets">
2123- <ul><li>There are none.<br /></li></ul>
2124- </tal:if>
2125- <tal:if condition="view/sheets">
2126- <ul>
2127- <li tal:repeat="sheet view/sheets">
2128- <a href="" tal:content="sheet/text"
2129- tal:attributes="href sheet/url">
2130- Report Sheet
2131- </a>
2132- </li>
2133- </ul>
2134- </tal:if>
2135- </fieldset>
2136- <br />
2137- <fieldset>
2138- <legend><b>Change of Status Messages</b><legend>
2139- <tal:if condition="not: view/statusMessages">
2140- <ul><li>There are none.<br /></li></ul>
2141- </tal:if>
2142- <tal:if condition="view/statusMessages">
2143- <ul>
2144- <li tal:repeat="message view/statusMessages">
2145- <a href="" tal:content="message/text"
2146- tal:attributes="href message/url">
2147- Change of Status Message
2148- </a>
2149- </li>
2150- </ul>
2151- </tal:if>
2152- <a class="button-ok" href="" title="New Status Message"
2153- tal:condition="view/isCurrentSchoolYear"
2154- tal:attributes="href view/newStatusMessageURL">
2155- New Status Message
2156- </a>
2157- <a class="button-ok" href="" title="View All Messages"
2158- tal:attributes="href view/allStatusMessagesURL">
2159- View All Status Messages
2160- </a>
2161- </fieldset>
2162-</metal:block>
2163-
2164-</body>
2165-</html>
2166
2167=== removed file 'src/schooltool/intervention/browser/intervention.py'
2168--- src/schooltool/intervention/browser/intervention.py 2009-07-29 09:33:38 +0000
2169+++ src/schooltool/intervention/browser/intervention.py 1970-01-01 00:00:00 +0000
2170@@ -1,570 +0,0 @@
2171-#
2172-# SchoolTool - common information systems platform for school administration
2173-# Copyright (c) 2005 Shuttleworth Foundation
2174-#
2175-# This program is free software; you can redistribute it and/or modify
2176-# it under the terms of the GNU General Public License as published by
2177-# the Free Software Foundation; either version 2 of the License, or
2178-# (at your option) any later version.
2179-#
2180-# This program is distributed in the hope that it will be useful,
2181-# but WITHOUT ANY WARRANTY; without even the implied warranty of
2182-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2183-# GNU General Public License for more details.
2184-#
2185-# You should have received a copy of the GNU General Public License
2186-# along with this program; if not, write to the Free Software
2187-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2188-#
2189-"""
2190-Student Intervention browser views.
2191-"""
2192-from zope.traversing.api import getParents
2193-from zope.traversing.browser.absoluteurl import absoluteURL
2194-from zope.app.form.browser.editview import EditView
2195-from zope.app.form.browser.submit import Update
2196-from zope.dublincore.interfaces import IZopeDublinCore
2197-from zope.app.form.utility import setUpEditWidgets
2198-from zope.html.field import IHtmlTextField
2199-from zope.publisher.browser import BrowserView
2200-
2201-from schooltool.app.interfaces import ISchoolToolApplication
2202-from schooltool.app.browser import app
2203-from schooltool.app.membership import URIGroup, URIMembership
2204-from schooltool.common import SchoolToolMessage as _
2205-from schooltool.course.interfaces import ISection
2206-from schooltool.gradebook.interfaces import IActivities
2207-from schooltool.intervention import intervention, sendmail
2208-from schooltool.intervention.interfaces import IInterventionSchoolYear
2209-from schooltool.intervention.browser.reports import buildHTMLParagraphs
2210-from schooltool.relationship import getRelatedObjects
2211-from schooltool.schoolyear.interfaces import ISchoolYear
2212-from schooltool.schoolyear.interfaces import ISchoolYearContainer
2213-from schooltool.securitypolicy.crowds import TeachersCrowd
2214-from schooltool.term.interfaces import ITerm
2215-
2216-
2217-class InterventionStartupView(BrowserView):
2218- """Startup view for searching for a student's intervention."""
2219-
2220- def __init__(self, *args, **kw):
2221- super(InterventionStartupView, self).__init__(*args, **kw)
2222- self.additional_filter_list = [
2223- ('', _('All students')),
2224- ('WITH_GOAL', _('With set goals')),
2225- ]
2226- self.name_filter = self.request.get('SEARCH', '').lower().replace(' ', '')
2227- self.additional_filter = self.request.get('ADDITIONAL_FILTER', '')
2228-
2229- @property
2230- def additional_options(self):
2231- for opt_id, text in self.additional_filter_list:
2232- selected = None
2233- if opt_id == self.request.get('ADDITIONAL_FILTER', ''):
2234- selected = 'selected'
2235- yield {
2236- 'value': opt_id,
2237- 'text': text,
2238- 'selected': selected}
2239-
2240- @property
2241- def currentSchoolYear(self):
2242- if 'schoolyear' in self.request:
2243- return self.request['schoolyear']
2244- return ISchoolYear(self.context).title
2245-
2246- @property
2247- def schoolyears(self):
2248- results = []
2249- app = ISchoolToolApplication(None)
2250- for year in ISchoolYearContainer(app).values():
2251- interventionSchoolYear = IInterventionSchoolYear(year)
2252- result = {
2253- 'title': year.title,
2254- }
2255- results.append(result)
2256- return results
2257-
2258- @property
2259- def perform_search(self):
2260- return bool(self.name_filter or self.additional_filter)
2261-
2262- def update(self):
2263- app = ISchoolToolApplication(None)
2264- self.interventions = []
2265-
2266- schoolYearId = self.context.__name__
2267- for year in ISchoolYearContainer(app).values():
2268- if year.title == self.currentSchoolYear:
2269- schoolYearId = year.__name__
2270-
2271- if 'CLEAR_SEARCH' in self.request:
2272- self.request.form['SEARCH'] = ''
2273- self.request.form['ADDITIONAL_FILTER'] = ''
2274- self.request.form['schoolyear'] = ISchoolYear(self.context).title
2275- self.name_filter = ''
2276- self.additional_filter = ''
2277-
2278- elif 'SEARCH_BUTTON' in self.request and self.perform_search:
2279- for person in app['persons'].values():
2280- fullname = intervention.convertIdToName(person.username)
2281- if (self.name_filter and
2282- fullname.lower().replace(' ', '').find(self.name_filter) < 0):
2283- continue
2284- teachers = TeachersCrowd(self.context)
2285- if teachers.contains(person):
2286- continue
2287- interventionStudent = intervention.getInterventionStudent(
2288- person.username, schoolYearId=schoolYearId)
2289-
2290- if self.additional_filter=='WITH_GOAL':
2291- if not interventionStudent.get('goals'):
2292- continue
2293-
2294- result = {
2295- 'text': fullname,
2296- 'url': absoluteURL(interventionStudent, self.request)
2297- }
2298- self.interventions.append(result)
2299-
2300-
2301-class InterventionStudentView(object):
2302- """View for managing a student's intervention."""
2303-
2304- @property
2305- def currentSchoolYear(self):
2306- return ISchoolYear(self.context.__parent__).title
2307-
2308- @property
2309- def isCurrentSchoolYear(self):
2310- interventionSchoolYear = intervention.getInterventionSchoolYear()
2311- return interventionSchoolYear == self.context.__parent__
2312-
2313- @property
2314- def schoolyears(self):
2315- results = []
2316- student = self.context.student
2317- app = ISchoolToolApplication(None)
2318- for year in ISchoolYearContainer(app).values():
2319- interventionStudent = intervention.getInterventionStudent(
2320- student.username, year.__name__)
2321- result = {
2322- 'url': absoluteURL(interventionStudent, self.request),
2323- 'title': year.title,
2324- }
2325- results.append(result)
2326- return results
2327-
2328- def learnerOf(self):
2329- """Get the sections the student is a member of."""
2330- results = []
2331-
2332- for item in self.context.student.groups:
2333- if ISection.providedBy(item):
2334- results.append(item)
2335- else:
2336- group_sections = getRelatedObjects(item, URIGroup,
2337- rel_type=URIMembership)
2338- for section in group_sections:
2339- results.append(section)
2340- results.sort(key=lambda s: s.__name__)
2341- return results
2342-
2343- def update(self):
2344- if 'schoolyear' in self.request:
2345- title = self.request['schoolyear']
2346- if title != self.currentSchoolYear:
2347- for year in self.schoolyears:
2348- if year['title'] == title:
2349- self.request.response.redirect(year['url'])
2350-
2351- interventionURL = absoluteURL(self.context, self.request)
2352- student = self.context.student
2353- app = ISchoolToolApplication(None)
2354-
2355- self.studentURL = absoluteURL(student, self.request)
2356- self.studentName = '%s %s' % (student.first_name, student.last_name)
2357-
2358- self.messages = []
2359- for k, v in sorted(self.context['messages'].items()):
2360- if v.status_change:
2361- continue
2362- name = intervention.convertIdToName(v.sender)
2363- added = IZopeDublinCore(v).created
2364- message = {
2365- 'creation_date': added,
2366- 'url': absoluteURL(v, self.request),
2367- 'text': 'Message from %s sent %s' % (name, added.strftime('%x'))
2368- }
2369- self.messages.append(message)
2370- self.messages.sort(key=lambda m: m['creation_date'], reverse=True)
2371- self.newMessageURL = interventionURL + '/messages/+/addMessage.html'
2372- self.allMessagesURL = interventionURL + '/messages/allMessages.html'
2373-
2374- self.goals = []
2375- for k, v in sorted(self.context['goals'].items()):
2376- added = IZopeDublinCore(v).created.strftime('%x')
2377- due = v.timeline.strftime('%x')
2378- if v.goal_met:
2379- status = 'CLOSED'
2380- else:
2381- status = 'OPEN'
2382- goal = {
2383- 'url': absoluteURL(v, self.request),
2384- 'text': 'Goal %s - Added %s - Due %s - %s' % (k, added,
2385- due, status)
2386- }
2387- self.goals.append(goal)
2388- self.newGoalURL = interventionURL + '/goals/+/addGoal.html'
2389- self.allGoalsURL = interventionURL + '/goals/allGoals.html'
2390-
2391- self.sheets = []
2392- studentId = self.context.student.username
2393- currentYear = ISchoolYear(self.context.__parent__)
2394- for section in self.learnerOf():
2395- if ISchoolYear(ITerm(section)) != currentYear:
2396- continue
2397- for worksheet in IActivities(section).values():
2398- if not worksheet.deployed:
2399- continue
2400- title = '%s for %s - %s' % (worksheet.title,
2401- list(section.courses)[0].title,
2402- section.title)
2403- worksheet_url = absoluteURL(worksheet, self.request)
2404- sheet = {
2405- 'url': '%s/gradebook/%s/view.html' % (worksheet_url,
2406- studentId),
2407- 'text': title
2408- }
2409- self.sheets.append(sheet)
2410-
2411- self.statusMessages = []
2412- for k, v in sorted(self.context['messages'].items()):
2413- if not v.status_change:
2414- continue
2415- name = intervention.convertIdToName(v.sender)
2416- added = IZopeDublinCore(v).created.strftime('%x')
2417- message = {
2418- 'url': absoluteURL(v, self.request),
2419- 'text': 'Change of Status Message from %s sent %s' % (name, added)
2420- }
2421- self.statusMessages.append(message)
2422- self.newStatusMessageURL = interventionURL + '/messages/+/addStatusMessage.html'
2423- self.allStatusMessagesURL = interventionURL + '/messages/allStatusMessages.html'
2424-
2425-
2426-class SectionInterventionsView(object):
2427- """Tabbed section view showing links for adding or editing intervention data."""
2428-
2429- def __init__(self, context, request):
2430- self.context = context
2431- self.request = request
2432- self.section = '%s - %s' % (list(self.context.courses)[0].title,
2433- self.context.title)
2434- self.schoolyear = IInterventionSchoolYear(ISchoolYear(self.context))
2435- worksheets = IActivities(self.context).values()
2436- self.worksheets = [worksheet for worksheet in worksheets
2437- if worksheet.deployed]
2438- self.activeSchoolYear = intervention.getInterventionSchoolYear()
2439-
2440- def messageLinks(self, student):
2441- newMessageURL = '%s/messages/%s/+/addMessage.html' % (
2442- absoluteURL(self.context, self.request), student.__name__)
2443- allMessagesURL = '%s/messages/allMessages.html' % (
2444- absoluteURL(student, self.request))
2445- n_messages = len([m for m in student['messages'].values()
2446- if not m.status_change])
2447- result = {
2448- 'title': _('View Messages (%d)') % n_messages,
2449- 'url': allMessagesURL,
2450- }
2451- results = [result]
2452- if self.schoolyear == self.activeSchoolYear:
2453- result = {
2454- 'title': _('Write New'),
2455- 'url': newMessageURL,
2456- }
2457- results.append(result)
2458- return (results)
2459-
2460- def goalLinks(self, student):
2461- student_url = absoluteURL(student, self.request)
2462- allGoalsURL = '%s/goals/allGoals.html' % student_url
2463- n_goals = len(student['goals'])
2464- return ({'title': _('View Goals (%d)') % n_goals, 'url': allGoalsURL},
2465- )
2466-
2467- def reportSheetLinks(self, student):
2468- studentId = student.__name__
2469- results = []
2470- for worksheet in self.worksheets:
2471- worksheet_url = absoluteURL(worksheet, self.request)
2472- result = {
2473- 'title': worksheet.title,
2474- 'url': '%s/gradebook/%s' % (worksheet_url, studentId)
2475- }
2476- results.append(result)
2477- return results
2478-
2479- @property
2480- def tabs(self):
2481- """Each tab is a tuple of tab_name, (tab_title, tab_link_factory)"""
2482- results = [
2483- ('messages', (_('Messages'), self.messageLinks)),
2484- ('goals', (_('Goals'), self.goalLinks)),
2485- ]
2486- if len(self.worksheets):
2487- result = ('sheets', (_('Report Sheets'), self.reportSheetLinks))
2488- results.append(result)
2489- return results
2490-
2491-
2492- def getActiveTabName(self):
2493- default_tab = 'messages'
2494- if len(self.worksheets):
2495- default_tab = 'sheets'
2496- return self.request.get('TAB', default_tab)
2497-
2498- def iterTabs(self):
2499- url = absoluteURL(self.context, self.request) + '/interventions.html'
2500- active_tab = self.getActiveTabName()
2501- for name, tab in self.tabs:
2502- title, link_factory = tab
2503- yield {
2504- 'active': name == active_tab,
2505- 'url': '%s?TAB=%s' % (url, name),
2506- 'title': title
2507- }
2508-
2509- def listStudents(self):
2510- tab = dict(self.tabs).get(self.getActiveTabName())
2511- if tab is None:
2512- link_factory = lambda student: ()
2513- else:
2514- tab_title, link_factory = tab
2515-
2516- rows = []
2517- for student in self.context.members:
2518- interventionStudent = intervention.getInterventionStudent(
2519- student.username, schoolYearId=self.schoolyear.__name__)
2520- row = {
2521- 'name': intervention.convertIdToName(student.username),
2522- 'sortName': student.last_name + student.first_name,
2523- 'url': absoluteURL(interventionStudent, self.request),
2524- 'links': link_factory(interventionStudent),
2525- }
2526- rows.append(row)
2527-
2528- return sorted(rows, key=lambda row: row['sortName'])
2529-
2530-
2531-class InterventionMessageAddView(app.BaseAddView):
2532- """View for adding a message."""
2533-
2534- def __init__(self, context, request):
2535- super(InterventionMessageAddView, self).__init__(context, request)
2536- self.label = "PLEASE REMEMBER: This information is part of the student's record."
2537-
2538- def create(self, *args, **kw):
2539- sender = self.request.principal._person.username
2540- return self._factory(sender, *args)
2541-
2542- def nextURL(self):
2543- """If section is in the context heirachcy, return to the section
2544- interventions view. Otherwise return to the student's intervention
2545- center."""
2546- for parent in getParents(self.context):
2547- if ISection.providedBy(parent):
2548- return absoluteURL(parent, self.request) + '/interventions.html'
2549- interventionStudent = self.context.context.__parent__
2550- return absoluteURL(interventionStudent, self.request)
2551-
2552-
2553-class InterventionStatusMessageAddView(app.BaseAddView):
2554- """View for adding a message."""
2555-
2556- def create(self, *args, **kw):
2557- sender = self.request.principal._person.username
2558- kw['status_change'] = True
2559- return self._factory(sender, *args, **kw)
2560-
2561- def nextURL(self):
2562- """If section is in the context heirachcy, return to the section
2563- interventions view. Otherwise return to the student's intervention
2564- center."""
2565- for parent in getParents(self.context):
2566- if ISection.providedBy(parent):
2567- return absoluteURL(parent, self.request) + '/interventions.html'
2568- interventionStudent = self.context.context.__parent__
2569- return absoluteURL(interventionStudent, self.request)
2570-
2571-
2572-class InterventionMessageView(object):
2573- """View for viewing a message."""
2574-
2575- def __init__(self, context, request):
2576- self.context = context
2577- self.request = request
2578- sender = intervention.convertIdToName(context.sender)
2579- added = IZopeDublinCore(context).created.strftime('%x')
2580- if context.status_change:
2581- format = 'Change of Status Message from: %s sent %s'
2582- else:
2583- format = 'Message from: %s sent %s'
2584- self.heading = format % (sender, added)
2585- self.recipients = intervention.convertIdsToNames(context.recipients)
2586-
2587-
2588-class InterventionMessagesView(object):
2589- """View for viewing all messages."""
2590-
2591- def __init__(self, context, request):
2592- self.context = context
2593- self.request = request
2594- name = intervention.convertIdToName(context.student.username)
2595- self.heading = self.headingFormat % name
2596- self.messages = []
2597- for k, v in sorted(self.context.items()):
2598- if self.skipMessage(v):
2599- continue
2600- name = intervention.convertIdToName(v.sender)
2601- added = IZopeDublinCore(v).created
2602- heading = 'Message sent by %s on %s' % (name, added.strftime('%x'))
2603- recipients = intervention.convertIdsToNames(v.recipients)
2604- message = {
2605- 'creation_date': added,
2606- 'heading': heading,
2607- 'recipients': recipients,
2608- 'body': v.body,
2609- }
2610- self.messages.append(message)
2611- self.messages.sort(key=lambda m: m['creation_date'], reverse=True)
2612-
2613- def skipMessage(self, message):
2614- return message.status_change
2615-
2616- @property
2617- def headingFormat(self):
2618- return 'Messages regarding %s'
2619-
2620-
2621-class InterventionStatusMessagesView(InterventionMessagesView):
2622- """View for viewing all change of status messages."""
2623-
2624- def skipMessage(self, message):
2625- return not message.status_change
2626-
2627- @property
2628- def headingFormat(self):
2629- return 'Change of Status Messages regarding %s'
2630-
2631-
2632-class InterventionGoalAddView(app.BaseAddView):
2633- """View for adding a goal."""
2634-
2635- def nextURL(self):
2636- interventionStudent = self.context.context.__parent__
2637- return absoluteURL(interventionStudent, self.request)
2638-
2639-
2640-class InterventionGoalEditView(EditView):
2641- """View for editing a goal"""
2642-
2643- def update(self):
2644- if 'CANCEL' in self.request:
2645- self.request.response.redirect(self.nextURL())
2646- else:
2647- status = EditView.update(self)
2648- if 'UPDATE_SUBMIT' in self.request and not self.errors:
2649- self.request.response.redirect(self.nextURL())
2650- return status
2651-
2652- def nextURL(self):
2653- return absoluteURL(self.context, self.request)
2654-
2655-
2656-class InterventionGoalView(object):
2657- """View for viewing a goal."""
2658-
2659- def __init__(self, context, request):
2660- self.context = context
2661- self.request = request
2662- name = intervention.convertIdToName(context.student.username)
2663- added = IZopeDublinCore(context).created.strftime('%x')
2664- self.heading = 'Goal %s for %s added %s' % (context.__name__,
2665- name, added)
2666- self.timeline = context.timeline.strftime('%x')
2667- self.notified = ''
2668- if context.notified:
2669- self.notified = ' notification sent'
2670- self.persons_responsible = intervention.convertIdsToNames(
2671- context.persons_responsible)
2672- self.goal_met = 'No'
2673- if context.goal_met:
2674- self.goal_met = 'Yes'
2675-
2676-
2677-class InterventionGoalsView(object):
2678- """View for viewing all goals."""
2679-
2680- def __init__(self, context, request):
2681- self.context = context
2682- self.request = request
2683- self.goals = []
2684- for k, v in sorted(self.context.items()):
2685- added = IZopeDublinCore(v).created.strftime('%x')
2686- heading = 'Goal %s added %s' % (k, added)
2687- notified = ''
2688- if v.notified:
2689- notified = ' notification sent'
2690- persons_responsible = intervention.convertIdsToNames(
2691- v.persons_responsible)
2692- goal_met = 'No'
2693- if v.goal_met:
2694- goal_met = 'Yes'
2695- goal = {
2696- 'heading': heading,
2697- 'presenting_concerns': v.presenting_concerns,
2698- 'goal': v.goal,
2699- 'strengths': v.strengths,
2700- 'indicators': v.indicators,
2701- 'intervention': v.intervention,
2702- 'timeline': v.timeline.strftime('%x'),
2703- 'notified': notified,
2704- 'persons_responsible': persons_responsible,
2705- 'goal_met': goal_met,
2706- 'follow_up_notes': v.follow_up_notes,
2707- }
2708- self.goals.append(goal)
2709-
2710-
2711-class NotifyGoalsView(object):
2712- """View for notifying persons responsible for goals that
2713- have come due"""
2714-
2715- def __init__(self, context, request):
2716- self.context = context
2717- self.request = request
2718- goalsNotified = sendmail.sendInterventionGoalNotifyEmails()
2719- self.goals = []
2720- for notified in goalsNotified:
2721- name = intervention.convertIdToName(notified.student.username)
2722- goal = {
2723- 'text': '%s goal %s' % (name, notified.__name__),
2724- 'url': absoluteURL(notified, request)
2725- }
2726- self.goals.append(goal)
2727-
2728-
2729-def configureFsckWidgets(view):
2730- for name in view.fieldNames:
2731- field = view.schema.get(name)
2732- if field is not None and IHtmlTextField.implementedBy(field.__class__):
2733- editor = getattr(view, '%s_widget' % name, None)
2734- if editor is not None:
2735- editor.editorWidth = 430
2736- editor.editorHeight = 300
2737- editor.toolbarConfiguration = "schooltool"
2738- url = absoluteURL(ISchoolToolApplication(None), view.request)
2739- editor.configurationPath = (url + '/@@/editor_config.js')
2740-
2741
2742=== removed file 'src/schooltool/intervention/browser/intervention_goal.pt'
2743--- src/schooltool/intervention/browser/intervention_goal.pt 2008-04-30 04:29:55 +0000
2744+++ src/schooltool/intervention/browser/intervention_goal.pt 1970-01-01 00:00:00 +0000
2745@@ -1,74 +0,0 @@
2746-<html metal:use-macro="view/@@standard_macros/page" i18n:domain="schooltool">
2747-<head>
2748- <title metal:fill-slot="title" tal:content="view/heading" />
2749-</head>
2750-<body>
2751- <h1 metal:fill-slot="content-header" i18n:translate="">
2752- <span tal:replace="view/heading" />
2753- </h1>
2754-
2755-<metal:block metal:fill-slot="body">
2756-
2757-<style type="text/css">
2758- td {
2759- width: 30em;
2760- height: 10em;
2761- vertical-align: top;
2762- padding-left:4px;
2763- }
2764-</style>
2765-
2766-<table border="1" style="margin-top: 1ex;">
2767- <tr>
2768- <td>
2769- <h3 i18n:translate="">Presenting concerns:</h3>
2770- <p tal:content="context/presenting_concerns" />
2771- </td>
2772- <td>
2773- <h3 i18n:translate="">Goal:</h3>
2774- <p tal:content="context/goal" />
2775- </td>
2776- <td>
2777- <h3 i18n:translate="">Strengths:</h3>
2778- <p tal:content="context/strengths" />
2779- </td>
2780- </tr>
2781-
2782- <tr>
2783- <td>
2784- <h3 i18n:translate="">Indicators:</h3>
2785- <p tal:content="context/indicators" />
2786- </td>
2787- <td>
2788- <h3 i18n:translate="">Intervention:</h3>
2789- <p tal:content="context/intervention" />
2790- </td>
2791- <td>
2792- <h3 i18n:translate="">Timeline:</h3>
2793- <p tal:content="view/timeline" />
2794- </td>
2795- </tr>
2796-
2797- <tr>
2798- <td>
2799- <h3 i18n:translate="" tal:content="string: Persons responsible:${view/notified}">Persons responsible:</h3>
2800- <ul>
2801- <li tal:repeat="person view/persons_responsible">
2802- <span tal:content="person" />
2803- </li>
2804- </ul>
2805- </td>
2806- <td>
2807- <h3 i18n:translate="">Goal met:</h3>
2808- <p tal:content="view/goal_met" />
2809- </td>
2810- <td>
2811- <h3 i18n:translate="">Follow up notes:</h3>
2812- <p tal:content="context/follow_up_notes" />
2813- </td>
2814- </tr>
2815-</table>
2816-
2817-</metal:block>
2818-</body>
2819-</html>
2820
2821=== removed file 'src/schooltool/intervention/browser/intervention_message.pt'
2822--- src/schooltool/intervention/browser/intervention_message.pt 2008-05-01 05:14:02 +0000
2823+++ src/schooltool/intervention/browser/intervention_message.pt 1970-01-01 00:00:00 +0000
2824@@ -1,30 +0,0 @@
2825-<html metal:use-macro="view/@@standard_macros/page" i18n:domain="schooltool">
2826-<head>
2827- <title metal:fill-slot="title" tal:content="view/heading" />
2828-</head>
2829-<body>
2830- <h1 metal:fill-slot="content-header" i18n:translate="">
2831- <span tal:replace="view/heading" />
2832- </h1>
2833-
2834-<metal:block metal:fill-slot="body">
2835- <div>
2836-
2837- <div class="info-block">
2838- <h3 i18n:translate="">To:</h3>
2839- <ul>
2840- <li tal:repeat="recipient view/recipients">
2841- <span tal:content="recipient" />
2842- </li>
2843- </ul>
2844- </div>
2845-
2846- <div class="info-block">
2847- <h3 i18n:translate="">Message body</h3>
2848- <p tal:content="context/body" />
2849- </div>
2850-
2851- </div>
2852-</metal:block>
2853-</body>
2854-</html>
2855
2856=== removed file 'src/schooltool/intervention/browser/intervention_messages.pt'
2857--- src/schooltool/intervention/browser/intervention_messages.pt 2008-05-07 04:03:05 +0000
2858+++ src/schooltool/intervention/browser/intervention_messages.pt 1970-01-01 00:00:00 +0000
2859@@ -1,44 +0,0 @@
2860-<html metal:use-macro="view/@@standard_macros/page" i18n:domain="schooltool">
2861-<head>
2862- <title metal:fill-slot="title" tal:content="view/heading" />
2863-</head>
2864-<body>
2865- <h1 metal:fill-slot="content-header" i18n:translate="">
2866- <span tal:replace="view/heading" />
2867- </h1>
2868-
2869-<style type="text/css">
2870- td {
2871- width: 90em;
2872- height: 10em;
2873- vertical-align: top;
2874- padding-left:4px;
2875- }
2876-</style>
2877-
2878-<metal:block metal:fill-slot="body">
2879-
2880-<table border="1" style="margin-top: 1ex;">
2881-<tal:block repeat="message view/messages">
2882- <tr>
2883- <td colspan="2" style="height: 1em;">
2884- <h2 i18n:translate="" tal:content="message/heading">Heading</h2>
2885- </td>
2886- </tr>
2887- <tr>
2888- <td style="width: 30em;">
2889- <h3 i18n:translate="">To:</h3>
2890- <ul>
2891- <li tal:repeat="recipient message/recipients">
2892- <span tal:content="recipient" />
2893- </li>
2894- </ul>
2895- </td>
2896- <td style="width: 60em; vertical-align: center;" tal:content="message/body" />
2897- </tr>
2898-</tal:block>
2899-</table>
2900-
2901-</metal:block>
2902-</body>
2903-</html>
2904
2905=== removed file 'src/schooltool/intervention/browser/intervention_startup.pt'
2906--- src/schooltool/intervention/browser/intervention_startup.pt 2009-07-20 09:02:34 +0000
2907+++ src/schooltool/intervention/browser/intervention_startup.pt 1970-01-01 00:00:00 +0000
2908@@ -1,65 +0,0 @@
2909-<tal:tag condition="view/update" />
2910-<html metal:use-macro="context/@@standard_macros/page"
2911- i18n:domain="schooltool">
2912-<head>
2913- <title metal:fill-slot="title" i18n:translate="">
2914- Intervention
2915- </title>
2916-</head>
2917-<body>
2918-<div metal:fill-slot="body">
2919- <form method="post" class="batch-search">
2920- <input id="batch-search-box" type="text" name="SEARCH"
2921- tal:attributes="value request/SEARCH|nothing"/>
2922-
2923- <select name="ADDITIONAL_FILTER">
2924- <tal:block repeat="option view/additional_options">
2925- <option tal:attributes="selected option/selected|Nothing;
2926- value option/value"
2927- tal:content="option/text" />
2928- </tal:block>
2929- </select>
2930-
2931- <label for="schoolyear" i18n:translate=""><b>School Year</b></label>
2932- <select name="schoolyear">
2933- <tal:block repeat="schoolyear view/schoolyears">
2934- <option value="1"
2935- tal:condition="python:schoolyear['title'] != view.currentSchoolYear"
2936- tal:attributes="value schoolyear/title"
2937- tal:content="schoolyear/title" />
2938- <option value="1" selected="selected"
2939- tal:condition="python:schoolyear['title'] == view.currentSchoolYear"
2940- tal:attributes="value schoolyear/title"
2941- tal:content="schoolyear/title" />
2942- </tal:block>
2943- </select>
2944-
2945- <input type="submit" name="SEARCH_BUTTON" value="Find Now"
2946- i18n:attributes="value"/>
2947- <input type="submit" name="CLEAR_SEARCH" value="Clear"
2948- i18n:attributes="value"/>
2949-
2950- <div tal:condition="not: view/perform_search" style="margin-top: 2ex;">
2951- <h1>Enter any part of a student's name or select a filter
2952- from the drop-down to find an intervention.</h1>
2953- <p>Listing all students currently disabled.</p>
2954- </div>
2955- <div tal:condition="view/perform_search" style="margin-top: 2ex;">
2956- <div tal:condition="not: view/interventions">
2957- <h1>There are no students that match the search criteria.</h1>
2958- </div>
2959- <div tal:condition="view/interventions">
2960- <ul>
2961- <li tal:repeat="intervention view/interventions">
2962- <a href="" tal:content="intervention/text"
2963- tal:attributes="href intervention/url">
2964- Intervention
2965- </a>
2966- </li>
2967- </ul>
2968- </div>
2969- </div>
2970- </form>
2971-</div>
2972-</body>
2973-</html>
2974
2975=== removed file 'src/schooltool/intervention/browser/intervention_tab.pt'
2976--- src/schooltool/intervention/browser/intervention_tab.pt 2009-07-26 06:12:58 +0000
2977+++ src/schooltool/intervention/browser/intervention_tab.pt 1970-01-01 00:00:00 +0000
2978@@ -1,13 +0,0 @@
2979-<tal:if condition="request/principal/schooltool:authenticated"
2980- define="app context/schooltool:app">
2981- <a i18n:translate=""
2982- class="navigation_header"
2983- tal:condition="python: len(app['schooltool.schoolyear']) > 0"
2984- tal:attributes="href string:${app/@@absolute_url}/intervention/intervention.html"
2985- >Intervention</a>
2986- <a i18n:translate=""
2987- class="navigation_header"
2988- tal:condition="python: len(app['schooltool.schoolyear']) == 0"
2989- tal:attributes="href string:${app/@@absolute_url}/no_current_term.html"
2990- >Intervention</a>
2991-</tal:if>
2992
2993=== removed file 'src/schooltool/intervention/browser/macros.pt'
2994--- src/schooltool/intervention/browser/macros.pt 2008-05-23 00:11:52 +0000
2995+++ src/schooltool/intervention/browser/macros.pt 1970-01-01 00:00:00 +0000
2996@@ -1,27 +0,0 @@
2997-<metal:block define-macro="widget-rows">
2998- <tal:block repeat="widget view/widgets/values">
2999- <div id="" class="row"
3000- tal:attributes="id string:${widget/id}-row"
3001- tal:condition="python:widget.mode != 'hidden'">
3002- <metal:block define-macro="widget-row">
3003- <div class="label">
3004- <label tal:attributes="for widget/id"
3005- tal:content="widget/label">label</label>
3006- <span class="required"
3007- tal:condition="widget/required">*</span>
3008- </div>
3009- <div class="widget" tal:content="structure widget/render">
3010- <input type="text" size="24" value="" />
3011- </div>
3012- <div class="error"
3013- tal:condition="widget/error">
3014- <span tal:replace="structure widget/error/render">error</span>
3015- </div>
3016- </metal:block>
3017- </div>
3018- <input type="hidden" value=""
3019- tal:condition="python:widget.mode == 'hidden'"
3020- tal:replace="structure widget/render" />
3021- </tal:block>
3022-</metal:block>
3023-
3024
3025=== removed file 'src/schooltool/intervention/browser/notify_goals.pt'
3026--- src/schooltool/intervention/browser/notify_goals.pt 2008-04-26 07:55:55 +0000
3027+++ src/schooltool/intervention/browser/notify_goals.pt 1970-01-01 00:00:00 +0000
3028@@ -1,29 +0,0 @@
3029-<html metal:use-macro="view/@@standard_macros/page" i18n:domain="schooltool">
3030-<head>
3031- <title metal:fill-slot="title" tal:content="string: Goal Notification" />
3032-</head>
3033-<body>
3034- <h1 metal:fill-slot="content-header" i18n:translate="">
3035- <span tal:replace="string: Goal Notification" />
3036- </h1>
3037-
3038-<metal:block metal:fill-slot="body">
3039- <div>
3040- <tal:if condition="not: view/goals">
3041- <ul><li>There are no goals that need notification.<br /></li></ul>
3042- </tal:if>
3043- <tal:if condition="view/goals">
3044- <p>The following goals had notifications sent to the persons responsible:</p>
3045- <ul>
3046- <li tal:repeat="goal view/goals">
3047- <a href="" tal:content="goal/text"
3048- tal:attributes="href goal/url">
3049- Goal
3050- </a>
3051- </li>
3052- </ul>
3053- </tal:if>
3054- </div>
3055-</metal:block>
3056-</body>
3057-</html>
3058
3059=== removed file 'src/schooltool/intervention/browser/person_add.pt'
3060--- src/schooltool/intervention/browser/person_add.pt 2008-05-23 00:11:52 +0000
3061+++ src/schooltool/intervention/browser/person_add.pt 1970-01-01 00:00:00 +0000
3062@@ -1,260 +0,0 @@
3063-<html metal:use-macro="view/@@standard_macros/page" i18n:domain="schooltool">
3064- <body>
3065- <metal:nothing metal:fill-slot="content-header" />
3066- <metal:block metal:fill-slot="body">
3067- <div>
3068- <form action="." method="post" enctype="multipart/form-data" class="edit-form"
3069- tal:attributes="method view/method;
3070- enctype view/enctype;
3071- acceptCharset view/acceptCharset;
3072- accept view/accept;
3073- action view/action;
3074- name view/name;
3075- id view/id">
3076- <h1 tal:condition="view/label|nothing"
3077- tal:content="view/label">Form Label</h1>
3078- <div class="required-info">
3079- <span class="required">*</span>
3080- &ndash; required
3081- </div>
3082- <div class="status"
3083- tal:condition="view/status">
3084- <div class="summary"
3085- i18n:translate=""
3086- tal:content="view/status">
3087- Form status summary
3088- </div>
3089- </div>
3090-
3091- <table style="margin-top: 1ex; margin-bottom: 1ex;">
3092- <tr>
3093- <td>
3094- <div class="row" tal:define="widget view/widgets/username">
3095- <div metal:use-macro="macro:widget-row" />
3096- </div>
3097- </td>
3098- <td>
3099- <div class="row" tal:define="widget view/widgets/password">
3100- <div metal:use-macro="macro:widget-row" />
3101- </div>
3102- </td>
3103- <td>
3104- <div class="row" tal:define="widget view/widgets/confirm">
3105- <div metal:use-macro="macro:widget-row" />
3106- </div>
3107- </td>
3108- </tr>
3109-
3110- <tr>
3111- <td>
3112- <div class="row" tal:define="widget view/widgets/first_name">
3113- <div metal:use-macro="macro:widget-row" />
3114- </div>
3115- </td>
3116- <td>
3117- <div class="row" tal:define="widget view/widgets/last_name">
3118- <div metal:use-macro="macro:widget-row" />
3119- </div>
3120- </td>
3121- <td>
3122- <div class="row" tal:define="widget view/widgets/gender">
3123- <div metal:use-macro="macro:widget-row" />
3124- </div>
3125- </td>
3126- </tr>
3127-
3128- <tr>
3129- <td>
3130- <div class="row" tal:define="widget view/widgets/district_id">
3131- <div metal:use-macro="macro:widget-row" />
3132- </div>
3133- </td>
3134- <td>
3135- <div class="row" tal:define="widget view/widgets/birth_date">
3136- <div metal:use-macro="macro:widget-row" />
3137- </div>
3138- </td>
3139- </tr>
3140-
3141- <tr>
3142- <td>
3143- <div class="row" tal:define="widget view/widgets/advisor1">
3144- <div metal:use-macro="macro:widget-row" />
3145- </div>
3146- </td>
3147- <td>
3148- <div class="row" tal:define="widget view/widgets/advisor2">
3149- <div metal:use-macro="macro:widget-row" />
3150- </div>
3151- </td>
3152- </tr>
3153-
3154- <tr>
3155- <td>
3156- <div class="row" tal:define="widget view/widgets/parent_first_name">
3157- <div metal:use-macro="macro:widget-row" />
3158- </div>
3159- </td>
3160- <td>
3161- <div class="row" tal:define="widget view/widgets/parent_last_name">
3162- <div metal:use-macro="macro:widget-row" />
3163- </div>
3164- </td>
3165- <td>
3166- <div class="row" tal:define="widget view/widgets/email">
3167- <div metal:use-macro="macro:widget-row" />
3168- </div>
3169- </td>
3170- </tr>
3171-
3172- <tr>
3173- <td>
3174- <div class="row" tal:define="widget view/widgets/parent2_first_name">
3175- <div metal:use-macro="macro:widget-row" />
3176- </div>
3177- </td>
3178- <td>
3179- <div class="row" tal:define="widget view/widgets/parent2_last_name">
3180- <div metal:use-macro="macro:widget-row" />
3181- </div>
3182- </td>
3183- <td>
3184- <div class="row" tal:define="widget view/widgets/email2">
3185- <div metal:use-macro="macro:widget-row" />
3186- </div>
3187- </td>
3188- </tr>
3189-
3190- <tr>
3191- <td>
3192- <div class="row" tal:define="widget view/widgets/address">
3193- <div metal:use-macro="macro:widget-row" />
3194- </div>
3195- </td>
3196- <td>
3197- <div class="row" tal:define="widget view/widgets/city">
3198- <div metal:use-macro="macro:widget-row" />
3199- </div>
3200- </td>
3201- <td>
3202- <div class="row" tal:define="widget view/widgets/state">
3203- <div metal:use-macro="macro:widget-row" />
3204- </div>
3205- </td>
3206- </tr>
3207-
3208- <tr>
3209- <td>
3210- <div class="row" tal:define="widget view/widgets/zip">
3211- <div metal:use-macro="macro:widget-row" />
3212- </div>
3213- </td>
3214- <td>
3215- <div class="row" tal:define="widget view/widgets/phone">
3216- <div metal:use-macro="macro:widget-row" />
3217- </div>
3218- </td>
3219- <td>
3220- <div class="row" tal:define="widget view/widgets/cell_phone">
3221- <div metal:use-macro="macro:widget-row" />
3222- </div>
3223- </td>
3224- </tr>
3225-
3226- <tr>
3227- <td>
3228- <div class="row" tal:define="widget view/widgets/address2">
3229- <div metal:use-macro="macro:widget-row" />
3230- </div>
3231- </td>
3232- <td>
3233- <div class="row" tal:define="widget view/widgets/city2">
3234- <div metal:use-macro="macro:widget-row" />
3235- </div>
3236- </td>
3237- <td>
3238- <div class="row" tal:define="widget view/widgets/state2">
3239- <div metal:use-macro="macro:widget-row" />
3240- </div>
3241- </td>
3242- </tr>
3243-
3244- <tr>
3245- <td>
3246- <div class="row" tal:define="widget view/widgets/zip2">
3247- <div metal:use-macro="macro:widget-row" />
3248- </div>
3249- </td>
3250- <td>
3251- <div class="row" tal:define="widget view/widgets/home_phone2">
3252- <div metal:use-macro="macro:widget-row" />
3253- </div>
3254- </td>
3255- <td>
3256- <div class="row" tal:define="widget view/widgets/cell_phone2">
3257- <div metal:use-macro="macro:widget-row" />
3258- </div>
3259- </td>
3260- </tr>
3261-
3262- <tr>
3263- <td>
3264- <div class="row" tal:define="widget view/widgets/address3">
3265- <div metal:use-macro="macro:widget-row" />
3266- </div>
3267- </td>
3268- <td>
3269- <div class="row" tal:define="widget view/widgets/city3">
3270- <div metal:use-macro="macro:widget-row" />
3271- </div>
3272- </td>
3273- <td>
3274- <div class="row" tal:define="widget view/widgets/state3">
3275- <div metal:use-macro="macro:widget-row" />
3276- </div>
3277- </td>
3278- </tr>
3279-
3280- <tr>
3281- <td>
3282- <div class="row" tal:define="widget view/widgets/zip3">
3283- <div metal:use-macro="macro:widget-row" />
3284- </div>
3285- </td>
3286- <td>
3287- <div class="row" tal:define="widget view/widgets/home_phone3">
3288- <div metal:use-macro="macro:widget-row" />
3289- </div>
3290- </td>
3291- <td>
3292- <div class="row" tal:define="widget view/widgets/cell_phone3">
3293- <div metal:use-macro="macro:widget-row" />
3294- </div>
3295- </td>
3296- </tr>
3297-
3298- <tr>
3299- <td>
3300- <div class="row" tal:define="widget view/widgets/work_phone">
3301- <div metal:use-macro="macro:widget-row" />
3302- </div>
3303- </td>
3304- <td>
3305- <div class="row" tal:define="widget view/widgets/work_phone2">
3306- <div metal:use-macro="macro:widget-row" />
3307- </div>
3308- </td>
3309- </tr>
3310- </table>
3311-
3312- <div class="buttons">
3313- <input tal:repeat="action view/actions/values"
3314- tal:replace="structure action/render"
3315- />
3316- </div>
3317-
3318- </form>
3319- </div>
3320- </metal:block>
3321- </body>
3322-</html>
3323
3324=== removed file 'src/schooltool/intervention/browser/person_edit.pt'
3325--- src/schooltool/intervention/browser/person_edit.pt 2008-05-23 00:11:52 +0000
3326+++ src/schooltool/intervention/browser/person_edit.pt 1970-01-01 00:00:00 +0000
3327@@ -1,242 +0,0 @@
3328-<html metal:use-macro="view/@@standard_macros/page" i18n:domain="schooltool">
3329- <body>
3330- <metal:nothing metal:fill-slot="content-header" />
3331- <metal:block metal:fill-slot="body">
3332- <div>
3333- <form action="." method="post" enctype="multipart/form-data" class="edit-form"
3334- tal:attributes="method view/method;
3335- enctype view/enctype;
3336- acceptCharset view/acceptCharset;
3337- accept view/accept;
3338- action view/action;
3339- name view/name;
3340- id view/id">
3341- <h1 tal:condition="view/form_label|nothing"
3342- tal:content="view/form_label">Form Label</h1>
3343- <div class="required-info">
3344- <span class="required">*</span>
3345- &ndash; required
3346- </div>
3347- <div class="status"
3348- tal:condition="view/status">
3349- <div class="summary"
3350- i18n:translate=""
3351- tal:content="view/status">
3352- Form status summary
3353- </div>
3354- </div>
3355-
3356- <table style="margin-top: 1ex; margin-bottom: 1ex;">
3357- <tr>
3358- <td>
3359- <div class="row" tal:define="widget view/widgets/first_name">
3360- <div metal:use-macro="macro:widget-row" />
3361- </div>
3362- </td>
3363- <td>
3364- <div class="row" tal:define="widget view/widgets/last_name">
3365- <div metal:use-macro="macro:widget-row" />
3366- </div>
3367- </td>
3368- <td>
3369- <div class="row" tal:define="widget view/widgets/gender">
3370- <div metal:use-macro="macro:widget-row" />
3371- </div>
3372- </td>
3373- </tr>
3374-
3375- <tr>
3376- <td>
3377- <div class="row" tal:define="widget view/widgets/district_id">
3378- <div metal:use-macro="macro:widget-row" />
3379- </div>
3380- </td>
3381- <td>
3382- <div class="row" tal:define="widget view/widgets/birth_date">
3383- <div metal:use-macro="macro:widget-row" />
3384- </div>
3385- </td>
3386- </tr>
3387-
3388- <tr>
3389- <td>
3390- <div class="row" tal:define="widget view/widgets/advisor1">
3391- <div metal:use-macro="macro:widget-row" />
3392- </div>
3393- </td>
3394- <td>
3395- <div class="row" tal:define="widget view/widgets/advisor2">
3396- <div metal:use-macro="macro:widget-row" />
3397- </div>
3398- </td>
3399- </tr>
3400-
3401- <tr>
3402- <td>
3403- <div class="row" tal:define="widget view/widgets/parent_first_name">
3404- <div metal:use-macro="macro:widget-row" />
3405- </div>
3406- </td>
3407- <td>
3408- <div class="row" tal:define="widget view/widgets/parent_last_name">
3409- <div metal:use-macro="macro:widget-row" />
3410- </div>
3411- </td>
3412- <td>
3413- <div class="row" tal:define="widget view/widgets/email">
3414- <div metal:use-macro="macro:widget-row" />
3415- </div>
3416- </td>
3417- </tr>
3418-
3419- <tr>
3420- <td>
3421- <div class="row" tal:define="widget view/widgets/parent2_first_name">
3422- <div metal:use-macro="macro:widget-row" />
3423- </div>
3424- </td>
3425- <td>
3426- <div class="row" tal:define="widget view/widgets/parent2_last_name">
3427- <div metal:use-macro="macro:widget-row" />
3428- </div>
3429- </td>
3430- <td>
3431- <div class="row" tal:define="widget view/widgets/email2">
3432- <div metal:use-macro="macro:widget-row" />
3433- </div>
3434- </td>
3435- </tr>
3436-
3437- <tr>
3438- <td>
3439- <div class="row" tal:define="widget view/widgets/address">
3440- <div metal:use-macro="macro:widget-row" />
3441- </div>
3442- </td>
3443- <td>
3444- <div class="row" tal:define="widget view/widgets/city">
3445- <div metal:use-macro="macro:widget-row" />
3446- </div>
3447- </td>
3448- <td>
3449- <div class="row" tal:define="widget view/widgets/state">
3450- <div metal:use-macro="macro:widget-row" />
3451- </div>
3452- </td>
3453- </tr>
3454-
3455- <tr>
3456- <td>
3457- <div class="row" tal:define="widget view/widgets/zip">
3458- <div metal:use-macro="macro:widget-row" />
3459- </div>
3460- </td>
3461- <td>
3462- <div class="row" tal:define="widget view/widgets/phone">
3463- <div metal:use-macro="macro:widget-row" />
3464- </div>
3465- </td>
3466- <td>
3467- <div class="row" tal:define="widget view/widgets/cell_phone">
3468- <div metal:use-macro="macro:widget-row" />
3469- </div>
3470- </td>
3471- </tr>
3472-
3473- <tr>
3474- <td>
3475- <div class="row" tal:define="widget view/widgets/address2">
3476- <div metal:use-macro="macro:widget-row" />
3477- </div>
3478- </td>
3479- <td>
3480- <div class="row" tal:define="widget view/widgets/city2">
3481- <div metal:use-macro="macro:widget-row" />
3482- </div>
3483- </td>
3484- <td>
3485- <div class="row" tal:define="widget view/widgets/state2">
3486- <div metal:use-macro="macro:widget-row" />
3487- </div>
3488- </td>
3489- </tr>
3490-
3491- <tr>
3492- <td>
3493- <div class="row" tal:define="widget view/widgets/zip2">
3494- <div metal:use-macro="macro:widget-row" />
3495- </div>
3496- </td>
3497- <td>
3498- <div class="row" tal:define="widget view/widgets/home_phone2">
3499- <div metal:use-macro="macro:widget-row" />
3500- </div>
3501- </td>
3502- <td>
3503- <div class="row" tal:define="widget view/widgets/cell_phone2">
3504- <div metal:use-macro="macro:widget-row" />
3505- </div>
3506- </td>
3507- </tr>
3508-
3509- <tr>
3510- <td>
3511- <div class="row" tal:define="widget view/widgets/address3">
3512- <div metal:use-macro="macro:widget-row" />
3513- </div>
3514- </td>
3515- <td>
3516- <div class="row" tal:define="widget view/widgets/city3">
3517- <div metal:use-macro="macro:widget-row" />
3518- </div>
3519- </td>
3520- <td>
3521- <div class="row" tal:define="widget view/widgets/state3">
3522- <div metal:use-macro="macro:widget-row" />
3523- </div>
3524- </td>
3525- </tr>
3526-
3527- <tr>
3528- <td>
3529- <div class="row" tal:define="widget view/widgets/zip3">
3530- <div metal:use-macro="macro:widget-row" />
3531- </div>
3532- </td>
3533- <td>
3534- <div class="row" tal:define="widget view/widgets/home_phone3">
3535- <div metal:use-macro="macro:widget-row" />
3536- </div>
3537- </td>
3538- <td>
3539- <div class="row" tal:define="widget view/widgets/cell_phone3">
3540- <div metal:use-macro="macro:widget-row" />
3541- </div>
3542- </td>
3543- </tr>
3544-
3545- <tr>
3546- <td>
3547- <div class="row" tal:define="widget view/widgets/work_phone">
3548- <div metal:use-macro="macro:widget-row" />
3549- </div>
3550- </td>
3551- <td>
3552- <div class="row" tal:define="widget view/widgets/work_phone2">
3553- <div metal:use-macro="macro:widget-row" />
3554- </div>
3555- </td>
3556- </tr>
3557- </table>
3558-
3559- <div class="buttons">
3560- <input tal:repeat="action view/actions/values"
3561- tal:replace="structure action/render"
3562- />
3563- </div>
3564-
3565- </form>
3566- </div>
3567- </metal:block>
3568- </body>
3569-</html>
3570
3571=== removed file 'src/schooltool/intervention/browser/person_list.pt'
3572--- src/schooltool/intervention/browser/person_list.pt 2008-05-23 00:11:52 +0000
3573+++ src/schooltool/intervention/browser/person_list.pt 1970-01-01 00:00:00 +0000
3574@@ -1,26 +0,0 @@
3575-<br /><br />
3576-<table>
3577- <tr>
3578- <td>Staff</td>
3579- <td>Student/Parents</td>
3580- </tr>
3581- <tr>
3582- <td style="vertical-align: top; horizontal-align: left;">
3583- <tal:block repeat="person view/responsible">
3584- <input type="checkbox"
3585- tal:attributes="name person/name; checked person/checked" />
3586- <span tal:content="person/value" />
3587- <br />
3588- </tal:block>
3589- </td>
3590- <td style="vertical-align: top; horizontal-align: left;">
3591- <tal:block repeat="person view/notified">
3592- <input type="checkbox"
3593- tal:attributes="name person/name; checked person/checked" />
3594- <span tal:content="person/value" />
3595- <br />
3596- </tal:block>
3597- </td>
3598- </tr>
3599-<div>
3600-</div>
3601
3602=== removed file 'src/schooltool/intervention/browser/reports.py'
3603--- src/schooltool/intervention/browser/reports.py 2009-07-23 07:08:31 +0000
3604+++ src/schooltool/intervention/browser/reports.py 1970-01-01 00:00:00 +0000
3605@@ -1,159 +0,0 @@
3606-#
3607-# SchoolTool - common information systems platform for school administration
3608-# Copyright (c) 2005 Shuttleworth Foundation
3609-#
3610-# This program is free software; you can redistribute it and/or modify
3611-# it under the terms of the GNU General Public License as published by
3612-# the Free Software Foundation; either version 2 of the License, or
3613-# (at your option) any later version.
3614-#
3615-# This program is distributed in the hope that it will be useful,
3616-# but WITHOUT ANY WARRANTY; without even the implied warranty of
3617-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3618-# GNU General Public License for more details.
3619-#
3620-# You should have received a copy of the GNU General Public License
3621-# along with this program; if not, write to the Free Software
3622-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3623-#
3624-"""
3625-Student Intervention browser report views.
3626-"""
3627-import tempfile
3628-import cgi
3629-import re
3630-import random
3631-from cStringIO import StringIO
3632-
3633-from reportlab.lib import units
3634-from reportlab.lib import pagesizes
3635-from reportlab.lib import colors
3636-from reportlab.platypus import SimpleDocTemplate
3637-from reportlab.platypus import Paragraph
3638-from reportlab.platypus.flowables import HRFlowable, Spacer, Image, PageBreak
3639-from reportlab.lib.styles import ParagraphStyle
3640-from reportlab.platypus.tables import Table, TableStyle
3641-from zope.interface import implements
3642-from zope.component import queryAdapter, queryMultiAdapter
3643-from zope.i18n import translate
3644-from zope.publisher.browser import BrowserView
3645-from zope.viewlet.interfaces import IViewletManager
3646-from zope.traversing.browser.absoluteurl import absoluteURL
3647-from zope.security.proxy import removeSecurityProxy
3648-from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
3649-from zope.app.catalog.interfaces import ICatalog
3650-from zope.component.interfaces import ComponentLookupError
3651-from zope.viewlet.viewlet import CSSViewlet, JavaScriptViewlet
3652-
3653-
3654-from schooltool.person.interfaces import IPerson
3655-from schooltool.group.interfaces import IGroup
3656-from schooltool.relationship.relationship import getRelatedObjects
3657-from schooltool.app.relationships import URIInstruction, URISection
3658-from schooltool.skin.skin import OrderedViewletManager
3659-from schooltool.app.interfaces import ISchoolToolApplication
3660-from schooltool.app.browser import pdfcal
3661-from schooltool.common import SchoolToolMessage as _
3662-
3663-
3664-ReportsCSSViewlet = CSSViewlet("reportsViewlet.css")
3665-ReportsJSViewlet = JavaScriptViewlet("reportsViewlet.js")
3666-
3667-
3668-def _para(text, style):
3669- """Helper which builds a reportlab Paragraph flowable"""
3670- if text is None:
3671- text = ''
3672- elif isinstance(text, unicode):
3673- text = text.encode('utf-8')
3674- else:
3675- text = str(text)
3676- return Paragraph(cgi.escape(text), style)
3677-
3678-
3679-def _unescape_FCKEditor_HTML(text):
3680- text = text.replace(u'&amp;', u'&')
3681- text = text.replace(u'&lt;', u'<')
3682- text = text.replace(u'&gt;', u'>')
3683- text = text.replace(u'&quot;', u'"')
3684- text = text.replace(u'&#39;', u"'")
3685- text = text.replace(u'&rsquo;', u"'")
3686- text = text.replace(u'&nbsp;', u' ')
3687- return text
3688-
3689-
3690-escaped_reportlab_tags_re = re.compile(
3691- r'&lt;(/?((strong)|(b)|(em)|(i)))&gt;')
3692-
3693-html_p_tag_re = re.compile(r'</?p[^>]*>')
3694-html_br_tag_re = re.compile(r'</?br[^>]*>')
3695-
3696-
3697-def buildHTMLParagraphs(snippet):
3698- """Build a list of paragraphs from an HTML snippet."""
3699- if not snippet:
3700- return []
3701- paragraphs = []
3702- tokens = []
3703- for token in html_p_tag_re.split(snippet):
3704- if not token or token.isspace():
3705- continue
3706- tokens.extend(html_br_tag_re.split(token))
3707- for token in tokens:
3708- if not token or token.isspace():
3709- continue
3710- # Reportlab is very sensitive to unknown tags and escaped symbols.
3711- # In case of invalid HTML, ensure correct escaping.
3712- fixed_escaping = cgi.escape(_unescape_FCKEditor_HTML(unicode(token)))
3713- # Unescape some of the tags which are also valid in Reportlab
3714- valid_text = escaped_reportlab_tags_re.sub(u'<\g<1>>', fixed_escaping)
3715- paragraphs.append(valid_text)
3716- return paragraphs
3717-
3718-
3719-class IReportsViewletManager(IViewletManager):
3720- """Provides a viewlet hook for report items."""
3721-
3722-
3723-class ReportsViewlet(object):
3724- """Schooltool action acting as drop-down menu item.
3725-
3726- Sub-items are collected from specified viewlet manager.
3727- """
3728-
3729- manager_interface = IReportsViewletManager
3730- manager_name = "schooltool.intervention.reports_action_manager"
3731-
3732- viewlet_manager = None
3733-
3734- _tag_uid = None
3735-
3736- @property
3737- def tag_uid(self):
3738- if self._tag_uid is None:
3739- self._tag_uid = u'MENU_'
3740- for i in range(15):
3741- self._tag_uid += unichr(ord(u'a') + random.randint(0, 25))
3742- return self._tag_uid
3743-
3744- def update(self):
3745- try:
3746- self.viewlet_manager = queryMultiAdapter(
3747- (self.context, self.request, self),
3748- self.manager_interface,
3749- name=self.manager_name)
3750- # Update __parent__ of the manager, so that it's viewlets could
3751- # be registered for the actual view instead of this viewlet.
3752- self.viewlet_manager.__parent__ = self.__parent__
3753- except ComponentLookupError:
3754- pass
3755-
3756- if self.viewlet_manager is not None:
3757- self.viewlet_manager.update()
3758-
3759- def render(self, *args, **kw):
3760- if (self.viewlet_manager is None or
3761- not self.viewlet_manager.viewlets):
3762- return ''
3763- return self.index(*args, **kw)
3764-
3765
3766=== removed file 'src/schooltool/intervention/browser/reportsViewlet.css'
3767--- src/schooltool/intervention/browser/reportsViewlet.css 2008-12-19 10:39:34 +0000
3768+++ src/schooltool/intervention/browser/reportsViewlet.css 1970-01-01 00:00:00 +0000
3769@@ -1,19 +0,0 @@
3770-/*
3771- * Stylesheet for SchoolTool dropdown action menu item
3772- */
3773-
3774-div.dropdownactions {
3775- background: #eae8e3;
3776- border: 1px solid #bab5ab;
3777- padding: 0.2em 0.3em;
3778- margin: 0px;
3779- position: absolute;
3780- z-index: 100;
3781- display: none;
3782- white-space: nowrap;
3783-}
3784-
3785-div.dropdownactions div.content-nav {
3786- border: none;
3787- display: block;
3788-}
3789
3790=== removed file 'src/schooltool/intervention/browser/reportsViewlet.js'
3791--- src/schooltool/intervention/browser/reportsViewlet.js 2008-12-19 10:39:34 +0000
3792+++ src/schooltool/intervention/browser/reportsViewlet.js 1970-01-01 00:00:00 +0000
3793@@ -1,79 +0,0 @@
3794-/*
3795- * Javascript for SchoolTool dropdown action menu item.
3796- */
3797-
3798-DDM_visible_menu_list_id = null;
3799-DDM_menu_hide_timeout_id = null;
3800-DDM_hide_timeout = 300;
3801-
3802-
3803-function DDM_getOffsetLeft (elem)
3804-{
3805- var offset = elem.offsetLeft;
3806- var elem = elem.offsetParent;
3807- while (elem != null){
3808- offset += elem.offsetLeft;
3809- elem = elem.offsetParent;
3810- }
3811- return offset;
3812-}
3813-
3814-
3815-function DDM_onShow(el_id)
3816-{
3817- var menu = document.getElementById(el_id);
3818- var mlist = document.getElementById(el_id + "_list");
3819- if (!menu || !mlist)
3820- return;
3821-
3822- DDM_cancelDelayedHide();
3823-
3824- if (DDM_visible_menu_list_id)
3825- {
3826- if (mlist.id == DDM_visible_menu_list_id)
3827- return;
3828- else
3829- DDM_performHide();
3830- }
3831-
3832- mlist.style.left = DDM_getOffsetLeft(menu) + "px";
3833- DDM_visible_menu_list_id = mlist.id;
3834- mlist.style.display="block";
3835-}
3836-
3837-
3838-function DDM_onHide(el_id){
3839- var menu = document.getElementById(el_id);
3840- var mlist = document.getElementById(el_id + "_list");
3841- if (!menu || !mlist)
3842- return;
3843-
3844- DDM_delayHide(mlist.id);
3845-}
3846-
3847-
3848-function DDM_delayHide(menu_id)
3849-{
3850- DDM_cancelDelayedHide();
3851- DDM_menu_hide_timeout_id = setTimeout("DDM_performHide();", DDM_hide_timeout);
3852-}
3853-
3854-
3855-function DDM_cancelDelayedHide()
3856-{
3857- if (DDM_menu_hide_timeout_id)
3858- clearTimeout(DDM_menu_hide_timeout_id);
3859-}
3860-
3861-
3862-function DDM_performHide()
3863-{
3864- if (!DDM_visible_menu_list_id)
3865- return;
3866- DDM_cancelDelayedHide();
3867- var mlist = document.getElementById(DDM_visible_menu_list_id);
3868- DDM_visible_menu_list_id = null;
3869- if (!mlist)
3870- return;
3871- mlist.style.display="none";
3872-}
3873
3874=== removed file 'src/schooltool/intervention/browser/reportsViewlet.pt'
3875--- src/schooltool/intervention/browser/reportsViewlet.pt 2008-12-19 10:39:34 +0000
3876+++ src/schooltool/intervention/browser/reportsViewlet.pt 1970-01-01 00:00:00 +0000
3877@@ -1,23 +0,0 @@
3878-<tal:block i18n:domain="schooltool"
3879- tal:define="url view/context/@@absolute_url">
3880-
3881-<div class="content-nav"
3882- tal:attributes="
3883- id view/tag_uid;
3884- onMouseOver string:DDM_onShow('${view/tag_uid}');
3885- onMouseOut string:DDM_onHide('${view/tag_uid}')">
3886-
3887- <span>
3888- <img src="++resource++printer.png" />
3889- Reports
3890- <img src="++resource++downarrow.png" />
3891- </span>
3892-
3893- <div tal:attributes="id string:${view/tag_uid}_list"
3894- class="dropdownactions">
3895- <tal:block content="structure view/viewlet_manager/render" />
3896- </div>
3897-
3898-</div>
3899-
3900-</tal:block>
3901
3902=== removed file 'src/schooltool/intervention/browser/section_interventions.css'
3903--- src/schooltool/intervention/browser/section_interventions.css 2009-01-05 12:53:51 +0000
3904+++ src/schooltool/intervention/browser/section_interventions.css 1970-01-01 00:00:00 +0000
3905@@ -1,55 +0,0 @@
3906-/*
3907- * Stylesheet for SLA intervention section view
3908- */
3909-
3910-div.tabmenu {
3911- display: block;
3912- float: left;
3913- margin: 0;
3914- font-weight: bold;
3915- font-size: 1em;
3916-}
3917-
3918-div.tabmenu p {
3919- display: inline;
3920- float: left;
3921- text-decoration: none;
3922- padding: 0.3em 0.5em;
3923- margin: 0px;
3924- border: 1px solid black;
3925-}
3926-
3927-div.tabmenu a {
3928- background: #eae8e3;
3929- display: inline;
3930- float: left;
3931- padding: 0.2em 0.5em;
3932- margin: 0.2em 0px 0px 0px;
3933- border: 1px solid black;
3934-}
3935-
3936-table.students_nav {
3937- border-spacing: 0;
3938-}
3939-
3940-table.students_nav td {
3941- padding: 0 0.2em 0.5em 0;
3942-}
3943-
3944-table.students_nav th {
3945- padding: 0;
3946- border-bottom: 1px solid black;
3947-}
3948-
3949-div.student_nav_link {
3950- display: inline;
3951-}
3952-
3953-div.student_nav_link a {
3954- font-weight: bold;
3955- font-size: 1em;
3956- display: inline;
3957- float: left;
3958- padding: 0.2em 0.5em;
3959- margin: 0.2em 0px 0px 0px;
3960-}
3961
3962=== removed file 'src/schooltool/intervention/browser/section_interventions.pt'
3963--- src/schooltool/intervention/browser/section_interventions.pt 2009-01-05 12:53:51 +0000
3964+++ src/schooltool/intervention/browser/section_interventions.pt 1970-01-01 00:00:00 +0000
3965@@ -1,62 +0,0 @@
3966-<html metal:use-macro="view/@@standard_macros/page" i18n:domain="schooltool.sla">
3967-<head>
3968- <title metal:fill-slot="title"
3969- i18n:translate="">
3970- Section Interventions
3971- </title>
3972-
3973- <metal:block metal:fill-slot="extrahead">
3974- <link rel="stylesheet" type="text/css" href="section_interventions.css"
3975- tal:attributes="href context/++resource++section_interventions.css"/>
3976- </metal:block>
3977-
3978-</head>
3979-<body>
3980-
3981-<h1 metal:fill-slot="content-header"
3982- tal:content="string:${view/section}'s Student Interventions"
3983- i18n:translate="">Contents</h1>
3984-
3985-<metal:block metal:fill-slot="body">
3986-
3987-<table class="students_nav">
3988-
3989- <tr>
3990- <th>Intervention</th>
3991- <th>
3992- <tal:block tal:repeat="tab view/iterTabs">
3993- <tal:block condition="tab/active">
3994- <div class="tabmenu">
3995- <p tal:content="tab/title">Selected Tab</p>
3996- </div>
3997- </tal:block>
3998- <tal:block condition="not:tab/active">
3999- <div class="tabmenu">
4000- <a tal:attributes="href tab/url"
4001- tal:content="tab/title">Not Selected Tab</a>
4002- </div>
4003- </tal:block>
4004- </tal:block>
4005- </th>
4006- </tr>
4007-
4008- <tr tal:repeat="student view/listStudents">
4009- <td>
4010- <a tal:attributes="href student/url"
4011- tal:content="student/name">Student Name</a>
4012- </td>
4013- <td>
4014- <tal:block repeat="link student/links">
4015- <div class="student_nav_link">
4016- <a tal:attributes="href link/url"
4017- tal:content="link/title">Do Something</a>
4018- </div>
4019- </tal:block>
4020- </td>
4021- </tr>
4022-
4023-</table>
4024-</metal:block>
4025-
4026-</body>
4027-</html>
4028
4029=== removed file 'src/schooltool/intervention/browser/skin.py'
4030--- src/schooltool/intervention/browser/skin.py 2008-04-20 20:22:23 +0000
4031+++ src/schooltool/intervention/browser/skin.py 1970-01-01 00:00:00 +0000
4032@@ -1,34 +0,0 @@
4033-#
4034-# SchoolTool - common information systems platform for school administration
4035-# Copyright (c) 2005 Shuttleworth Foundation
4036-#
4037-# This program is free software; you can redistribute it and/or modify
4038-# it under the terms of the GNU General Public License as published by
4039-# the Free Software Foundation; either version 2 of the License, or
4040-# (at your option) any later version.
4041-#
4042-# This program is distributed in the hope that it will be useful,
4043-# but WITHOUT ANY WARRANTY; without even the implied warranty of
4044-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4045-# GNU General Public License for more details.
4046-#
4047-# You should have received a copy of the GNU General Public License
4048-# along with this program; if not, write to the Free Software
4049-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4050-#
4051-"""
4052-Intervention skin.
4053-"""
4054-from zope.publisher.interfaces.browser import IBrowserRequest
4055-
4056-from schooltool.timetable.browser.skin import ITimetableLayer
4057-from schooltool.skin.skin import ISchoolToolSkin
4058-from schooltool.basicperson.browser.skin import IBasicPersonLayer
4059-
4060-
4061-class IInterventionLayer(IBrowserRequest):
4062- """Intervention layer."""
4063-
4064-
4065-class IInterventionSkin(IInterventionLayer, ITimetableLayer, IBasicPersonLayer, ISchoolToolSkin):
4066- """The Intervention skin"""
4067
4068=== removed file 'src/schooltool/intervention/browser/sla_logo.png'
4069Binary files src/schooltool/intervention/browser/sla_logo.png 2008-10-15 10:46:58 +0000 and src/schooltool/intervention/browser/sla_logo.png 1970-01-01 00:00:00 +0000 differ
4070=== removed file 'src/schooltool/intervention/browser/widgets.py'
4071--- src/schooltool/intervention/browser/widgets.py 2009-07-20 05:33:58 +0000
4072+++ src/schooltool/intervention/browser/widgets.py 1970-01-01 00:00:00 +0000
4073@@ -1,191 +0,0 @@
4074-#
4075-# SchoolTool - common information systems platform for school administration
4076-# Copyright (c) 2005 Shuttleworth Foundation
4077-#
4078-# This program is free software; you can redistribute it and/or modify
4079-# it under the terms of the GNU General Public License as published by
4080-# the Free Software Foundation; either version 2 of the License, or
4081-# (at your option) any later version.
4082-#
4083-# This program is distributed in the hope that it will be useful,
4084-# but WITHOUT ANY WARRANTY; without even the implied warranty of
4085-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4086-# GNU General Public License for more details.
4087-#
4088-# You should have received a copy of the GNU General Public License
4089-# along with this program; if not, write to the Free Software
4090-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4091-#
4092-"""
4093-Student Intervention widgets.
4094-"""
4095-from zope.app.container.interfaces import IAdding
4096-from zope.app.form.interfaces import MissingInputError
4097-from zope.app.form.browser.interfaces import IBrowserWidget, IInputWidget
4098-from zope.app.form.browser.submit import Update
4099-from zope.app.pagetemplate import ViewPageTemplateFile
4100-from zope.dublincore.interfaces import IZopeDublinCore
4101-from zope.interface import implements
4102-
4103-from schooltool.common import SchoolToolMessage as _
4104-from schooltool.intervention import interfaces, intervention
4105-
4106-
4107-class WidgetBase(object):
4108- """Base Class for all Widget Classes"""
4109-
4110- implements(IBrowserWidget, IInputWidget)
4111-
4112- template = None
4113- _prefix = 'field.'
4114- _error = ''
4115-
4116- # See zope.app.form.interfaces.IWidget
4117- name = None
4118- label = property(lambda self: self.context.title)
4119- hint = property(lambda self: self.context.description)
4120- visible = True
4121-
4122- # See zope.app.form.interfaces.IInputWidget
4123- required = property(lambda self: self.context.required)
4124-
4125- def __init__(self, field, request):
4126- self.context = field
4127- self.request = request
4128-
4129- def isAddView(self):
4130- return IAdding.providedBy(self.context.context)
4131-
4132- def setRenderedValue(self, value):
4133- """See zope.app.form.interfaces.IWidget"""
4134- pass
4135-
4136- def setPrefix(self, prefix):
4137- """See zope.app.form.interfaces.IWidget"""
4138- self._prefix = prefix
4139-
4140- def applyChanges(self, content):
4141- """See zope.app.form.interfaces.IInputWidget"""
4142- field = self.context
4143- new_value = self.getInputValue()
4144- old_value = field.query(content, self)
4145- if new_value == old_value:
4146- return False
4147- field.set(content, new_value)
4148- return True
4149-
4150- def hasInput(self):
4151- """See zope.app.form.interfaces.IInputWidget"""
4152- return True
4153-
4154- def hasValidInput(self):
4155- """See zope.app.form.interfaces.IInputWidget"""
4156- return True
4157-
4158- def getInputValue(self):
4159- """See zope.app.form.interfaces.IInputWidget"""
4160- return None
4161-
4162- def error(self):
4163- """See zope.app.form.browser.interfaces.IBrowserWidget"""
4164- return self._error
4165-
4166- def __call__(self):
4167- """See zope.app.form.browser.interfaces.IBrowserWidget"""
4168- return self.template()
4169-
4170-
4171-class PersonListWidget(WidgetBase):
4172- """Person List Widget"""
4173-
4174- template = ViewPageTemplateFile('person_list.pt')
4175-
4176- def __init__(self, field, request):
4177- super(PersonListWidget, self).__init__(field, request)
4178-
4179- valueList = self.getRequestValue()
4180- if self.isAddView():
4181- student = field.context.context.student
4182- else:
4183- student = field.context.student
4184- if not Update in self.request:
4185- valueList = getattr(self.context.context, field.getName())
4186-
4187- person_choices = intervention.getPersonsResponsible(student)
4188- advisors = [advisor.username for advisor in student.advisors]
4189-
4190- self.responsible = []
4191- self.notified = []
4192- for choice in person_choices:
4193- checked = ''
4194- if choice in valueList:
4195- checked = 'checked'
4196-
4197- value = intervention.convertIdToName(choice)
4198- if choice in advisors:
4199- value = 'ADVISOR: ' + value
4200- if self.isAddView() and not Update in self.request:
4201- checked = 'checked'
4202- if choice[-2] == ':':
4203- value = 'PARENT: ' + value
4204-
4205- person = {
4206- 'name': 'person.' + choice,
4207- 'checked': checked,
4208- 'value': value
4209- }
4210-
4211- if choice == student.username or choice[-2] == ':':
4212- self.notified.append(person)
4213- else:
4214- self.responsible.append(person)
4215-
4216- def getRequestValue(self):
4217- persons = []
4218- for field in self.request:
4219- if field.startswith('person.'):
4220- person = field[7:]
4221- persons.append(person)
4222- return persons
4223-
4224- def setPrefix(self, prefix):
4225- """See zope.app.form.interfaces.IWidget"""
4226- self._prefix = prefix
4227- self.name = prefix + self.context.username
4228-
4229- def getInputValue(self):
4230- """See zope.app.form.interfaces.IInputWidget"""
4231- persons = self.getRequestValue()
4232- if not persons and self.required:
4233- self._error = MissingInputError.__doc__
4234- raise MissingInputError('', '')
4235- return persons
4236-
4237- def hasValidInput(self):
4238- """See zope.app.form.interfaces.IInputWidget"""
4239- return bool(self.getInputValue())
4240-
4241-
4242-class GoalMetWidget(WidgetBase):
4243- """Goal Met Widget"""
4244-
4245- template = ViewPageTemplateFile('goal_met.pt')
4246- label = property(lambda self: '')
4247-
4248- def __init__(self, field, request):
4249- super(GoalMetWidget, self).__init__(field, request)
4250-
4251- if self.isAddView():
4252- value = False
4253- else:
4254- value = getattr(field.context, field.getName())
4255-
4256- if Update in self.request:
4257- value = self.getInputValue()
4258-
4259- self.goal_not_met = not value and 'checked' or None
4260- self.goal_met = value and 'checked' or None
4261-
4262- def getInputValue(self):
4263- """See zope.app.form.interfaces.IInputWidget"""
4264- return self.request['goal_met'] == 'Yes'
4265
4266=== removed file 'src/schooltool/intervention/configure.zcml'
4267--- src/schooltool/intervention/configure.zcml 2009-07-23 07:08:31 +0000
4268+++ src/schooltool/intervention/configure.zcml 1970-01-01 00:00:00 +0000
4269@@ -1,194 +0,0 @@
4270-<?xml version="1.0" encoding="utf-8"?>
4271-<configure xmlns="http://namespaces.zope.org/zope"
4272- xmlns:mail="http://namespaces.zope.org/mail"
4273- xmlns:security="http://schooltool.org/securitypolicy"
4274- i18n_domain="schooltool">
4275-
4276- <!-- The objects -->
4277- <class class=".intervention.InterventionRoot">
4278- <implements interface=".interfaces.IInterventionRoot" />
4279- <implements interface=".interfaces.IInterventionMarker" />
4280- <require
4281- permission="schooltool.edit"
4282- set_schema=".interfaces.IInterventionRoot" />
4283- <require
4284- permission="schooltool.view"
4285- interface=".interfaces.IInterventionRoot" />
4286- </class>
4287- <class class=".intervention.InterventionSchoolYear">
4288- <implements interface=".interfaces.IInterventionSchoolYear" />
4289- <implements interface=".interfaces.IInterventionMarker" />
4290- <require
4291- permission="schooltool.edit"
4292- set_schema=".interfaces.IInterventionSchoolYear" />
4293- <require
4294- permission="schooltool.view"
4295- interface=".interfaces.IInterventionSchoolYear" />
4296- </class>
4297- <class class=".intervention.InterventionStudent">
4298- <implements interface=".interfaces.IInterventionStudent" />
4299- <implements interface=".interfaces.IInterventionMarker" />
4300- <require
4301- permission="schooltool.edit"
4302- set_schema=".interfaces.IInterventionStudent" />
4303- <require
4304- permission="schooltool.view"
4305- interface=".interfaces.IInterventionStudent" />
4306- </class>
4307- <class class=".intervention.InterventionMessages">
4308- <implements interface=".interfaces.IInterventionMessages" />
4309- <implements interface=".interfaces.IInterventionMarker" />
4310- <require
4311- permission="schooltool.edit"
4312- set_schema=".interfaces.IInterventionMessages" />
4313- <require
4314- permission="schooltool.view"
4315- interface=".interfaces.IInterventionMessages" />
4316- </class>
4317- <class class=".intervention.InterventionMessage">
4318- <implements interface=".interfaces.IInterventionMessage" />
4319- <implements interface=".interfaces.IInterventionMarker" />
4320- <require
4321- permission="schooltool.edit"
4322- set_schema=".interfaces.IInterventionMessage" />
4323- <require
4324- permission="schooltool.view"
4325- interface=".interfaces.IInterventionMessage" />
4326- </class>
4327- <class class=".intervention.InterventionGoals">
4328- <implements interface=".interfaces.IInterventionGoals" />
4329- <implements interface=".interfaces.IInterventionMarker" />
4330- <require
4331- permission="schooltool.edit"
4332- set_schema=".interfaces.IInterventionGoals" />
4333- <require
4334- permission="schooltool.view"
4335- interface=".interfaces.IInterventionGoals" />
4336- </class>
4337- <class class=".intervention.InterventionGoal">
4338- <implements interface=".interfaces.IInterventionGoal" />
4339- <implements interface=".interfaces.IInterventionMarker" />
4340- <require
4341- permission="schooltool.edit"
4342- set_schema=".interfaces.IInterventionGoal" />
4343- <require
4344- permission="schooltool.view"
4345- interface=".interfaces.IInterventionGoal" />
4346- </class>
4347-
4348- <!-- Security -->
4349- <security:crowd
4350- name="intervention_crowd"
4351- factory=".intervention.InterventionCrowd" />
4352- <security:allow
4353- interface=".interfaces.IInterventionMarker"
4354- crowds="intervention_crowd"
4355- permission="schooltool.edit" />
4356-
4357- <!-- The application hook -->
4358- <adapter
4359- for="schooltool.app.interfaces.ISchoolToolApplication"
4360- factory=".intervention.InterventionInit"
4361- name="schooltool.interventions"
4362- />
4363-
4364- <!-- Various adapters -->
4365- <adapter
4366- factory=".intervention.getSchoolYearInterventionSchoolYear" />
4367- <adapter
4368- factory=".intervention.getSchoolToolApplicationInterventionSchoolYear" />
4369- <adapter
4370- factory=".intervention.getInterventionSchoolYearSchoolYear" />
4371-
4372- <!-- Pluggable traverser plugins for HTTP paths -->
4373- <adapterTraverserPlugin
4374- for="schooltool.schoolyear.interfaces.ISchoolYear"
4375- layer="zope.publisher.interfaces.http.IHTTPRequest"
4376- name="intervention"
4377- adapter="schooltool.intervention.interfaces.IInterventionSchoolYear"
4378- />
4379- <adapterTraverserPlugin
4380- for="schooltool.app.interfaces.ISchoolToolApplication"
4381- layer="zope.publisher.interfaces.http.IHTTPRequest"
4382- name="intervention"
4383- adapter="schooltool.intervention.interfaces.IInterventionSchoolYear"
4384- />
4385-
4386- <!-- The name choosers -->
4387- <adapter
4388- for=".interfaces.IInterventionMessages"
4389- factory=".intervention.SequenceNumberNameChooser"
4390- provides="zope.app.container.interfaces.INameChooser" />
4391- <adapter
4392- for=".interfaces.IInterventionGoals"
4393- factory=".intervention.SequenceNumberNameChooser"
4394- provides="zope.app.container.interfaces.INameChooser" />
4395-
4396- <!-- Traversal to a student's intervention -->
4397- <adapter
4398- name="intervention"
4399- for="schooltool.basicperson.interfaces.IBasicPerson
4400- zope.publisher.interfaces.http.IHTTPRequest"
4401- provides="schooltool.traverser.interfaces.ITraverserPlugin"
4402- factory=".intervention.InterventionStudentTraverserPlugin" />
4403-
4404- <!-- Traversal to a student's messages with section in traversal path -->
4405- <class class=".intervention.SectionMessagesProxy">
4406- <require permission="schooltool.view"
4407- attributes="section" />
4408- </class>
4409- <adapter
4410- name="messages"
4411- for="schooltool.course.interfaces.ISection
4412- zope.publisher.interfaces.http.IHTTPRequest"
4413- provides="schooltool.traverser.interfaces.ITraverserPlugin"
4414- factory=".intervention.SectionMessagesTraverserPlugin" />
4415- <adapter
4416- for=".intervention.SectionMessagesProxy
4417- zope.publisher.interfaces.http.IHTTPRequest"
4418- provides="zope.publisher.interfaces.IPublishTraverse"
4419- factory=".intervention.SectionMessagesTraverser" />
4420-
4421- <!-- Vocabularies -->
4422- <utility
4423- factory=".vocabularies.advisorVocabularyFactory"
4424- provides="zope.schema.interfaces.IVocabularyFactory"
4425- name="schooltool.intervention.advisor_source" />
4426-
4427- <!-- Sending email -->
4428- <subscriber
4429- for="schooltool.intervention.interfaces.IInterventionMessage zope.app.container.interfaces.IObjectAddedEvent"
4430- handler=".sendmail.sendInterventionMessageEmail"
4431- />
4432- <subscriber
4433- for="schooltool.intervention.interfaces.IInterventionGoal zope.app.container.interfaces.IObjectAddedEvent"
4434- handler=".sendmail.sendInterventionGoalAddEmail"
4435- />
4436- <!--
4437- Choose either the null utility or the three directives that follow it and place
4438- them in the site.zcml file. Hostname and port will need to be set to the real
4439- values for the smtp server.
4440- <utility
4441- provides="zope.sendmail.interfaces.IMailDelivery"
4442- name="intervention"
4443- factory="schooltool.intervention.sendmail.NullMailDelivery"
4444- />
4445- <include package="zope.sendmail" file="meta.zcml" />
4446- <mail:smtpMailer
4447- name="intervention"
4448- hostname="localhost"
4449- port="25"
4450- />
4451- <mail:queuedDelivery
4452- name="intervention"
4453- permission="schooltool.edit"
4454- queuePath="mail-queue"
4455- mailer="intervention"
4456- />
4457- -->
4458-
4459-
4460- <include package=".browser" />
4461-
4462-</configure>
4463-
4464
4465=== removed file 'src/schooltool/intervention/interfaces.py'
4466--- src/schooltool/intervention/interfaces.py 2009-07-23 07:08:31 +0000
4467+++ src/schooltool/intervention/interfaces.py 1970-01-01 00:00:00 +0000
4468@@ -1,169 +0,0 @@
4469-#
4470-# SchoolTool - common information systems platform for school administration
4471-# Copyright (c) 2005 Shuttleworth Foundation
4472-#
4473-# This program is free software; you can redistribute it and/or modify
4474-# it under the terms of the GNU General Public License as published by
4475-# the Free Software Foundation; either version 2 of the License, or
4476-# (at your option) any later version.
4477-#
4478-# This program is distributed in the hope that it will be useful,
4479-# but WITHOUT ANY WARRANTY; without even the implied warranty of
4480-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4481-# GNU General Public License for more details.
4482-#
4483-# You should have received a copy of the GNU General Public License
4484-# along with this program; if not, write to the Free Software
4485-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4486-#
4487-
4488-from zope.app import container
4489-from zope.interface import Interface, implements, Attribute
4490-from zope.schema.interfaces import IList, IBool
4491-from zope.schema import TextLine, Text, Bool, List, Date, ValidationError
4492-from zope.schema import Choice
4493-from zope.html.field import HtmlFragment
4494-
4495-from schooltool.common import SchoolToolMessage as _
4496-
4497-
4498-class IInterventionMarker(Interface):
4499- """A marker interface for all intervention classes."""
4500-
4501-
4502-class IPersonListField(IList):
4503- """A field that represents a list of people."""
4504-
4505-
4506-class PersonListField(List):
4507- """A field that represents a list of people."""
4508-
4509- implements(IPersonListField)
4510-
4511-
4512-class IGoalMetField(IBool):
4513- """A field that represents the goal met boolean."""
4514-
4515-
4516-class GoalMetField(Bool):
4517- """A field that represents the goal met boolean."""
4518-
4519- implements(IGoalMetField)
4520-
4521-
4522-class IInterventionRoot(container.interfaces.IContainer):
4523- """Container of IInterventionSchoolYear objects."""
4524-
4525- container.constraints.contains('schooltool.intervention.interfaces.IInterventionSchoolYear')
4526-
4527-
4528-class IInterventionSchoolYear(container.interfaces.IContainer):
4529- """Container of the IInteventionStudent objects."""
4530-
4531- container.constraints.contains('schooltool.intervention.interfaces.IInterventionStudent')
4532- container.constraints.containers(IInterventionRoot)
4533-
4534-
4535-class IInterventionStudent(container.interfaces.IContainer):
4536- """Container of the student's intervention containers."""
4537-
4538- student = Attribute("Student under intervention")
4539-
4540- container.constraints.contains('zope.app.container.interfaces.IContainer')
4541- container.constraints.containers(IInterventionSchoolYear)
4542-
4543-
4544-class IInterventionMessages(container.interfaces.IContainer):
4545- """Container of intervention messages."""
4546-
4547- student = Attribute("Student under intervention")
4548-
4549- container.constraints.contains('schooltool.intervention.interfaces.IInterventionMessage')
4550- container.constraints.containers(IInterventionStudent)
4551-
4552-
4553-class IInterventionMessage(container.interfaces.IContained):
4554- """Intervention message about a given student."""
4555-
4556- student = Attribute("Student under intervention")
4557-
4558- sender = TextLine(
4559- title=u"Sender's person id"
4560- )
4561-
4562- recipients = PersonListField(
4563- title=_("Recipients"),
4564- value_type=TextLine(title=u"Recipient's person id"),
4565- )
4566-
4567- body = Text(
4568- title=_("Message body.")
4569- )
4570-
4571- status_change = Bool(
4572- title=u"Status Change Message",
4573- required=False
4574- )
4575-
4576- container.constraints.containers(IInterventionMessages)
4577-
4578-
4579-class IInterventionGoals(container.interfaces.IContainer):
4580- """Container of the studnet's interventions goals."""
4581-
4582- student = Attribute("Student under intervention")
4583-
4584- container.constraints.contains('schooltool.intervention.interfaces.IInterventionGoal')
4585- container.constraints.containers(IInterventionStudent)
4586-
4587-
4588-class IInterventionGoal(container.interfaces.IContained):
4589- """intervention goal for a given student."""
4590-
4591- student = Attribute("Student under intervention")
4592-
4593- presenting_concerns = Text(
4594- title=u"Presenting concerns",
4595- )
4596-
4597- goal = Text(
4598- title=u"Goal",
4599- )
4600-
4601- strengths = Text(
4602- title=u"Strengths",
4603- )
4604-
4605- indicators = Text(
4606- title=u"Indicators",
4607- )
4608-
4609- intervention = Text(
4610- title=u"Intervention",
4611- )
4612-
4613- timeline = Date(
4614- title=u"Timeline",
4615- )
4616-
4617- persons_responsible = PersonListField(
4618- title=_("Persons responsible"),
4619- value_type=TextLine(title=u"Responsible person's person id"),
4620- )
4621-
4622- goal_met = GoalMetField(
4623- title=u"Goal met",
4624- required=False
4625- )
4626-
4627- follow_up_notes = Text(
4628- title=u"Follow-up notes",
4629- required=False
4630- )
4631-
4632- notified = Bool(
4633- title=u"Notification sent to persons responsible"
4634- )
4635-
4636- container.constraints.containers(IInterventionGoals)
4637-
4638
4639=== removed file 'src/schooltool/intervention/intervention.py'
4640--- src/schooltool/intervention/intervention.py 2009-07-23 06:13:37 +0000
4641+++ src/schooltool/intervention/intervention.py 1970-01-01 00:00:00 +0000
4642@@ -1,402 +0,0 @@
4643-#
4644-# SchoolTool - common information systems platform for school administration
4645-# Copyright (c) 2005 Shuttleworth Foundation
4646-#
4647-# This program is free software; you can redistribute it and/or modify
4648-# it under the terms of the GNU General Public License as published by
4649-# the Free Software Foundation; either version 2 of the License, or
4650-# (at your option) any later version.
4651-#
4652-# This program is distributed in the hope that it will be useful,
4653-# but WITHOUT ANY WARRANTY; without even the implied warranty of
4654-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4655-# GNU General Public License for more details.
4656-#
4657-# You should have received a copy of the GNU General Public License
4658-# along with this program; if not, write to the Free Software
4659-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4660-#
4661-
4662-from pytz import utc
4663-from persistent import Persistent
4664-from datetime import date
4665-
4666-from zope.annotation.interfaces import IAttributeAnnotatable
4667-from zope.app.container.contained import Contained, NameChooser
4668-from zope.app.container.interfaces import INameChooser
4669-from zope.app.container import btree
4670-from zope.app.security.interfaces import IUnauthenticatedPrincipal
4671-from zope.component import queryMultiAdapter, queryUtility
4672-from zope.component import adapter
4673-from zope.interface import implementer
4674-from zope.event import notify
4675-from zope.interface import implements
4676-from zope.lifecycleevent import ObjectModifiedEvent
4677-from zope.location import location
4678-from zope.publisher.interfaces import NotFound, IPublishTraverse, IRequest
4679-from zope.publisher.browser import TestRequest
4680-from zope.security import proxy, management
4681-
4682-from schooltool.app.app import InitBase
4683-from schooltool.app.interfaces import ISchoolToolApplication
4684-from schooltool.basicperson.interfaces import IBasicPerson
4685-from schooltool.contact.interfaces import IContactable
4686-from schooltool.contact.contact import Contact
4687-from schooltool.course.interfaces import ISectionContainer
4688-from schooltool.group.interfaces import IGroupContainer
4689-from schooltool.person.interfaces import IPerson
4690-from schooltool.schoolyear.interfaces import ISchoolYear
4691-from schooltool.schoolyear.interfaces import ISchoolYearContainer
4692-from schooltool.securitypolicy import crowds
4693-from schooltool.term.interfaces import IDateManager
4694-from schooltool.traverser.traverser import NameTraverserPlugin
4695-
4696-import interfaces
4697-
4698-
4699-def getRequest():
4700- """Return the request object for the current request.
4701- In the case of unit testing, return a TestRequest instance."""
4702-
4703- i = management.getInteraction()
4704- for p in i.participations:
4705- if IRequest.providedBy(p):
4706- return p
4707- return TestRequest()
4708-
4709-
4710-def convertIdToPerson(id):
4711- return ISchoolToolApplication(None)['persons'][id]
4712-
4713-
4714-def convertIdToNameWithSort(id):
4715- if id[-2] == ':':
4716- student = convertIdToPerson(id[:-2])
4717- for index, contact in enumerate(IContactable(student).contacts):
4718- if id[-1] == str(index + 1):
4719- first_name = contact.first_name
4720- last_name = contact.last_name
4721- break
4722- else:
4723- raise IndexError
4724- else:
4725- person = convertIdToPerson(id)
4726- first_name = person.first_name
4727- last_name = person.last_name
4728- name = '%s %s' % (first_name, last_name)
4729- sort = (last_name, first_name)
4730- return sort, name
4731-
4732-
4733-def convertIdToName(id):
4734- sort, name = convertIdToNameWithSort(id)
4735- return name
4736-
4737-
4738-def convertIdsToNames(ids):
4739- return [name for sort, name in
4740- sorted([convertIdToNameWithSort(id) for id in ids])]
4741-
4742-
4743-def convertIdToEmail(id):
4744- if id[-2] == ':':
4745- student = convertIdToPerson(id[:-2])
4746- for index, contact in enumerate(IContactable(student).contacts):
4747- if id[-1] == str(index + 1):
4748- return contact.email
4749- else:
4750- raise IndexError
4751- else:
4752- return id + '@scienceleadership.org'
4753-
4754-
4755-def convertIdsToEmail(ids):
4756- return sorted([convertIdToEmail(id) for id in ids])
4757-
4758-
4759-def getPersonsResponsible(student):
4760- """Return the list of persons responsible for the student.
4761- This includes all teachers that teach the student, the student's
4762- advisors, and all members of the school administation.
4763- Additionally, we will include the student and the student's
4764- parents (designated by student id + :1 or :2) in this list
4765- for the purpose of sending emails, but they will be filtered
4766- out of any application elements that are for staff only."""
4767-
4768- responsible = [advisor.username for advisor in student.advisors]
4769-
4770- term = queryUtility(IDateManager).current_term
4771- groups = IGroupContainer(ISchoolYear(term))
4772- sections = ISectionContainer(term)
4773-
4774- for member in groups['administrators'].members:
4775- if member.username not in responsible:
4776- responsible.append(member.username)
4777-
4778- for section in sections.values():
4779- if student in section.members:
4780- for teacher in section.instructors:
4781- if teacher.username not in responsible:
4782- responsible.append(teacher.username)
4783-
4784- responsible.append(student.username)
4785- for index, contact in enumerate(IContactable(student).contacts):
4786- responsible.append(student.username + ':%d' % (index + 1))
4787-
4788- return responsible
4789-
4790-
4791-class InterventionCrowd(crowds.Crowd):
4792- """Crowd of persons that can work with interventions.
4793- This includes teachers, school administrators and site mangers."""
4794-
4795- def contains(self, principal):
4796- if IUnauthenticatedPrincipal.providedBy(principal):
4797- return False
4798- if crowds.ManagersCrowd(self.context).contains(principal):
4799- return True
4800- if crowds.AdministratorsCrowd(self.context).contains(principal):
4801- return True
4802- if crowds.TeachersCrowd(self.context).contains(principal):
4803- return True
4804- return False
4805-
4806-
4807-class InterventionRoot(btree.BTreeContainer):
4808- """Container of InterventionSchoolYear objects."""
4809-
4810- implements(interfaces.IInterventionRoot)
4811-
4812-
4813-class InterventionSchoolYear(btree.BTreeContainer):
4814- """Container of InteventionStudent objects."""
4815-
4816- implements(interfaces.IInterventionSchoolYear)
4817-
4818-
4819-class InterventionStudent(btree.BTreeContainer):
4820- """Container of the student's intervention containers."""
4821-
4822- implements(interfaces.IInterventionStudent)
4823-
4824- def __init__(self):
4825- super(InterventionStudent, self).__init__()
4826-
4827- @property
4828- def student(self):
4829- app = ISchoolToolApplication(None)
4830- if self.__name__ in app['persons']:
4831- return app['persons'][self.__name__]
4832- else:
4833- return None
4834-
4835-
4836-class InterventionMessages(btree.BTreeContainer):
4837- """Container of Tier1 InteventionMessage objects."""
4838-
4839- implements(interfaces.IInterventionMessages)
4840-
4841- @property
4842- def student(self):
4843- try:
4844- return self.__parent__.student
4845- except:
4846- return None
4847-
4848-
4849-class InterventionMessage(Persistent, Contained):
4850- """Intervention message about a given student."""
4851-
4852- implements(interfaces.IInterventionMessage, IAttributeAnnotatable)
4853-
4854- def __init__(self, sender, recipients, body, status_change=False):
4855- self.sender = sender
4856- self.recipients = recipients
4857- self.body = body
4858- self.status_change = status_change
4859-
4860- @property
4861- def student(self):
4862- try:
4863- return self.__parent__.student
4864- except:
4865- return None
4866-
4867-
4868-class InterventionGoals(btree.BTreeContainer):
4869- """Container of InterventionGoal objects."""
4870-
4871- implements(interfaces.IInterventionGoals)
4872-
4873- @property
4874- def student(self):
4875- try:
4876- return self.__parent__.student
4877- except:
4878- return None
4879-
4880-
4881-class InterventionGoal(Persistent, Contained):
4882- """Intervention goal for a given student.
4883- """
4884- implements(interfaces.IInterventionGoal, IAttributeAnnotatable)
4885-
4886- def __init__(self, presenting_concerns, goal, strengths, indicators,
4887- intervention, timeline, persons_responsible, goal_met=False,
4888- follow_up_notes=u''):
4889- self.presenting_concerns = presenting_concerns
4890- self.goal = goal
4891- self.strengths = strengths
4892- self.indicators = indicators
4893- self.intervention = intervention
4894- self.timeline = timeline
4895- self.persons_responsible = persons_responsible
4896- self.goal_met = goal_met
4897- self.follow_up_notes = follow_up_notes
4898- self.notified = False
4899-
4900- @property
4901- def student(self):
4902- try:
4903- return self.__parent__.student
4904- except:
4905- return None
4906-
4907-
4908-class InterventionInit(InitBase):
4909- """Create the InterventionRoot object."""
4910-
4911- def __call__(self):
4912- self.app[u'schooltool.interventions'] = InterventionRoot()
4913-
4914-
4915-@adapter(ISchoolYear)
4916-@implementer(interfaces.IInterventionSchoolYear)
4917-def getSchoolYearInterventionSchoolYear(schoolyear):
4918- return getInterventionSchoolYear(schoolyear.__name__)
4919-
4920-
4921-@adapter(ISchoolToolApplication)
4922-@implementer(interfaces.IInterventionSchoolYear)
4923-def getSchoolToolApplicationInterventionSchoolYear(app):
4924- return getInterventionSchoolYear()
4925-
4926-
4927-@adapter(interfaces.IInterventionSchoolYear)
4928-@implementer(ISchoolYear)
4929-def getInterventionSchoolYearSchoolYear(schoolyear):
4930- app = ISchoolToolApplication(None)
4931- return ISchoolYearContainer(app)[schoolyear.__name__]
4932-
4933-
4934-def getInterventionSchoolYear(schoolYearId=None):
4935- """Get InterventionSchoolYear object for the given school yearr.
4936- If school year not specified, use current school year."""
4937-
4938- app = ISchoolToolApplication(None)
4939- interventionRoot = app[u'schooltool.interventions']
4940- if not schoolYearId:
4941- term = queryUtility(IDateManager).current_term
4942- schoolyear = ISchoolYear(term)
4943- schoolYearId = schoolyear.__name__
4944- try:
4945- interventionSchoolYear = interventionRoot[schoolYearId]
4946- except KeyError:
4947- interventionSchoolYear = InterventionSchoolYear()
4948- interventionRoot[schoolYearId] = interventionSchoolYear
4949- return interventionSchoolYear
4950-
4951-
4952-def getInterventionStudent(studentId, schoolYearId=None):
4953- """Get InterventionStudent object for the given student, school year pair.
4954- If school year not specified, use current school year.
4955- Create InterventionSchoolYear and InterventionStudent objects if
4956- not already present."""
4957-
4958- interventionSchoolYear = getInterventionSchoolYear(schoolYearId)
4959- try:
4960- interventionStudent = interventionSchoolYear[studentId]
4961- except KeyError:
4962- interventionStudent = InterventionStudent()
4963- interventionSchoolYear[studentId] = interventionStudent
4964- interventionStudent[u'messages'] = InterventionMessages()
4965- interventionStudent[u'goals'] = InterventionGoals()
4966- return interventionStudent
4967-
4968-
4969-class SequenceNumberNameChooser(NameChooser):
4970- """A name chooser that returns a sequence number."""
4971-
4972- implements(INameChooser)
4973-
4974- def chooseName(self, name, obj):
4975- """See INameChooser."""
4976- numbers = [int(v.__name__) for v in self.context.values()
4977- if v.__name__.isdigit()]
4978- if numbers:
4979- n = str(max(numbers) + 1)
4980- else:
4981- n = '1'
4982- self.checkName(n, obj)
4983- return n
4984-
4985-
4986-class InterventionStudentTraverserPlugin(NameTraverserPlugin):
4987- """Allows traversal to a student's intervention object.
4988-
4989- i.e. if you go to localhost/persons/somestudent/intervention this traverser
4990- will get called instead of standard traverser. It returns the student's
4991- intervention object for the current school year.
4992- """
4993-
4994- traversalName = "intervention"
4995- def _traverse(self, request, name):
4996- interventionStudent = getInterventionStudent(self.context.__name__)
4997- return interventionStudent
4998-
4999-
5000-class SectionMessagesProxy(object):
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: