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

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

Add InterswitchPage? which generates POST requests for the Interswitch CollegePAY gateway (work in progress).

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