source: main/waeup.kofa/trunk/src/waeup/kofa/students/viewlets.py @ 8490

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

Fix typo.

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