source: main/waeup.sirp/trunk/src/waeup/sirp/students/viewlets.py @ 7724

Last change on this file since 7724 was 7694, checked in by Henrik Bettermann, 13 years ago

Remove unneeded import.

  • Property svn:keywords set to Id
File size: 24.7 KB
RevLine 
[7191]1## $Id: viewlets.py 7694 2012-02-23 17:35:54Z henrik $
2##
3## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; if not, write to the Free Software
16## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17##
[7106]18import os
[6642]19import grok
[7097]20from zope.component import getUtility
[6642]21from zope.interface import Interface
[7097]22from waeup.sirp.interfaces import (
[7321]23    ISIRPObject, IExtFileStore, IFileStoreNameChooser)
[7097]24from waeup.sirp.utils.helpers import string_from_bytes, file_size
25from waeup.sirp.browser import DEFAULT_IMAGE_PATH
[7591]26from waeup.sirp.browser.viewlets import (
27    PrimaryNavTab, ManageActionButton, AddActionButton)
[7243]28from waeup.sirp.browser.layout import default_primary_nav_template
[7591]29from waeup.sirp.students.workflow import (ADMITTED, PAID,
30    CLEARANCE, REQUESTED, RETURNING, CLEARED, REGISTERED, VALIDATED)
[7097]31from waeup.sirp.students.browser import (
[7591]32    StudentClearanceManageFormPage,
33    write_log_message, StudentBaseManageFormPage,
34    StudentFilesUploadPage, ExportPDFClearanceSlipPage, StudentsContainerPage,
35    StudentsContainerManagePage, StudentBaseDisplayFormPage,
36    StudentClearanceDisplayFormPage, StudentPersonalDisplayFormPage,
37    StudyCourseDisplayFormPage, StudyLevelDisplayFormPage,
38    CourseTicketDisplayFormPage, OnlinePaymentDisplayFormPage,
39    AccommodationManageFormPage, BedTicketDisplayFormPage,)
40from waeup.sirp.students.interfaces import (
41    IStudentsContainer, IStudent, IStudentClearance,
42    IStudentStudyCourse, IStudentAccommodation, IStudentStudyLevel,
43    ICourseTicket, IStudentOnlinePayment, IBedTicket,
44    )
[6642]45
[7693]46from waeup.sirp.interfaces import MessageFactory as _
[7674]47
[7321]48grok.context(ISIRPObject) # Make ISIRPObject the default context
[6687]49grok.templatedir('browser_templates')
[6642]50
[7123]51ALLOWED_FILE_EXTENSIONS = ('jpg', 'png', 'pdf', 'tif')
52
[6687]53class StudentManageSidebar(grok.ViewletManager):
54    grok.name('left_studentmanage')
[6642]55
[6687]56class StudentManageLink(grok.Viewlet):
[6660]57    """A link displayed in the student box which shows up for StudentNavigation
[6642]58    objects.
59
60    """
61    grok.baseclass()
[6687]62    grok.viewletmanager(StudentManageSidebar)
[7321]63    grok.context(ISIRPObject)
[6642]64    grok.view(Interface)
65    grok.order(5)
[6660]66    grok.require('waeup.viewStudent')
[6642]67
68    link = 'index'
69    text = u'Base Data'
70
71    def render(self):
72        url = self.view.url(self.context.getStudent(), self.link)
[7459]73        return u'<li><a href="%s">%s</a></li>' % (
[6642]74                url, self.text)
75
[7459]76class StudentManageApplicationLink(StudentManageLink):
[6687]77    grok.order(1)
[7351]78    link = 'application_slip'
79    text = u'Application Slip'
[7340]80
81    def render(self):
[7351]82        slip = getUtility(IExtFileStore).getFileByContext(
83            self.context.getStudent(), attr=self.link)
84        if slip:
85            url = self.view.url(self.context,self.link)
[7459]86            return u'<li><a href="%s">%s</a></li>' % (
[7340]87                    url, self.text)
88        return ''
89
[7459]90class StudentManageBaseLink(StudentManageLink):
91    grok.order(2)
92    link = 'index'
93    text = u'Base Data'
94
[6687]95class StudentManageClearanceLink(StudentManageLink):
[7340]96    grok.order(3)
[6687]97    link = 'view_clearance'
98    text = u'Clearance Data'
99
100class StudentManagePersonalLink(StudentManageLink):
[7340]101    grok.order(4)
[6687]102    link = 'view_personal'
103    text = u'Personal Data'
104
105class StudentManageStudyCourseLink(StudentManageLink):
[7340]106    grok.order(5)
[6687]107    link = 'studycourse'
108    text = u'Study Course'
109
110class StudentManagePaymentsLink(StudentManageLink):
[7340]111    grok.order(6)
[7181]112    grok.require('waeup.payStudent')
[6687]113    link = 'payments'
114    text = u'Payments'
115
116class StudentManageAccommodationLink(StudentManageLink):
[7340]117    grok.order(7)
[7181]118    grok.require('waeup.handleAccommodation')
[6687]119    link = 'accommodation'
[7459]120    text = u'Accommodation'
[6687]121
122class StudentManageHistoryLink(StudentManageLink):
[7340]123    grok.order(8)
[6687]124    link = 'history'
125    text = u'History'
126
[7591]127
128class StudentsContainerManageActionButton(ManageActionButton):
129    grok.order(1)
130    grok.context(IStudentsContainer)
131    grok.view(StudentsContainerPage)
132    grok.require('waeup.manageStudent')
133    text = 'Manage student section'
134
135class StudentsContainerAddActionButton(AddActionButton):
136    grok.order(1)
137    grok.context(IStudentsContainer)
138    grok.view(StudentsContainerManagePage)
139    grok.require('waeup.manageStudent')
140    text = 'Add student'
141    target = 'addstudent'
142
143class ContactActionButton(ManageActionButton):
144    grok.order(4)
145    grok.context(IStudent)
146    grok.view(StudentBaseDisplayFormPage)
147    grok.require('waeup.manageStudent')
148    icon = 'actionicon_mail.png'
149    text = 'Send email'
150    target = 'contactstudent'
151
152class StudentBaseManageActionButton(ManageActionButton):
153    grok.order(1)
154    grok.context(IStudent)
155    grok.view(StudentBaseDisplayFormPage)
156    grok.require('waeup.manageStudent')
157    text = 'Manage'
158    target = 'manage_base'
159
160class StudentClearanceManageActionButton(ManageActionButton):
161    grok.order(1)
162    grok.context(IStudent)
163    grok.view(StudentClearanceDisplayFormPage)
164    grok.require('waeup.manageStudent')
165    text = 'Manage'
166    target = 'edit_clearance'
167
168class StudentClearActionButton(ManageActionButton):
169    grok.order(2)
170    grok.context(IStudent)
171    grok.view(StudentClearanceDisplayFormPage)
172    grok.require('waeup.clearStudent')
173    text = 'Clear student'
174    target = 'clear'
175    icon = 'actionicon_accept.png'
176
177    @property
178    def target_url(self):
179        if self.context.state != REQUESTED:
180            return ''
181        return self.view.url(self.view.context, self.target)
182
183class StudentRejectClearanceActionButton(ManageActionButton):
184    grok.order(3)
185    grok.context(IStudent)
186    grok.view(StudentClearanceDisplayFormPage)
187    grok.require('waeup.clearStudent')
188    text = 'Reject clearance'
189    target = 'reject_clearance'
190    icon = 'actionicon_reject.png'
191
192    @property
193    def target_url(self):
194        if self.context.state not in (REQUESTED, CLEARED):
195            return ''
196        return self.view.url(self.view.context, self.target)
197
198class ClearanceSlipActionButton(ManageActionButton):
199    grok.order(4)
200    grok.context(IStudent)
201    grok.view(StudentClearanceDisplayFormPage)
202    grok.require('waeup.viewStudent')
203    icon = 'actionicon_pdf.png'
204    text = 'Download clearance slip'
205    target = 'clearance.pdf'
206
207class StudentPersonalEditActionButton(ManageActionButton):
208    grok.order(1)
209    grok.context(IStudent)
210    grok.view(StudentPersonalDisplayFormPage)
211    grok.require('waeup.viewStudent')
212    text = 'Edit'
213    target = 'edit_personal'
214
215class StudyCourseManageActionButton(ManageActionButton):
216    grok.order(1)
217    grok.context(IStudentStudyCourse)
218    grok.view(StudyCourseDisplayFormPage)
219    grok.require('waeup.manageStudent')
220    text = 'Manage'
221    target = 'manage'
222
223class CourseRegistrationSlipActionButton(ManageActionButton):
224    grok.order(1)
225    grok.context(IStudentStudyLevel)
226    grok.view(StudyLevelDisplayFormPage)
227    grok.require('waeup.viewStudent')
228    icon = 'actionicon_pdf.png'
229    text = 'Download course registration slip'
230    target = 'course_registration.pdf'
231
232class StudyLevelManageActionButton(ManageActionButton):
233    grok.order(2)
234    grok.context(IStudentStudyLevel)
235    grok.view(StudyLevelDisplayFormPage)
236    grok.require('waeup.manageStudent')
237    text = 'Manage'
238    target = 'manage'
239
240class StudentValidateCoursesActionButton(ManageActionButton):
241    grok.order(3)
242    grok.context(IStudentStudyLevel)
243    grok.view(StudyLevelDisplayFormPage)
244    grok.require('waeup.validateStudent')
245    text = 'Validate courses'
246    target = 'validate_courses'
247    icon = 'actionicon_accept.png'
248
249    @property
250    def target_url(self):
251        if self.context.getStudent().state != REGISTERED or \
252            str(self.context.__parent__.current_level) != self.context.__name__:
253            return ''
254        return self.view.url(self.view.context, self.target)
255
256class StudentRejectCoursesActionButton(ManageActionButton):
257    grok.order(4)
258    grok.context(IStudentStudyLevel)
259    grok.view(StudyLevelDisplayFormPage)
260    grok.require('waeup.validateStudent')
261    text = 'Reject courses'
262    target = 'reject_courses'
263    icon = 'actionicon_reject.png'
264
265    @property
266    def target_url(self):
267        if self.context.getStudent().state not in (VALIDATED, REGISTERED) or \
268            str(self.context.__parent__.current_level) != self.context.__name__:
269            return ''
270        return self.view.url(self.view.context, self.target)
271
272class CourseTicketManageActionButton(ManageActionButton):
273    grok.order(1)
274    grok.context(ICourseTicket)
275    grok.view(CourseTicketDisplayFormPage)
276    grok.require('waeup.manageStudent')
277    text = 'Manage'
278    target = 'manage'
279
280#class OnlinePaymentManageActionButton(ManageActionButton):
281#    grok.order(1)
282#    grok.context(IStudentPaymentsContainer)
283#    grok.view(PaymentsDisplayFormPage)
284#    grok.require('waeup.manageStudent')
285#    text = 'Manage payments'
286#    target = 'manage'
287
288class PaymentReceiptActionButton(ManageActionButton):
289    grok.order(1)
290    grok.context(IStudentOnlinePayment)
291    grok.view(OnlinePaymentDisplayFormPage)
292    grok.require('waeup.viewStudent')
293    icon = 'actionicon_pdf.png'
294    text = 'Download payment receipt'
295    target = 'payment_receipt.pdf'
296
297    @property
298    def target_url(self):
299        if self.context.p_state != 'paid':
300            return ''
301        return self.view.url(self.view.context, self.target)
302
303class RequestCallbackActionButton(ManageActionButton):
304    grok.order(2)
305    grok.context(IStudentOnlinePayment)
306    grok.view(OnlinePaymentDisplayFormPage)
307    grok.require('waeup.payStudent')
308    icon = 'actionicon_call.png'
309    text = 'Request callback'
310    target = 'callback'
311
312    @property
313    def target_url(self):
314        if self.context.p_state != 'unpaid':
315            return ''
316        return self.view.url(self.view.context, self.target)
317
318class AddBedTicketActionButton(ManageActionButton):
319    grok.order(1)
320    grok.context(IStudentAccommodation)
321    grok.view(AccommodationManageFormPage)
322    grok.require('waeup.handleAccommodation')
323    icon = 'actionicon_home.png'
324    text = 'Book accommodation'
325    target = 'add'
326
327class BedTicketSlipActionButton(ManageActionButton):
328    grok.order(1)
329    grok.context(IBedTicket)
330    grok.view(BedTicketDisplayFormPage)
331    grok.require('waeup.handleAccommodation')
332    icon = 'actionicon_pdf.png'
333    text = 'Download bed allocation slip'
334    target = 'bed_allocation.pdf'
335
336class RelocateStudentActionButton(ManageActionButton):
337    grok.order(2)
338    grok.context(IBedTicket)
339    grok.view(BedTicketDisplayFormPage)
340    grok.require('waeup.manageHostels')
341    icon = 'actionicon_reload.png'
342    text = 'Relocate student'
343    target = 'relocate'
344
345class StudentBaseActionButton(ManageActionButton):
346    grok.order(1)
347    grok.context(IStudent)
348    grok.view(StudentBaseDisplayFormPage)
349    grok.require('waeup.handleStudent')
350    text = 'Edit base data'
351    target = 'edit_base'
352
353class StudentPasswordActionButton(ManageActionButton):
354    grok.order(2)
355    grok.context(IStudent)
356    grok.view(StudentBaseDisplayFormPage)
357    grok.require('waeup.handleStudent')
358    icon = 'actionicon_key.png'
359    text = 'Change password'
360    target = 'change_password'
361
362class StudentPassportActionButton(ManageActionButton):
363    grok.order(3)
364    grok.context(IStudent)
365    grok.view(StudentBaseDisplayFormPage)
366    grok.require('waeup.handleStudent')
367    icon = 'actionicon_portrait.png'
368    text = 'Change portrait'
369    target = 'change_portrait'
370
371    @property
372    def target_url(self):
[7671]373        if self.context.state != ADMITTED:
[7591]374            return ''
375        return self.view.url(self.view.context, self.target)
376
377class StudentClearanceStartActionButton(ManageActionButton):
378    grok.order(1)
379    grok.context(IStudent)
380    grok.view(StudentClearanceDisplayFormPage)
381    grok.require('waeup.handleStudent')
382    icon = 'actionicon_start.gif'
383    text = 'Start clearance'
384    target = 'start_clearance'
385
386    @property
387    def target_url(self):
[7671]388        if self.context.state != ADMITTED:
[7591]389            return ''
390        return self.view.url(self.view.context, self.target)
391
392class StudentClearanceEditActionButton(ManageActionButton):
393    grok.order(1)
394    grok.context(IStudent)
395    grok.view(StudentClearanceDisplayFormPage)
396    grok.require('waeup.handleStudent')
397    text = 'Edit'
398    target = 'cedit'
399
400    @property
401    def target_url(self):
402        if self.context.clearance_locked:
403            return ''
404        return self.view.url(self.view.context, self.target)
405
406class CourseRegistrationStartActionButton(ManageActionButton):
407    grok.order(1)
408    grok.context(IStudentStudyCourse)
409    grok.view(StudyCourseDisplayFormPage)
410    grok.require('waeup.handleStudent')
411    icon = 'actionicon_start.gif'
412    text = 'Start course registration'
413    target = 'start_course_registration'
414
415    @property
416    def target_url(self):
417        if not self.context.getStudent().state in (CLEARED,RETURNING):
418            return ''
419        return self.view.url(self.view.context, self.target)
420
421class AddStudyLevelActionButton(AddActionButton):
422    grok.order(1)
423    grok.context(IStudentStudyCourse)
424    grok.view(StudyCourseDisplayFormPage)
425    grok.require('waeup.handleStudent')
426    text = 'Add course list'
427    target = 'add'
428
429    @property
430    def target_url(self):
431        student = self.view.context.getStudent()
[7671]432        condition1 = student.state != PAID
[7591]433        condition2 = str(student['studycourse'].current_level) in \
434            self.view.context.keys()
435        if condition1 or condition2:
436            return ''
437        return self.view.url(self.view.context, self.target)
438
439class StudyLevelEditActionButton(ManageActionButton):
440    grok.order(1)
441    grok.context(IStudentStudyLevel)
442    grok.view(StudyLevelDisplayFormPage)
443    grok.require('waeup.handleStudent')
444    text = 'Add and remove courses'
445    target = 'edit'
446
447    @property
448    def target_url(self):
449        student = self.view.context.getStudent()
[7671]450        condition1 = student.state != PAID
[7591]451        condition2 = student[
452            'studycourse'].current_level != self.view.context.level
453        if condition1 or condition2:
454            return ''
455        return self.view.url(self.view.context, self.target)
456
[7184]457class StudentsTab(PrimaryNavTab):
458    """Students tab in primary navigation.
459    """
460
[7321]461    grok.context(ISIRPObject)
[7184]462    grok.order(4)
[7240]463    grok.require('waeup.viewStudentsTab')
[7184]464
465    pnav = 4
[7674]466    tab_title = _(u'Students')
[7184]467
468    @property
469    def link_target(self):
470        return self.view.application_url('students')
471
[6687]472class PrimaryStudentNavManager(grok.ViewletManager):
473    """Viewlet manager for the primary navigation tab.
474    """
475    grok.name('primary_nav_student')
476
477class PrimaryStudentNavTab(grok.Viewlet):
478    """Base for primary student nav tabs.
479    """
480    grok.baseclass()
481    grok.viewletmanager(PrimaryStudentNavManager)
[7243]482    template = default_primary_nav_template
[6687]483    grok.order(1)
[7184]484    grok.require('waeup.Authenticated')
[6687]485    pnav = 0
486    tab_title = u'Some Text'
487
488    @property
489    def link_target(self):
490        return self.view.application_url()
491
492    @property
493    def active(self):
494        view_pnav = getattr(self.view, 'pnav', 0)
495        if view_pnav == self.pnav:
496            return 'active'
497        return ''
498
[7240]499class MyStudentDataTab(PrimaryStudentNavTab):
[7459]500    """MyData dropdown tab in primary navigation.
[6687]501    """
502    grok.order(3)
[7240]503    grok.require('waeup.viewMyStudentDataTab')
[7459]504    grok.template('mydatadropdowntabs')
[6687]505    pnav = 4
506    tab_title = u'My Data'
507
508    @property
[7459]509    def active(self):
510        view_pnav = getattr(self.view, 'pnav', 0)
511        if view_pnav == self.pnav:
512            return 'active dropdown'
513        return 'dropdown'
[7097]514
[7459]515    @property
516    def targets(self):
517        student_url = self.view.application_url() + (
518            '/students/%s' % self.request.principal.id)
519        #app_slip = getUtility(IExtFileStore).getFileByContext(
520        #    self.context.getStudent(), 'application_slip')
521        targets = []
522        #if app_slip:
523        #    targets = [{'url':student_url + '/application_slip', 'title':'Application Slip'},]
524        targets += [
525            {'url':student_url, 'title':'Base Data'},
526            {'url':student_url + '/view_clearance', 'title':'Clearance Data'},
527            {'url':student_url + '/view_personal', 'title':'Personal Data'},
528            {'url':student_url + '/studycourse', 'title':'Study Course'},
529            {'url':student_url + '/payments', 'title':'Payments'},
530            {'url':student_url + '/accommodation', 'title':'Accommodation Data'},
531            {'url':student_url + '/history', 'title':'History'},
532            ]
533        return targets
534
[7107]535def handle_file_delete(context, view, download_name):
536    """Handle deletion of student file.
537
538    """
539    store = getUtility(IExtFileStore)
540    store.deleteFileByContext(context, attr=download_name)
[7108]541    write_log_message(view, 'deleted: %s' % download_name)
[7123]542    view.flash('%s deleted.' % download_name)
[7107]543    return
544
[7106]545def handle_file_upload(upload, context, view, max_size, download_name=None):
546    """Handle upload of student file.
[7097]547
548    Returns `True` in case of success or `False`.
549
550    Please note that file pointer passed in (`upload`) most probably
551    points to end of file when leaving this function.
552    """
[7106]553    # Check some file requirements first
554    if upload.filename.count('.') == 0:
555        view.flash('File name has no extension.')
556        return False
557    if upload.filename.count('.') > 1:
558        view.flash('File name contains more than one dot.')
559        return False
560    basename, expected_ext = os.path.splitext(download_name)
561    dummy, ext = os.path.splitext(upload.filename)
562    ext.lower()
[7123]563    if expected_ext:
564        if ext != expected_ext:
565            view.flash('%s file extension expected.' %
566                expected_ext.replace('.',''))
567            return False
568    else:
569        if not ext.replace('.','') in ALLOWED_FILE_EXTENSIONS:
570            view.flash(
571                'Only the following extension are allowed: %s' %
572                ', '.join(ALLOWED_FILE_EXTENSIONS))
573            return False
574        download_name += ext
[7097]575    size = file_size(upload)
576    if size > max_size:
[7106]577        view.flash('Uploaded file is too big.')
[7097]578        return False
579    upload.seek(0) # file pointer moved when determining size
580    store = getUtility(IExtFileStore)
[7106]581    file_id = IFileStoreNameChooser(context).chooseName(attr=download_name)
[7097]582    store.createFile(file_id, upload)
[7108]583    write_log_message(view, 'uploaded: %s (%s)' % (download_name,upload.filename))
584    view.flash('File %s uploaded.' % download_name)
[7097]585    return True
586
587class FileManager(grok.ViewletManager):
588    """Viewlet manager for uploading files, preferably scanned images.
589    """
590    grok.name('files')
591
592class FileDisplay(grok.Viewlet):
593    """Base file display viewlet.
594    """
595    grok.baseclass()
[7100]596    grok.context(IStudentClearance)
[7097]597    grok.viewletmanager(FileManager)
598    grok.view(StudentClearanceDisplayFormPage)
599    grok.template('filedisplay')
600    grok.order(1)
601    grok.require('waeup.viewStudent')
[7319]602    label = u'File'
[7127]603    title = u'Scan'
[7106]604    download_name = u'filename.jpg'
[7097]605
[7107]606    @property
607    def file_exists(self):
608        image = getUtility(IExtFileStore).getFileByContext(
609            self.context, attr=self.download_name)
610        if image:
611            return True
612        else:
613            return False
614
[7097]615class FileUpload(FileDisplay):
616    """Base upload viewlet.
617    """
618    grok.baseclass()
[7100]619    grok.context(IStudentClearance)
[7097]620    grok.viewletmanager(FileManager)
621    grok.view(StudentClearanceManageFormPage)
622    grok.template('fileupload')
[7127]623    grok.require('waeup.uploadStudentFile')
[7491]624    tab_redirect = '?tab2'
[7097]625    mus = 1024 * 150
626
[7117]627    @property
628    def input_name(self):
629        return "%s" % self.__name__
630
[7097]631    def update(self):
632        self.max_upload_size = string_from_bytes(self.mus)
[7117]633        delete_button = self.request.form.get(
634            'delete_%s' % self.input_name, None)
635        upload_button = self.request.form.get(
636            'upload_%s' % self.input_name, None)
[7108]637        if delete_button:
[7107]638            handle_file_delete(
639                context=self.context, view=self.view,
640                download_name=self.download_name)
641            self.view.redirect(
[7134]642                self.view.url(
643                    self.context, self.view.__name__) + self.tab_redirect)
[7107]644            return
[7108]645        if upload_button:
646            upload = self.request.form.get(self.input_name, None)
647            if upload:
648                # We got a fresh upload
[7111]649                handle_file_upload(upload,
650                    self.context, self.view, self.mus, self.download_name)
651                self.view.redirect(
[7134]652                    self.view.url(
653                        self.context, self.view.__name__) + self.tab_redirect)
[7117]654            else:
655                self.view.flash('No local file selected.')
656                self.view.redirect(
[7134]657                    self.view.url(
658                        self.context, self.view.__name__) + self.tab_redirect)
[7097]659        return
660
[7112]661class PassportDisplay(FileDisplay):
662    """Passport display viewlet.
663    """
664    grok.order(1)
665    grok.context(IStudent)
666    grok.view(StudentBaseDisplayFormPage)
667    grok.require('waeup.viewStudent')
668    grok.template('imagedisplay')
[7319]669    label = u'Passport Picture'
[7112]670    download_name = u'passport.jpg'
671
672class PassportUploadManage(FileUpload):
673    """Passport upload viewlet for officers.
674    """
675    grok.order(1)
676    grok.context(IStudent)
677    grok.view(StudentBaseManageFormPage)
[7136]678    grok.require('waeup.manageStudent')
[7112]679    grok.template('imageupload')
[7319]680    label = u'Passport Picture (jpg only)'
[7112]681    mus = 1024 * 50
682    download_name = u'passport.jpg'
[7491]683    tab_redirect = '?tab2'
[7112]684
685class PassportUploadEdit(PassportUploadManage):
686    """Passport upload viewlet for students.
687    """
[7114]688    grok.view(StudentFilesUploadPage)
[7127]689    grok.require('waeup.uploadStudentFile')
[7112]690
[7097]691class BirthCertificateDisplay(FileDisplay):
[7112]692    """Birth Certificate display viewlet.
[7097]693    """
694    grok.order(1)
[7319]695    label = u'Birth Certificate'
[7127]696    title = u'Birth Certificate Scan'
[7123]697    download_name = u'birth_certificate'
[7097]698
[7280]699class BirthCertificateSlip(BirthCertificateDisplay):
700    grok.view(ExportPDFClearanceSlipPage)
701
[7127]702class BirthCertificateUpload(FileUpload):
[7097]703    """Birth Certificate upload viewlet.
704    """
705    grok.order(1)
[7319]706    label = u'Birth Certificate'
[7127]707    title = u'Birth Certificate Scan'
[7097]708    mus = 1024 * 150
[7123]709    download_name = u'birth_certificate'
[7491]710    tab_redirect = '?tab2'
[7097]711
[7111]712class AcceptanceLetterDisplay(FileDisplay):
[7112]713    """Acceptance Letter display viewlet.
[7111]714    """
715    grok.order(1)
[7319]716    label = u'Acceptance Letter'
[7127]717    title = u'Acceptance Letter Scan'
[7123]718    download_name = u'acceptance_letter'
[7111]719
[7280]720class AcceptanceLetterSlip(AcceptanceLetterDisplay):
721    grok.view(ExportPDFClearanceSlipPage)
722
[7127]723class AcceptanceLetterUpload(FileUpload):
[7111]724    """AcceptanceLetter upload viewlet.
725    """
[7112]726    grok.order(2)
[7319]727    label = u'Acceptance Letter'
[7127]728    title = u'Acceptance Letter Scan'
[7111]729    mus = 1024 * 150
[7123]730    download_name = u'acceptance_letter'
[7491]731    tab_redirect = '?tab2'
[7111]732
[7097]733class Image(grok.View):
[7351]734    """Renders images for students.
[7097]735    """
[7106]736    grok.baseclass()
[7097]737    grok.name('none.jpg')
[7112]738    grok.context(IStudentClearance)
[7097]739    grok.require('waeup.viewStudent')
[7106]740    download_name = u'none.jpg'
[7097]741
742    def render(self):
743        # A filename chooser turns a context into a filename suitable
744        # for file storage.
745        image = getUtility(IExtFileStore).getFileByContext(
[7106]746            self.context, attr=self.download_name)
[7097]747        if image is None:
748            # show placeholder image
[7123]749            self.response.setHeader('Content-Type', 'image/jpeg')
[7097]750            return open(DEFAULT_IMAGE_PATH, 'rb').read()
[7123]751        dummy,ext = os.path.splitext(image.name)
752        if ext == '.jpg':
753            self.response.setHeader('Content-Type', 'image/jpeg')
754        elif ext == '.png':
755            self.response.setHeader('Content-Type', 'image/png')
756        elif ext == '.pdf':
757            self.response.setHeader('Content-Type', 'application/pdf')
758        elif ext == '.tif':
759            self.response.setHeader('Content-Type', 'image/tiff')
[7097]760        return image
761
[7112]762class Passport(Image):
763    """Renders jpeg passport picture.
764    """
765    grok.name('passport.jpg')
766    download_name = u'passport.jpg'
767    grok.context(IStudent)
768
[7351]769class ApplicationSlipImage(Image):
770    """Renders application slip scan.
771    """
772    grok.name('application_slip')
773    download_name = u'application_slip'
774
[7097]775class BirthCertificateImage(Image):
[7351]776    """Renders birth certificate scan.
[7097]777    """
[7123]778    grok.name('birth_certificate')
779    download_name = u'birth_certificate'
[7111]780
781class AcceptanceLetterImage(Image):
[7351]782    """Renders acceptance letter scan.
[7111]783    """
[7123]784    grok.name('acceptance_letter')
785    download_name = u'acceptance_letter'
Note: See TracBrowser for help on using the repository browser.