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

Last change on this file since 9120 was 9070, checked in by Henrik Bettermann, 12 years ago

Approve and Download buttons should always be the last buttons.

  • Property svn:keywords set to Id
File size: 26.0 KB
Line 
1## $Id: viewlets.py 9070 2012-07-26 16:39:27Z 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,
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.student, 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.student, 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 StudentPersonalManageActionButton(ManageActionButton):
234    grok.order(1)
235    grok.context(IStudent)
236    grok.view(StudentPersonalDisplayFormPage)
237    grok.require('waeup.manageStudent')
238    text = _('Manage')
239    target = 'manage_personal'
240
241class StudentPersonalEditActionButton(ManageActionButton):
242    grok.order(2)
243    grok.context(IStudent)
244    grok.view(StudentPersonalDisplayFormPage)
245    grok.require('waeup.handleStudent')
246    text = _('Edit')
247    target = 'edit_personal'
248
249class StudyCourseManageActionButton(ManageActionButton):
250    grok.order(1)
251    grok.context(IStudentStudyCourse)
252    grok.view(StudyCourseDisplayFormPage)
253    grok.require('waeup.manageStudent')
254    text = _('Manage')
255    target = 'manage'
256
257class StudyLevelManageActionButton(ManageActionButton):
258    grok.order(1)
259    grok.context(IStudentStudyLevel)
260    grok.view(StudyLevelDisplayFormPage)
261    grok.require('waeup.manageStudent')
262    text = _('Manage')
263    target = 'manage'
264
265class StudentValidateCoursesActionButton(ManageActionButton):
266    grok.order(3)
267    grok.context(IStudentStudyLevel)
268    grok.view(StudyLevelDisplayFormPage)
269    grok.require('waeup.validateStudent')
270    text = _('Validate courses')
271    target = 'validate_courses'
272    icon = 'actionicon_accept.png'
273
274    @property
275    def target_url(self):
276        if self.context.student.state != REGISTERED or \
277            str(self.context.__parent__.current_level) != self.context.__name__:
278            return ''
279        return self.view.url(self.view.context, self.target)
280
281class StudentRejectCoursesActionButton(ManageActionButton):
282    grok.order(4)
283    grok.context(IStudentStudyLevel)
284    grok.view(StudyLevelDisplayFormPage)
285    grok.require('waeup.validateStudent')
286    text = _('Reject courses')
287    target = 'reject_courses'
288    icon = 'actionicon_reject.png'
289
290    @property
291    def target_url(self):
292        if self.context.student.state not in (VALIDATED, REGISTERED) or \
293            str(self.context.__parent__.current_level) != self.context.__name__:
294            return ''
295        return self.view.url(self.view.context, self.target)
296
297class CourseRegistrationSlipActionButton(ManageActionButton):
298    grok.order(5)
299    grok.context(IStudentStudyLevel)
300    grok.view(StudyLevelDisplayFormPage)
301    grok.require('waeup.viewStudent')
302    icon = 'actionicon_pdf.png'
303    text = _('Download course registration slip')
304    target = 'course_registration.pdf'
305
306class CourseTicketManageActionButton(ManageActionButton):
307    grok.order(1)
308    grok.context(ICourseTicket)
309    grok.view(CourseTicketDisplayFormPage)
310    grok.require('waeup.manageStudent')
311    text = _('Manage')
312    target = 'manage'
313
314#class OnlinePaymentManageActionButton(ManageActionButton):
315#    grok.order(1)
316#    grok.context(IStudentPaymentsContainer)
317#    grok.view(PaymentsDisplayFormPage)
318#    grok.require('waeup.manageStudent')
319#    text = 'Manage payments'
320#    target = 'manage'
321
322class PaymentReceiptActionButton(ManageActionButton):
323    grok.order(9) # This button should always be the last one.
324    grok.context(IStudentOnlinePayment)
325    grok.view(OnlinePaymentDisplayFormPage)
326    grok.require('waeup.viewStudent')
327    icon = 'actionicon_pdf.png'
328    text = _('Download payment slip')
329    target = 'payment_slip.pdf'
330
331    @property
332    def target_url(self):
333        #if self.context.p_state != 'paid':
334        #    return ''
335        return self.view.url(self.view.context, self.target)
336
337class ApprovePaymentActionButton(ManageActionButton):
338    grok.order(8)
339    grok.context(IStudentOnlinePayment)
340    grok.view(OnlinePaymentDisplayFormPage)
341    grok.require('waeup.managePortal')
342    icon = 'actionicon_accept.png'
343    text = _('Approve payment')
344    target = 'approve'
345
346    @property
347    def target_url(self):
348        if self.context.p_state == 'paid':
349            return ''
350        return self.view.url(self.view.context, self.target)
351
352class AddBedTicketActionButton(ManageActionButton):
353    grok.order(1)
354    grok.context(IStudentAccommodation)
355    grok.view(AccommodationManageFormPage)
356    grok.require('waeup.handleAccommodation')
357    icon = 'actionicon_home.png'
358    text = _('Book accommodation')
359    target = 'add'
360
361class BedTicketSlipActionButton(ManageActionButton):
362    grok.order(1)
363    grok.context(IBedTicket)
364    grok.view(BedTicketDisplayFormPage)
365    grok.require('waeup.handleAccommodation')
366    icon = 'actionicon_pdf.png'
367    text = _('Download bed allocation slip')
368    target = 'bed_allocation.pdf'
369
370class RelocateStudentActionButton(ManageActionButton):
371    grok.order(2)
372    grok.context(IBedTicket)
373    grok.view(BedTicketDisplayFormPage)
374    grok.require('waeup.manageHostels')
375    icon = 'actionicon_reload.png'
376    text = _('Relocate student')
377    target = 'relocate'
378
379class StudentBaseActionButton(ManageActionButton):
380    grok.order(1)
381    grok.context(IStudent)
382    grok.view(StudentBaseDisplayFormPage)
383    grok.require('waeup.handleStudent')
384    text = _('Edit')
385    target = 'edit_base'
386
387class StudentPasswordActionButton(ManageActionButton):
388    grok.order(2)
389    grok.context(IStudent)
390    grok.view(StudentBaseDisplayFormPage)
391    grok.require('waeup.handleStudent')
392    icon = 'actionicon_key.png'
393    text = _('Change password')
394    target = 'change_password'
395
396class StudentPassportActionButton(ManageActionButton):
397    grok.order(3)
398    grok.context(IStudent)
399    grok.view(StudentBaseDisplayFormPage)
400    grok.require('waeup.handleStudent')
401    icon = 'actionicon_portrait.png'
402    text = _('Change portrait')
403    target = 'change_portrait'
404
405    @property
406    def target_url(self):
407        if self.context.state != ADMITTED:
408            return ''
409        return self.view.url(self.view.context, self.target)
410
411class StudentClearanceStartActionButton(ManageActionButton):
412    grok.order(1)
413    grok.context(IStudent)
414    grok.view(StudentClearanceDisplayFormPage)
415    grok.require('waeup.handleStudent')
416    icon = 'actionicon_start.gif'
417    text = _('Start clearance')
418    target = 'start_clearance'
419
420    @property
421    def target_url(self):
422        if self.context.state != ADMITTED:
423            return ''
424        return self.view.url(self.view.context, self.target)
425
426class StudentClearanceEditActionButton(ManageActionButton):
427    grok.order(1)
428    grok.context(IStudent)
429    grok.view(StudentClearanceDisplayFormPage)
430    grok.require('waeup.handleStudent')
431    text = _('Edit')
432    target = 'cedit'
433
434    @property
435    def target_url(self):
436        if self.context.clearance_locked:
437            return ''
438        return self.view.url(self.view.context, self.target)
439
440class StartSessionActionButton(ManageActionButton):
441    grok.order(1)
442    grok.context(IStudentStudyCourse)
443    grok.view(StudyCourseDisplayFormPage)
444    grok.require('waeup.handleStudent')
445    icon = 'actionicon_start.gif'
446    text = _('Start new session')
447    target = 'start_session'
448
449    @property
450    def target_url(self):
451        if self.context.next_session_allowed:
452            return self.view.url(self.view.context, self.target)
453        return False
454
455class AddStudyLevelActionButton(AddActionButton):
456    grok.order(1)
457    grok.context(IStudentStudyCourse)
458    grok.view(StudyCourseDisplayFormPage)
459    grok.require('waeup.handleStudent')
460    text = _('Add course list')
461    target = 'add'
462
463    @property
464    def target_url(self):
465        student = self.view.context.student
466        condition1 = student.state != PAID
467        condition2 = str(student['studycourse'].current_level) in \
468            self.view.context.keys()
469        if condition1 or condition2:
470            return ''
471        return self.view.url(self.view.context, self.target)
472
473class StudyLevelEditActionButton(ManageActionButton):
474    grok.order(2)
475    grok.context(IStudentStudyLevel)
476    grok.view(StudyLevelDisplayFormPage)
477    grok.require('waeup.handleStudent')
478    text = _('Edit course list')
479    target = 'edit'
480
481    @property
482    def target_url(self):
483        student = self.view.context.student
484        condition1 = student.state != PAID
485        condition2 = student[
486            'studycourse'].current_level != self.view.context.level
487        if condition1 or condition2:
488            return ''
489        return self.view.url(self.view.context, self.target)
490
491class StudentsTab(PrimaryNavTab):
492    """Students tab in primary navigation.
493    """
494
495    grok.context(IKofaObject)
496    grok.order(4)
497    grok.require('waeup.viewStudentsTab')
498
499    pnav = 4
500    tab_title = _(u'Students')
501
502    @property
503    def link_target(self):
504        return self.view.application_url('students')
505
506class PrimaryStudentNavManager(grok.ViewletManager):
507    """Viewlet manager for the primary navigation tab.
508    """
509    grok.name('primary_nav_student')
510
511class PrimaryStudentNavTab(grok.Viewlet):
512    """Base for primary student nav tabs.
513    """
514    grok.baseclass()
515    grok.viewletmanager(PrimaryStudentNavManager)
516    template = default_primary_nav_template
517    grok.order(1)
518    grok.require('waeup.Authenticated')
519    pnav = 0
520    tab_title = u'Some Text'
521
522    @property
523    def link_target(self):
524        return self.view.application_url()
525
526    @property
527    def active(self):
528        view_pnav = getattr(self.view, 'pnav', 0)
529        if view_pnav == self.pnav:
530            return 'active'
531        return ''
532
533class MyStudentDataTab(PrimaryStudentNavTab):
534    """MyData dropdown tab in primary navigation.
535    """
536    grok.order(3)
537    grok.require('waeup.viewMyStudentDataTab')
538    grok.template('mydatadropdowntabs')
539    pnav = 4
540    tab_title = _(u'My Data')
541
542    @property
543    def active(self):
544        view_pnav = getattr(self.view, 'pnav', 0)
545        if view_pnav == self.pnav:
546            return 'active dropdown'
547        return 'dropdown'
548
549    @property
550    def targets(self):
551        student_url = self.view.application_url() + (
552            '/students/%s' % self.request.principal.id)
553        #app_slip = getUtility(IExtFileStore).getFileByContext(
554        #    self.context.student, 'application_slip')
555        targets = []
556        #if app_slip:
557        #    targets = [{'url':student_url + '/application_slip', 'title':'Application Slip'},]
558        targets += [
559            {'url':student_url, 'title':'Base Data'},
560            {'url':student_url + '/view_clearance',
561             'title':_('Clearance Data')},
562            {'url':student_url + '/view_personal', 'title':_('Personal Data')},
563            {'url':student_url + '/studycourse', 'title':_('Study Course')},
564            {'url':student_url + '/payments', 'title':_('Payments')},
565            {'url':student_url + '/accommodation',
566             'title':_('Accommodation Data')},
567            {'url':student_url + '/history', 'title':_('History')},
568            ]
569        return targets
570
571def handle_file_delete(context, view, download_name):
572    """Handle deletion of student file.
573
574    """
575    store = getUtility(IExtFileStore)
576    store.deleteFileByContext(context, attr=download_name)
577    context.writeLogMessage(view, 'deleted: %s' % download_name)
578    view.flash(_('${a} deleted.', mapping = {'a':download_name}))
579    return
580
581def handle_file_upload(upload, context, view, max_size, download_name=None):
582    """Handle upload of student file.
583
584    Returns `True` in case of success or `False`.
585
586    Please note that file pointer passed in (`upload`) most probably
587    points to end of file when leaving this function.
588    """
589    # Check some file requirements first
590    size = file_size(upload)
591    if size > max_size:
592        view.flash(_('Uploaded file is too big.'))
593        return False
594    upload.seek(0) # file pointer moved when determining size
595    file_format = get_fileformat(None, upload.read(512))
596    upload.seek(0) # same here
597    if file_format is None:
598        view.flash(_('Could not determine file type.'))
599        return False
600    basename, expected_ext = os.path.splitext(download_name)
601    if expected_ext:
602        if '.' + file_format != expected_ext:
603            view.flash(_('${a} file extension expected.',
604                mapping = {'a':expected_ext[1:]}))
605            return False
606    else:
607        if not file_format in ALLOWED_FILE_EXTENSIONS:
608            view.flash(
609                _('Only the following extensions are allowed: ${a}',
610                mapping = {'a':', '.join(ALLOWED_FILE_EXTENSIONS)}))
611            return False
612        download_name += '.' + file_format
613    store = getUtility(IExtFileStore)
614    file_id = IFileStoreNameChooser(context).chooseName(attr=download_name)
615    store.createFile(file_id, upload)
616    context.writeLogMessage(view, 'uploaded: %s (%s)' % (
617        download_name,upload.filename))
618    view.flash(_('File ${a} uploaded.', mapping = {'a':download_name}))
619    return True
620
621class FileManager(grok.ViewletManager):
622    """Viewlet manager for uploading files, preferably scanned images.
623    """
624    grok.name('files')
625
626class FileDisplay(grok.Viewlet):
627    """Base file display viewlet.
628    """
629    grok.baseclass()
630    grok.context(IStudent)
631    grok.viewletmanager(FileManager)
632    grok.view(StudentClearanceDisplayFormPage)
633    template = default_filedisplay_template
634    grok.order(1)
635    grok.require('waeup.viewStudent')
636    label = _(u'File')
637    title = _(u'Scan')
638    download_name = u'filename.jpg'
639
640    @property
641    def file_exists(self):
642        image = getUtility(IExtFileStore).getFileByContext(
643            self.context, attr=self.download_name)
644        if image:
645            return True
646        else:
647            return False
648
649class FileUpload(FileDisplay):
650    """Base upload viewlet.
651    """
652    grok.baseclass()
653    grok.context(IStudent)
654    grok.viewletmanager(FileManager)
655    grok.view(StudentClearanceManageFormPage)
656    template = default_fileupload_template
657    grok.require('waeup.uploadStudentFile')
658    tab_redirect = '?tab2'
659    mus = 1024 * 150
660    upload_button =_('Upload new file')
661    delete_button = _('Delete attachment')
662    show_viewlet = True
663
664    @property
665    def input_name(self):
666        return "%s" % self.__name__
667
668    def update(self):
669        self.max_upload_size = string_from_bytes(self.mus)
670        delete_button = self.request.form.get(
671            'delete_%s' % self.input_name, None)
672        upload_button = self.request.form.get(
673            'upload_%s' % self.input_name, None)
674        if delete_button:
675            handle_file_delete(
676                context=self.context, view=self.view,
677                download_name=self.download_name)
678            self.view.redirect(
679                self.view.url(
680                    self.context, self.view.__name__) + self.tab_redirect)
681            return
682        if upload_button:
683            upload = self.request.form.get(self.input_name, None)
684            if upload:
685                # We got a fresh upload
686                handle_file_upload(upload,
687                    self.context, self.view, self.mus, self.download_name)
688                self.view.redirect(
689                    self.view.url(
690                        self.context, self.view.__name__) + self.tab_redirect)
691            else:
692                self.view.flash(_('No local file selected.'))
693                self.view.redirect(
694                    self.view.url(
695                        self.context, self.view.__name__) + self.tab_redirect)
696        return
697
698class PassportDisplay(FileDisplay):
699    """Passport display viewlet.
700    """
701    grok.order(1)
702    grok.context(IStudent)
703    grok.view(StudentBaseDisplayFormPage)
704    grok.require('waeup.viewStudent')
705    grok.template('imagedisplay')
706    label = _(u'Passport Picture')
707    download_name = u'passport.jpg'
708
709class PassportUploadManage(FileUpload):
710    """Passport upload viewlet for officers.
711    """
712    grok.order(1)
713    grok.context(IStudent)
714    grok.view(StudentBaseManageFormPage)
715    grok.require('waeup.manageStudent')
716    grok.template('imageupload')
717    label = _(u'Passport Picture (jpg only)')
718    mus = 1024 * 50
719    download_name = u'passport.jpg'
720    tab_redirect = '?tab2'
721
722class PassportUploadEdit(PassportUploadManage):
723    """Passport upload viewlet for students.
724    """
725    grok.view(StudentFilesUploadPage)
726    grok.require('waeup.uploadStudentFile')
727
728class BirthCertificateDisplay(FileDisplay):
729    """Birth Certificate display viewlet.
730    """
731    grok.order(1)
732    label = _(u'Birth Certificate')
733    title = _(u'Birth Certificate Scan')
734    download_name = u'birth_certificate'
735
736class BirthCertificateSlip(BirthCertificateDisplay):
737    grok.view(ExportPDFClearanceSlipPage)
738
739class BirthCertificateUpload(FileUpload):
740    """Birth Certificate upload viewlet.
741    """
742    grok.order(1)
743    label = _(u'Birth Certificate')
744    title = _(u'Birth Certificate Scan')
745    mus = 1024 * 150
746    download_name = u'birth_certificate'
747    tab_redirect = '?tab2'
748
749class AcceptanceLetterDisplay(FileDisplay):
750    """Acceptance Letter display viewlet.
751    """
752    grok.order(1)
753    label = _(u'Acceptance Letter')
754    title = _(u'Acceptance Letter Scan')
755    download_name = u'acc_let'
756
757class AcceptanceLetterSlip(AcceptanceLetterDisplay):
758    grok.view(ExportPDFClearanceSlipPage)
759
760class AcceptanceLetterUpload(FileUpload):
761    """AcceptanceLetter upload viewlet.
762    """
763    grok.order(2)
764    label = _(u'Acceptance Letter')
765    title = _(u'Acceptance Letter Scan')
766    mus = 1024 * 150
767    download_name = u'acc_let'
768    tab_redirect = '?tab2'
769
770class Image(grok.View):
771    """Renders images for students.
772    """
773    grok.baseclass()
774    grok.name('none.jpg')
775    grok.context(IStudent)
776    grok.require('waeup.viewStudent')
777    download_name = u'none.jpg'
778
779    def render(self):
780        # A filename chooser turns a context into a filename suitable
781        # for file storage.
782        image = getUtility(IExtFileStore).getFileByContext(
783            self.context, attr=self.download_name)
784        if image is None:
785            # show placeholder image
786            self.response.setHeader('Content-Type', 'image/jpeg')
787            return open(DEFAULT_IMAGE_PATH, 'rb').read()
788        dummy,ext = os.path.splitext(image.name)
789        if ext == '.jpg':
790            self.response.setHeader('Content-Type', 'image/jpeg')
791        elif ext == '.png':
792            self.response.setHeader('Content-Type', 'image/png')
793        elif ext == '.pdf':
794            self.response.setHeader('Content-Type', 'application/pdf')
795        elif ext == '.tif':
796            self.response.setHeader('Content-Type', 'image/tiff')
797        return image
798
799class Passport(Image):
800    """Renders jpeg passport picture.
801    """
802    grok.name('passport.jpg')
803    download_name = u'passport.jpg'
804    grok.context(IStudent)
805
806class ApplicationSlipImage(Image):
807    """Renders application slip scan.
808    """
809    grok.name('application_slip')
810    download_name = u'application_slip'
811
812class BirthCertificateImage(Image):
813    """Renders birth certificate scan.
814    """
815    grok.name('birth_certificate')
816    download_name = u'birth_certificate'
817
818class AcceptanceLetterImage(Image):
819    """Renders acceptance letter scan.
820    """
821    grok.name('acc_let')
822    download_name = u'acc_let'
Note: See TracBrowser for help on using the repository browser.