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

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

KOFA -> Kofa

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