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

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

Change order of ManageActionButtons?.

Change label of ApplicantRegistrationPage?.

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