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

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

We need to customize StudentStudyCourse? and StudentStudyLevel?. Therefore it's better to use the factory utility.

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